Module Name: src Committed By: matt Date: Mon Feb 13 23:07:31 UTC 2012
Modified Files: src/sys/uvm [matt-nb5-mips64]: uvm_page.h uvm_pdaemon.c Log Message: Use separate pending and paging tailq entries. Add a queue check routine to validate the queues aren't corrupt. To generate a diff of this commit: cvs rdiff -u -r1.55.14.6 -r1.55.14.7 src/sys/uvm/uvm_page.h cvs rdiff -u -r1.93.4.2.4.3 -r1.93.4.2.4.4 src/sys/uvm/uvm_pdaemon.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/uvm/uvm_page.h diff -u src/sys/uvm/uvm_page.h:1.55.14.6 src/sys/uvm/uvm_page.h:1.55.14.7 --- src/sys/uvm/uvm_page.h:1.55.14.6 Thu Feb 9 03:05:00 2012 +++ src/sys/uvm/uvm_page.h Mon Feb 13 23:07:31 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_page.h,v 1.55.14.6 2012/02/09 03:05:00 matt Exp $ */ +/* $NetBSD: uvm_page.h,v 1.55.14.7 2012/02/13 23:07:31 matt Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -248,7 +248,8 @@ struct vm_physseg { * Fields from uvmexp which need to be kept on a per-group basis. */ struct uvm_pggroup { - TAILQ_ENTRY(uvm_pggroup) pgrp_pd_link; + TAILQ_ENTRY(uvm_pggroup) pgrp_pending_link; + TAILQ_ENTRY(uvm_pggroup) pgrp_paging_link; STAILQ_ENTRY(uvm_pggroup) pgrp_uvm_link; struct uvmpdpol_groupstate *pgrp_gs; /* for pdpolicy */ Index: src/sys/uvm/uvm_pdaemon.c diff -u src/sys/uvm/uvm_pdaemon.c:1.93.4.2.4.3 src/sys/uvm/uvm_pdaemon.c:1.93.4.2.4.4 --- src/sys/uvm/uvm_pdaemon.c:1.93.4.2.4.3 Thu Feb 9 03:05:01 2012 +++ src/sys/uvm/uvm_pdaemon.c Mon Feb 13 23:07:31 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_pdaemon.c,v 1.93.4.2.4.3 2012/02/09 03:05:01 matt Exp $ */ +/* $NetBSD: uvm_pdaemon.c,v 1.93.4.2.4.4 2012/02/13 23:07:31 matt Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -71,7 +71,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.93.4.2.4.3 2012/02/09 03:05:01 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.93.4.2.4.4 2012/02/13 23:07:31 matt Exp $"); #include "opt_uvmhist.h" #include "opt_readahead.h" @@ -106,6 +106,8 @@ static void uvmpd_scan(struct uvm_pggrou static void uvmpd_scan_queue(struct uvm_pggroup *); static void uvmpd_tune(void); +static void uvmpd_checkgroup(const struct uvm_pggroup *); + static struct uvm_pdinfo { unsigned int pd_waiters; unsigned int pd_scans_neededs; @@ -170,6 +172,40 @@ uvm_wait(const char *wmsg) UVM_UNLOCK_AND_WAIT(&uvmexp.free, &uvm_fpageqlock, false, wmsg, timo); } + +static void +uvmpd_checkgroup(const struct uvm_pggroup *grp) +{ +#ifdef DEBUG + struct uvm_pdinfo * const pdinfo = &uvm_pdinfo; + bool in_pendingq = false; + bool in_pagingq = false; + const struct uvm_pggroup *tstgrp; + + TAILQ_FOREACH(tstgrp, &pdinfo->pd_pendingq, pgrp_pending_link) { + if (tstgrp == grp) { + in_pendingq = true; + break; + } + } + + TAILQ_FOREACH(tstgrp, &pdinfo->pd_pagingq, pgrp_paging_link) { + if (tstgrp == grp) { + in_pagingq = true; + break; + } + } + + if (grp->pgrp_paging > 0) { + KASSERT(in_pagingq); + KASSERT(!in_pendingq); + } else { + KASSERT(!in_pagingq); + KASSERT(in_pendingq == grp->pgrp_scan_needed); + } +#endif +} + /* * uvm_kick_pdaemon: perform checks to determine if we need to * give the pagedaemon a nudge, and do so if necessary. @@ -191,6 +227,7 @@ uvm_kick_pdaemon(void) const bool prev_scan_needed = grp->pgrp_scan_needed; KASSERT(grp->pgrp_npages > 0); + uvmpd_checkgroup(grp); grp->pgrp_scan_needed = grp->pgrp_free + grp->pgrp_paging < grp->pgrp_freemin @@ -207,16 +244,16 @@ uvm_kick_pdaemon(void) grp->pgrp_freemin, grp->pgrp_freetarg); } - if (grp->pgrp_paging == 0 - && prev_scan_needed != grp->pgrp_scan_needed) { + if (prev_scan_needed != grp->pgrp_scan_needed) { if (grp->pgrp_scan_needed) { TAILQ_INSERT_TAIL(&pdinfo->pd_pendingq, - grp, pgrp_pd_link); + grp, pgrp_pending_link); need_wakeup = true; } else { TAILQ_REMOVE(&pdinfo->pd_pendingq, - grp, pgrp_pd_link); + grp, pgrp_pending_link); } + uvmpd_checkgroup(grp); } } @@ -224,7 +261,7 @@ uvm_kick_pdaemon(void) wakeup(&uvm.pagedaemon); UVMHIST_LOG(pdhist, " <- done: wakeup=%d!", - grp - uvm.pggroups, need_wakeup, 0, 0); + need_wakeup, 0, 0, 0); } /* @@ -371,6 +408,16 @@ uvm_pageout(void *arg) uvmpdpol_tune(grp); + /* + * While we are locked, remove this from the pendingq. + */ + uvmpd_checkgroup(grp); + KASSERT(grp->pgrp_scan_needed); + TAILQ_REMOVE(&pdinfo->pd_pendingq, grp, + pgrp_pending_link); + grp->pgrp_scan_needed = false; + uvmpd_checkgroup(grp); + int diff = grp->pgrp_freetarg - grp->pgrp_free; if (diff < 0) diff = 0; @@ -411,11 +458,6 @@ uvm_pageout(void *arg) need_wakeup = true; } - /* - * We are done, remove it from the queue. - */ - TAILQ_REMOVE(&pdinfo->pd_pendingq, grp, pgrp_pd_link); - grp->pgrp_scan_needed = false; } if (need_wakeup) { pdinfo->pd_waiters = 0; @@ -487,10 +529,10 @@ uvm_pageout_start(struct uvm_pggroup *gr mutex_spin_enter(&uvm_fpageqlock); uvmexp.paging += npages; + uvmpd_checkgroup(grp); if (grp->pgrp_paging == 0) { - KASSERT(grp->pgrp_scan_needed); - TAILQ_REMOVE(&pdinfo->pd_pendingq, grp, pgrp_pd_link); - TAILQ_INSERT_TAIL(&pdinfo->pd_pagingq, grp, pgrp_pd_link); + TAILQ_INSERT_TAIL(&pdinfo->pd_pagingq, grp, pgrp_paging_link); + uvmpd_checkgroup(grp); } grp->pgrp_paging += npages; mutex_spin_exit(&uvm_fpageqlock); @@ -507,13 +549,11 @@ uvm_pageout_done(struct vm_page *pg, boo struct uvm_pggroup * const grp = uvm_page_to_pggroup(pg); KASSERT(grp->pgrp_paging > 0); + uvmpd_checkgroup(grp); if (--grp->pgrp_paging == 0) { - TAILQ_REMOVE(&pdinfo->pd_pagingq, grp, pgrp_pd_link); - if (grp->pgrp_scan_needed) { - TAILQ_INSERT_TAIL(&pdinfo->pd_pendingq, grp, pgrp_pd_link); - } + TAILQ_REMOVE(&pdinfo->pd_pagingq, grp, pgrp_paging_link); + uvmpd_checkgroup(grp); } - KASSERT(uvmexp.paging > 0); uvmexp.paging--; grp->pgrp_pdfreed += freed;