handle a locking problem where the second (or later) call in the loanentry

loop returns 0.   loanentry was returning >0, but was unlocking the maps
(because of the zero).   reworked to avoid this.  problem reported by
chuck silvers.   also clarify a comment that jdolecek asked about.
This commit is contained in:
chuck 2001-08-27 02:34:29 +00:00
parent df657b5158
commit 2dec1a929d
1 changed files with 14 additions and 14 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_loan.c,v 1.30 2001/08/18 05:51:44 chs Exp $ */
/* $NetBSD: uvm_loan.c,v 1.31 2001/08/27 02:34:29 chuck Exp $ */
/*
*
@ -119,13 +119,14 @@ static int uvm_loanzero __P((struct uvm_faultinfo *, void ***, int));
* uvm_loanentry: loan out pages in a map entry (helper fn for uvm_loan())
*
* => "ufi" is the result of a successful map lookup (meaning that
* the map is locked by the caller)
* on entry the map is locked by the caller)
* => we may unlock and then relock the map if needed (for I/O)
* => we put our output result in "output"
* => we always return with the map unlocked
* => possible return values:
* -1 == error, map is unlocked
* 0 == map relock error (try again!), map is unlocked
* >0 == number of pages we loaned, map remain locked
* >0 == number of pages we loaned, map is unlocked
*/
static __inline int
@ -174,15 +175,15 @@ uvm_loanentry(ufi, output, flags)
} else {
rv = -1; /* null map entry... fail now */
}
/* locked: if (rv > 0) => map, amap, uobj */
/* locked: if (rv > 0) => map, amap, uobj [o.w. unlocked] */
/* total failure */
if (rv < 0)
return(-1);
return(-1); /* everything unlocked */
/* relock failed, need to do another lookup */
if (rv == 0)
return(result);
return(result); /* everything unlocked */
/*
* got it... advance to next page
@ -193,12 +194,13 @@ uvm_loanentry(ufi, output, flags)
}
/*
* unlock what we locked and return (with map still locked)
* unlock what we locked, unlock the maps and return
*/
if (aref->ar_amap)
amap_unlock(aref->ar_amap);
if (uobj)
simple_unlock(&uobj->vmobjlock);
uvmfault_unlockmaps(ufi, FALSE);
return(result);
}
@ -280,18 +282,16 @@ uvm_loan(map, start, len, result, flags)
}
/*
* done! the map is locked only if rv > 0. if that
* is the case, advance and unlock.
* done! the map is unlocked. advance, if possible.
*
* XXXCDC: could avoid the unlock with smarter code
* (but it only happens on map entry boundaries,
* so it isn't that bad).
* XXXCDC: could be recoded to hold the map lock with
* smarter code (but it only happens on map entry
* boundaries, so it isn't that bad).
*/
if (rv) {
rv <<= PAGE_SHIFT;
len -= rv;
start += rv;
uvmfault_unlockmaps(&ufi, FALSE);
}
}
@ -760,7 +760,7 @@ uvm_unloanpage(ploans, npages)
panic("uvm_unloanpage: page %p isn't loaned", pg);
pg->loan_count--; /* drop loan */
uvm_pageunwire(pg); /* and wire */
uvm_pageunwire(pg); /* and unwire */
/*
* if page is unowned and we killed last loan, then we can