norman@decvax.UUCP (Norman Wilson) (09/04/83)
another 4.1bsd paging code problem ... in vmpage.c/pagein, if the page being faulted in is a text page from an 0413 a.out which has yet to be touched (ie, if the page table entry is fill-on-demand), mfind is called to see if the desired page happens to be in the free list in memory. if so, the page can be reused in place, without reading it in from disk. for sanity's sake, the cmap returned by mfind is checked: c_type == CTEXT (it's a text page), c_gone != 0 (it doesn't belong to a segment -- otherwise we shouldn't be here, as it would belong to our segment!), c_free != 0 (it's really on the freelist). if these conditions aren't satisfied, the system panics ("pagein mfind"). however, it's not safe to do just that test, since the page could be undergoing mutation in some other part of the paging code. for example, the page might be being paged out at the time (having been stolen from a process which has since exited or execed, and has let go its text segment). this would cause c_gone to be set, but not c_free (since the page isn't on the free list yet; it will be put there by vmpage/cleanup when the pageout is complete). c_lock is set for such pages, and pagein should honour it. the bug is that it does not. i've applied the following fix. don't take line numbers too seriously, as there are other changes to my vmpage.c. the call to mfind which is replaced by the while loop is the first mfind call in the file, and is followed by `if (c) {'. diff 4.1vmpage.c vmpage.c (extract) 202a243 > * honour lock bit to avoid races with pageouts 205c246,252 < c = mfind(dev, bncache); --- > while ((c = mfind(dev, bncache)) != 0) { > pf = cmtopg(c - cmap); > if (c->c_lock == 0) > break; > mlock(pf); > munlock(pf); > } ie, if the page was locked, lock it ourselves (which will cause a sleep until it becomes unlocked), then let it go (since we don't really want it locked), then look in the hash lists again (if we went to sleep, anything could have happened to the page). norman wilson caltech high energy physics group ucbvax!cithep!norman decvax!cithep!norman