summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_page.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/vm_page.h')
-rw-r--r--sys/vm/vm_page.h46
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);
OpenPOWER on IntegriCloud