Subject: My latest page scanner patch
To: None <tech-kern@netbsd.org>
From: Jason R Thorpe <thorpej@zembu.com>
List: tech-kern
Date: 01/26/2001 11:34:15
Folks..
Here is my latest page scanner patch. Note that I'm still debating
whether or not to clear_reference or actually deactivate the pages
in the aobj/map "clean" path, tho I'm leaning towards deactivate (they
go on the end of the list, so other references won't be penalized unless
there's a free page shortage).
I would really appreciate it if people would "cvs update" their
sys/uvm directory and try this patch, and report to me any change
in behavior (positive or negative) on their systems.
--
-- Jason R. Thorpe <thorpej@zembu.com>
Index: uvm_anon.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_anon.c,v
retrieving revision 1.13
diff -c -r1.13 uvm_anon.c
*** uvm_anon.c 2001/01/23 02:27:39 1.13
--- uvm_anon.c 2001/01/26 19:18:54
***************
*** 526,532 ****
*/
pmap_clear_reference(pg);
- pmap_page_protect(pg, VM_PROT_NONE);
uvm_lock_pageq();
uvm_pagedeactivate(pg);
uvm_unlock_pageq();
--- 526,531 ----
Index: uvm_aobj.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_aobj.c,v
retrieving revision 1.37
diff -c -r1.37 uvm_aobj.c
*** uvm_aobj.c 2000/11/25 06:27:59 1.37
--- uvm_aobj.c 2001/01/26 19:18:54
***************
*** 882,892 ****
pp->wire_count != 0)
continue;
! /* zap all mappings for the page. */
! pmap_page_protect(pp, VM_PROT_NONE);
!
/* ...and deactivate the page. */
uvm_pagedeactivate(pp);
continue;
--- 882,900 ----
pp->wire_count != 0)
continue;
! #if 1
! /*
! * simply clear the reference to the page.
! * the page will remain on the active queue,
! * and if nothing references it by the next
! * time the scanner runs, it will be deactivated
! * at that time.
! */
! pmap_clear_reference(pp);
! #else
/* ...and deactivate the page. */
uvm_pagedeactivate(pp);
+ #endif
continue;
***************
*** 1543,1549 ****
* deactivate the page (to put it on a page queue).
*/
pmap_clear_reference(pg);
- pmap_page_protect(pg, VM_PROT_NONE);
uvm_lock_pageq();
uvm_pagedeactivate(pg);
uvm_unlock_pageq();
--- 1551,1556 ----
Index: uvm_fault.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_fault.c,v
retrieving revision 1.54
diff -c -r1.54 uvm_fault.c
*** uvm_fault.c 2001/01/23 02:27:39 1.54
--- uvm_fault.c 2001/01/26 19:18:56
***************
*** 205,211 ****
if (pg && (pg->flags & PG_BUSY) == 0 && pg->loan_count == 0) {
uvm_lock_pageq();
if (pg->wire_count == 0) {
! pmap_page_protect(pg, VM_PROT_NONE);
uvm_pagedeactivate(pg);
}
uvm_unlock_pageq();
--- 205,211 ----
if (pg && (pg->flags & PG_BUSY) == 0 && pg->loan_count == 0) {
uvm_lock_pageq();
if (pg->wire_count == 0) {
! pmap_clear_reference(pg);
uvm_pagedeactivate(pg);
}
uvm_unlock_pageq();
Index: uvm_map.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_map.c,v
retrieving revision 1.88
diff -c -r1.88 uvm_map.c
*** uvm_map.c 2001/01/14 02:10:01 1.88
--- uvm_map.c 2001/01/26 19:18:58
***************
*** 2566,2576 ****
}
KASSERT(pg->uanon == anon);
! /* zap all mappings for the page. */
! pmap_page_protect(pg, VM_PROT_NONE);
!
/* ...and deactivate the page. */
uvm_pagedeactivate(pg);
uvm_unlock_pageq();
simple_unlock(&anon->an_lock);
--- 2566,2584 ----
}
KASSERT(pg->uanon == anon);
! #if 1
! /*
! * simply clear the reference to the page.
! * the page will remain on the active queue,
! * and if nothing references it by the next
! * time the scanner runs, it will be de-
! * activated at that time.
! */
! pmap_clear_reference(pg);
! #else
/* ...and deactivate the page. */
uvm_pagedeactivate(pg);
+ #endif
uvm_unlock_pageq();
simple_unlock(&anon->an_lock);
Index: uvm_page_i.h
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_page_i.h,v
retrieving revision 1.15
diff -c -r1.15 uvm_page_i.h
*** uvm_page_i.h 2001/01/14 02:10:02 1.15
--- uvm_page_i.h 2001/01/26 19:18:59
***************
*** 193,203 ****
}
/*
! * uvm_pagedeactivate: deactivate page -- no pmaps have access to page
*
* => caller must lock page queues
* => caller must check to make sure page is not wired
* => object that page belongs to must be locked (so we can adjust pg->flags)
*/
PAGE_INLINE void
--- 193,204 ----
}
/*
! * uvm_pagedeactivate: deactivate page
*
* => caller must lock page queues
* => caller must check to make sure page is not wired
* => object that page belongs to must be locked (so we can adjust pg->flags)
+ * => caller must clear the reference on the page before calling
*/
PAGE_INLINE void
***************
*** 217,223 ****
TAILQ_INSERT_TAIL(&uvm.page_inactive_obj, pg, pageq);
pg->pqflags |= PQ_INACTIVE;
uvmexp.inactive++;
! pmap_clear_reference(pg);
if (pmap_is_modified(pg))
pg->flags &= ~PG_CLEAN;
}
--- 218,231 ----
TAILQ_INSERT_TAIL(&uvm.page_inactive_obj, pg, pageq);
pg->pqflags |= PQ_INACTIVE;
uvmexp.inactive++;
!
! /* XXX this probably isn't even necessary. */
! /*
! * update the "clean" bit. this isn't 100%
! * accurate, and doesn't have to be. we'll
! * re-sync it after we zap all mappings when
! * scanning the inactive list.
! */
if (pmap_is_modified(pg))
pg->flags &= ~PG_CLEAN;
}
Index: uvm_pager.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_pager.c,v
retrieving revision 1.38
diff -c -r1.38 uvm_pager.c
*** uvm_pager.c 2000/12/09 23:26:27 1.38
--- uvm_pager.c 2001/01/26 19:18:59
***************
*** 315,325 ****
/*
* attempt to cluster around the left [backward], and then
* the right side [forward].
- *
- * note that for inactive pages (pages that have been deactivated)
- * there are no valid mappings and PG_CLEAN should be up to date.
- * [i.e. there is no need to query the pmap with pmap_is_modified
- * since there are no mappings].
*/
for (forward = 0 ; forward <= 1 ; forward++) {
--- 315,320 ----
***************
*** 333,356 ****
if (pclust == NULL) {
break; /* no page */
}
- /* handle active pages */
- /* NOTE: inactive pages don't have pmap mappings */
- if ((pclust->pqflags & PQ_INACTIVE) == 0) {
- if ((flags & PGO_DOACTCLUST) == 0) {
- /* dont want mapped pages at all */
- break;
- }
! /* make sure "clean" bit is sync'd */
! if ((pclust->flags & PG_CLEANCHK) == 0) {
! if ((pclust->flags & (PG_CLEAN|PG_BUSY))
! == PG_CLEAN &&
! pmap_is_modified(pclust))
! pclust->flags &= ~PG_CLEAN;
! /* now checked */
! pclust->flags |= PG_CLEANCHK;
! }
}
/* is page available for cleaning and does it need it */
--- 328,355 ----
if (pclust == NULL) {
break; /* no page */
}
! if ((flags & PGO_DOACTCLUST) == 0) {
! /* dont want mapped pages at all */
! break;
! }
!
! /*
! * get an up-to-date view of the "clean" bit.
! * note this isn't 100% accurate, but it doesn't
! * have to be. if it's not quite right, the
! * worst that happens is we don't cluster as
! * aggressively. we'll sync-it-for-sure before
! * we free the page, and clean it if necessary.
! */
! if ((pclust->flags & PG_CLEANCHK) == 0) {
! if ((pclust->flags & (PG_CLEAN|PG_BUSY))
! == PG_CLEAN &&
! pmap_is_modified(pclust))
! pclust->flags &= ~PG_CLEAN;
! /* now checked */
! pclust->flags |= PG_CLEANCHK;
}
/* is page available for cleaning and does it need it */
Index: uvm_pdaemon.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_pdaemon.c,v
retrieving revision 1.28
diff -c -r1.28 uvm_pdaemon.c
*** uvm_pdaemon.c 2001/01/25 00:24:48 1.28
--- uvm_pdaemon.c 2001/01/26 19:19:00
***************
*** 533,542 ****
/*
* we now have the object and the page queues locked.
! * the page is not busy. if the page is clean we
! * can free it now and continue.
*/
if (p->flags & PG_CLEAN) {
if (p->pqflags & PQ_SWAPBACKED) {
/* this page now lives only in swap */
--- 533,548 ----
/*
* we now have the object and the page queues locked.
! * the page is not busy. remove all the permissions
! * from the page so we can sync the modified info
! * without any race conditions. if the page is clean
! * we can free it now and continue.
*/
+ pmap_page_protect(p, VM_PROT_NONE);
+ if ((p->flags & PG_CLEAN) != 0 && pmap_is_modified(p))
+ p->flags &= ~PG_CLEAN;
+
if (p->flags & PG_CLEAN) {
if (p->pqflags & PQ_SWAPBACKED) {
/* this page now lives only in swap */
***************
*** 1105,1111 ****
if (inactive_shortage > 0 &&
pmap_clear_reference(p) == FALSE) {
- pmap_page_protect(p, VM_PROT_NONE);
/* no need to check wire_count as pg is "active" */
uvm_pagedeactivate(p);
uvmexp.pddeact++;
--- 1111,1116 ----
Index: uvm_vnode.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_vnode.c,v
retrieving revision 1.41
diff -c -r1.41 uvm_vnode.c
*** uvm_vnode.c 2001/01/08 06:21:13 1.41
--- uvm_vnode.c 2001/01/26 19:19:01
***************
*** 540,546 ****
*/
if ((pp->flags & PG_CLEAN) != 0 &&
(flags & PGO_FREE) != 0 &&
! (pp->pqflags & PQ_ACTIVE) != 0)
pmap_page_protect(pp, VM_PROT_NONE);
if ((pp->flags & PG_CLEAN) != 0 &&
pmap_is_modified(pp))
--- 540,547 ----
*/
if ((pp->flags & PG_CLEAN) != 0 &&
(flags & PGO_FREE) != 0 &&
! /* XXX ACTIVE|INACTIVE test unnecessary? */
! (pp->pqflags & (PQ_ACTIVE|PQ_INACTIVE)) != 0)
pmap_page_protect(pp, VM_PROT_NONE);
if ((pp->flags & PG_CLEAN) != 0 &&
pmap_is_modified(pp))
***************
*** 564,570 ****
if ((pp->pqflags & PQ_INACTIVE) == 0 &&
(pp->flags & PG_BUSY) == 0 &&
pp->wire_count == 0) {
! pmap_page_protect(pp, VM_PROT_NONE);
uvm_pagedeactivate(pp);
}
--- 565,571 ----
if ((pp->pqflags & PQ_INACTIVE) == 0 &&
(pp->flags & PG_BUSY) == 0 &&
pp->wire_count == 0) {
! pmap_clear_reference(pp);
uvm_pagedeactivate(pp);
}
***************
*** 756,762 ****
if ((pp->pqflags & PQ_INACTIVE) == 0 &&
(pp->flags & PG_BUSY) == 0 &&
pp->wire_count == 0) {
! pmap_page_protect(ptmp, VM_PROT_NONE);
uvm_pagedeactivate(ptmp);
}
} else if (flags & PGO_FREE) {
--- 757,763 ----
if ((pp->pqflags & PQ_INACTIVE) == 0 &&
(pp->flags & PG_BUSY) == 0 &&
pp->wire_count == 0) {
! pmap_clear_reference(ptmp);
uvm_pagedeactivate(ptmp);
}
} else if (flags & PGO_FREE) {