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