Subject: Re: kern/15364
To: None <chs@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: Chuck Silvers <chuq@chuq.com>
List: netbsd-bugs
Date: 09/02/2005 16:09:02
The following reply was made to PR kern/15364; it has been noted by GNATS.
From: Chuck Silvers <chuq@chuq.com>
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
Cc: gnats-bugs@NetBSD.org
Subject: Re: kern/15364
Date: Fri, 2 Sep 2005 09:08:54 -0700
On Wed, Aug 31, 2005 at 05:29:45AM +0900, YAMAMOTO Takashi wrote:
> > could you give some details on how the pagedaemon would be confused by this?
>
> pagedaemon frees the whole block when one of the corresponding pages
> happens to be inactive.
could you explain how this happens?
here's the code that sets PG_RELEASE or PG_PAGEOUT on a page.
the marked lines skip setting those flags on pages in the cluster that
are outside the original request. this should prevent the problem you're
describing, right?
/*
* apply FREE or DEACTIVATE options if requested.
*/
if (flags & (PGO_DEACTIVATE|PGO_FREE)) {
uvm_lock_pageq();
}
for (i = 0; i < npages; i++) {
tpg = pgs[i];
KASSERT(tpg->uobject == uobj);
if (by_list && tpg == TAILQ_NEXT(pg, listq))
pg = tpg;
--> if (tpg->offset < startoff || tpg->offset >= endoff)
--> continue;
if (flags & PGO_DEACTIVATE &&
(tpg->pqflags & PQ_INACTIVE) == 0 &&
tpg->wire_count == 0) {
(void) pmap_clear_reference(tpg);
uvm_pagedeactivate(tpg);
} else if (flags & PGO_FREE) {
pmap_page_protect(tpg, VM_PROT_NONE);
if (tpg->flags & PG_BUSY) {
tpg->flags |= freeflag;
if (pagedaemon) {
uvmexp.paging++;
uvm_pagedequeue(tpg);
}
} else {
/*
* ``page is not busy''
* implies that npages is 1
* and needs_clean is false.
*/
nextpg = TAILQ_NEXT(tpg, listq);
uvm_pagefree(tpg);
if (pagedaemon)
uvmexp.pdfreed++;
}
}
}
-Chuck