summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authorkmacy <kmacy@FreeBSD.org>2010-04-30 00:46:43 +0000
committerkmacy <kmacy@FreeBSD.org>2010-04-30 00:46:43 +0000
commit1dc1263413262d13f45f42d89c554d0ddc167ca2 (patch)
tree250705d42bcb9b364f4fd2233c38faaadadf7ae0 /sys/ia64
parenta43425e8835983e7c93a15a2d6a42fdb292c1676 (diff)
downloadFreeBSD-src-1dc1263413262d13f45f42d89c554d0ddc167ca2.zip
FreeBSD-src-1dc1263413262d13f45f42d89c554d0ddc167ca2.tar.gz
On Alan's advice, rather than do a wholesale conversion on a single
architecture from page queue lock to a hashed array of page locks (based on a patch by Jeff Roberson), I've implemented page lock support in the MI code and have only moved vm_page's hold_count out from under page queue mutex to page lock. This changes pmap_extract_and_hold on all pmaps. Supported by: Bitgravity Inc. Discussed with: alc, jeffr, and kib
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/pmap.c8
-rw-r--r--sys/ia64/include/pmap.h2
2 files changed, 8 insertions, 2 deletions
diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c
index 91b2e07..7cc18c1 100644
--- a/sys/ia64/ia64/pmap.c
+++ b/sys/ia64/ia64/pmap.c
@@ -1028,18 +1028,22 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
struct ia64_lpte *pte;
pmap_t oldpmap;
vm_page_t m;
+ vm_paddr_t pa;
+ pa = 0;
m = NULL;
- vm_page_lock_queues();
PMAP_LOCK(pmap);
oldpmap = pmap_switch(pmap);
+retry:
pte = pmap_find_vhpt(va);
if (pte != NULL && pmap_present(pte) &&
(pmap_prot(pte) & prot) == prot) {
m = PHYS_TO_VM_PAGE(pmap_ppn(pte));
+ if (vm_page_pa_tryrelock(pmap, pmap_ppn(pte), &pa))
+ goto retry;
vm_page_hold(m);
}
- vm_page_unlock_queues();
+ PA_UNLOCK_COND(pa);
pmap_switch(oldpmap);
PMAP_UNLOCK(pmap);
return (m);
diff --git a/sys/ia64/include/pmap.h b/sys/ia64/include/pmap.h
index 44079c8..ff059fd 100644
--- a/sys/ia64/include/pmap.h
+++ b/sys/ia64/include/pmap.h
@@ -77,6 +77,8 @@ struct pmap {
TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */
u_int32_t pm_rid[5]; /* base RID for pmap */
struct pmap_statistics pm_stats; /* pmap statistics */
+ uint32_t pm_gen_count; /* generation count (pmap lock dropped) */
+ u_int pm_retries;
};
typedef struct pmap *pmap_t;
OpenPOWER on IntegriCloud