diff options
Diffstat (limited to 'sys/vm/vm_page.h')
-rw-r--r-- | sys/vm/vm_page.h | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index 662af98..da4d42a 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -90,20 +90,21 @@ * and sundry status bits. * * Fields in this structure are locked either by the lock on the - * object that the page belongs to (O) or by the lock on the page - * queues (P). + * object that the page belongs to (O), its corresponding page lock (P), + * or by the lock on the page queues (Q). + * */ TAILQ_HEAD(pglist, vm_page); struct vm_page { - TAILQ_ENTRY(vm_page) pageq; /* queue info for FIFO queue or free list (P) */ + TAILQ_ENTRY(vm_page) pageq; /* queue info for FIFO queue or free list (Q) */ TAILQ_ENTRY(vm_page) listq; /* pages in same object (O) */ struct vm_page *left; /* splay tree link (O) */ struct vm_page *right; /* splay tree link (O) */ vm_object_t object; /* which object am I in (O,P)*/ - vm_pindex_t pindex; /* offset into object (O,P) */ + vm_pindex_t pindex; /* offset into object (O,Q) */ vm_paddr_t phys_addr; /* physical address of page */ struct md_page md; /* machine dependant stuff */ uint8_t queue; /* page queue index */ @@ -111,11 +112,11 @@ struct vm_page { u_short flags; /* see below */ uint8_t order; /* index of the buddy queue */ uint8_t pool; - u_short cow; /* page cow mapping count */ - u_int wire_count; /* wired down maps refs (P) */ - short hold_count; /* page hold count */ + u_short cow; /* page cow mapping count (Q) */ + u_int wire_count; /* wired down maps refs (Q) */ + short hold_count; /* page hold count (P) */ u_short oflags; /* page flags (O) */ - u_char act_count; /* page usage count */ + u_char act_count; /* page usage count (Q) */ u_char busy; /* page busy count (O) */ /* NOTE that these must support one bit per DEV_BSIZE in a page!!! */ /* so, on normal X86 kernels, they must be at least 8 bits wide */ @@ -177,9 +178,35 @@ struct vpglocks { } __aligned(CACHE_LINE_SIZE); extern struct vpglocks vm_page_queue_free_lock; +extern struct vpglocks pa_lock[]; -#define vm_page_queue_free_mtx vm_page_queue_free_lock.data +#if defined(__arm__) +#define PDRSHIFT PDR_SHIFT +#elif !defined(PDRSHIFT) +#define PDRSHIFT 21 +#endif +#define pa_index(pa) ((pa) >> PDRSHIFT) +#define PA_LOCKPTR(pa) &pa_lock[pa_index((pa)) % PA_LOCK_COUNT].data +#define PA_LOCKOBJPTR(pa) ((struct lock_object *)PA_LOCKPTR((pa))) +#define PA_LOCK(pa) mtx_lock(PA_LOCKPTR(pa)) +#define PA_TRYLOCK(pa) mtx_trylock(PA_LOCKPTR(pa)) +#define PA_UNLOCK(pa) mtx_unlock(PA_LOCKPTR(pa)) +#define PA_UNLOCK_COND(pa) \ + do { \ + if (pa) \ + PA_UNLOCK(pa); \ + } while (0) + +#define PA_LOCK_ASSERT(pa, a) mtx_assert(PA_LOCKPTR(pa), (a)) + +#define vm_page_lockptr(m) (PA_LOCKPTR(VM_PAGE_TO_PHYS((m)))) +#define vm_page_lock(m) mtx_lock(vm_page_lockptr((m))) +#define vm_page_unlock(m) mtx_unlock(vm_page_lockptr((m))) +#define vm_page_trylock(m) mtx_trylock(vm_page_lockptr((m))) +#define vm_page_lock_assert(m, a) mtx_assert(vm_page_lockptr((m)), (a)) + +#define vm_page_queue_free_mtx vm_page_queue_free_lock.data /* * These are the flags defined for vm_page. * @@ -324,6 +351,7 @@ void vm_page_dontneed(vm_page_t); void vm_page_deactivate (vm_page_t); void vm_page_insert (vm_page_t, vm_object_t, vm_pindex_t); vm_page_t vm_page_lookup (vm_object_t, vm_pindex_t); +int vm_page_pa_tryrelock(pmap_t, vm_paddr_t, vm_paddr_t *); void vm_page_remove (vm_page_t); void vm_page_rename (vm_page_t, vm_object_t, vm_pindex_t); void vm_page_requeue(vm_page_t m); |