diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2007-04-13 18:57:50 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2007-04-13 18:57:50 +0000 |
commit | 8dcbe71580f80a022d075e6454486bc9d964c765 (patch) | |
tree | a758a75bd2f6e39d8ea45545b501abbee0430ef1 /sys/uvm/uvm_page.c | |
parent | 977eb8538189c8e232f80c85b5a0416ec6cd3670 (diff) |
While splitting flags and pqflags might have been a good idea in theory
to separate locking, on most modern machines this is not enough
since operations on short types touch other short types that share the
same word in memory.
Merge pg_flags and pqflags again and now use atomic operations to change
the flags. Also bump wire_count to an int and pg_version might go
int as well, just for alignment.
tested by many, many. ok miod@
Diffstat (limited to 'sys/uvm/uvm_page.c')
-rw-r--r-- | sys/uvm/uvm_page.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c index deaf13ccc9c..0ef257dad2d 100644 --- a/sys/uvm/uvm_page.c +++ b/sys/uvm/uvm_page.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_page.c,v 1.58 2007/04/11 12:10:42 art Exp $ */ +/* $OpenBSD: uvm_page.c,v 1.59 2007/04/13 18:57:49 art Exp $ */ /* $NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $ */ /* @@ -166,7 +166,7 @@ uvm_pageinsert(struct vm_page *pg) splx(s); TAILQ_INSERT_TAIL(&pg->uobject->memq, pg, listq); /* put in object */ - pg->pg_flags |= PG_TABLED; + atomic_setbits_int(&pg->pg_flags, PG_TABLED); pg->uobject->uo_npages++; } @@ -201,7 +201,7 @@ uvm_pageremove(struct vm_page *pg) /* object should be locked */ TAILQ_REMOVE(&pg->uobject->memq, pg, listq); - pg->pg_flags &= ~PG_TABLED; + atomic_clearbits_int(&pg->pg_flags, PG_TABLED); pg->uobject->uo_npages--; pg->uobject = NULL; pg->pg_version++; @@ -1041,14 +1041,13 @@ uvm_pagealloc_strat(obj, off, anon, flags, strat, free_list) pg->pg_version++; if (anon) { anon->u.an_page = pg; - pg->pqflags = PQ_ANON; + atomic_setbits_int(&pg->pg_flags, PQ_ANON); #ifdef UBC uvm_pgcnt_anon++; #endif } else { if (obj) uvm_pageinsert(pg); - pg->pqflags = 0; } #if defined(UVM_PAGE_TRKOWN) pg->owner_tag = NULL; @@ -1060,7 +1059,7 @@ uvm_pagealloc_strat(obj, off, anon, flags, strat, free_list) * A zero'd page is not clean. If we got a page not already * zero'd, then we have to zero it ourselves. */ - pg->pg_flags &= ~PG_CLEAN; + atomic_clearbits_int(&pg->pg_flags, PG_CLEAN); if (zeroit) pmap_zero_page(pg); } @@ -1153,8 +1152,9 @@ uvm_pagefree(struct vm_page *pg) * page out. */ + /* in case an anon takes over */ if (saved_loan_count) - pg->pg_flags &= ~PG_CLEAN;/* in case an anon takes over */ + atomic_clearbits_int(&pg->pg_flags, PG_CLEAN); uvm_pageremove(pg); /* @@ -1168,7 +1168,7 @@ uvm_pagefree(struct vm_page *pg) if (saved_loan_count) return; - } else if (saved_loan_count && (pg->pqflags & PQ_ANON)) { + } else if (saved_loan_count && (pg->pg_flags & PQ_ANON)) { /* * if our page is owned by an anon and is loaned out to the * kernel then we just want to drop ownership and return. @@ -1176,8 +1176,7 @@ uvm_pagefree(struct vm_page *pg) * note that the kernel can't change the loan status of our * page as long as we are holding PQ lock. */ - - pg->pqflags &= ~PQ_ANON; + atomic_clearbits_int(&pg->pg_flags, PQ_ANON); pg->uanon = NULL; return; } @@ -1187,17 +1186,17 @@ uvm_pagefree(struct vm_page *pg) * now remove the page from the queues */ - if (pg->pqflags & PQ_ACTIVE) { + if (pg->pg_flags & PQ_ACTIVE) { TAILQ_REMOVE(&uvm.page_active, pg, pageq); - pg->pqflags &= ~PQ_ACTIVE; + atomic_clearbits_int(&pg->pg_flags, PQ_ACTIVE); uvmexp.active--; } - if (pg->pqflags & PQ_INACTIVE) { - if (pg->pqflags & PQ_SWAPBACKED) + if (pg->pg_flags & PQ_INACTIVE) { + if (pg->pg_flags & PQ_SWAPBACKED) TAILQ_REMOVE(&uvm.page_inactive_swp, pg, pageq); else TAILQ_REMOVE(&uvm.page_inactive_obj, pg, pageq); - pg->pqflags &= ~PQ_INACTIVE; + atomic_clearbits_int(&pg->pg_flags, PQ_INACTIVE); uvmexp.inactive--; } @@ -1219,12 +1218,13 @@ uvm_pagefree(struct vm_page *pg) * and put on free queue */ - pg->pg_flags &= ~PG_ZERO; + atomic_clearbits_int(&pg->pg_flags, PG_ZERO); s = uvm_lock_fpageq(); TAILQ_INSERT_TAIL(&uvm.page_free[ uvm_page_lookup_freelist(pg)].pgfl_queues[PGFL_UNKNOWN], pg, pageq); - pg->pqflags = PQ_FREE; + atomic_clearbits_int(&pg->pg_flags, PQ_MASK); + atomic_setbits_int(&pg->pg_flags, PQ_FREE); #ifdef DEBUG pg->uobject = (void *)0xdeadbeef; pg->offset = 0xdeadbeef; @@ -1271,13 +1271,13 @@ uvm_page_unbusy(pgs, npgs) if (uobj != NULL) { uobj->pgops->pgo_releasepg(pg, NULL); } else { - pg->pg_flags &= ~(PG_BUSY); + atomic_clearbits_int(&pg->pg_flags, PG_BUSY); UVM_PAGE_OWN(pg, NULL); uvm_anfree(pg->uanon); } } else { UVMHIST_LOG(pdhist, "unbusying pg %p", pg,0,0,0); - pg->pg_flags &= ~(PG_WANTED|PG_BUSY); + atomic_clearbits_int(&pg->pg_flags, PG_WANTED|PG_BUSY); UVM_PAGE_OWN(pg, NULL); } } @@ -1390,7 +1390,7 @@ uvm_pageidlezero() */ pmap_zero_page(pg); #endif - pg->pg_flags |= PG_ZERO; + atomic_setbits_int(&pg->pg_flags, PG_ZERO); s = uvm_lock_fpageq(); TAILQ_INSERT_HEAD(&pgfl->pgfl_queues[PGFL_ZEROS], pg, pageq); |