summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2020-11-24 13:49:10 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2020-11-24 13:49:10 +0000
commit22cf3f4dc18f4ca08d182c94036a857ca85ae64e (patch)
treeca86b36b9bdd5b51fbd3fa35ece144275606c528 /sys/uvm
parent4241f56e14c2843e4fc4f8aece6b032ceb6a3e38 (diff)
Grab the `pageqlock' before calling uvm_pageclean() as intended.
Document which global data structures require this lock and add some asserts where the lock should be held. Some code paths are still incorrect and should be revisited. ok jmatthew@
Diffstat (limited to 'sys/uvm')
-rw-r--r--sys/uvm/uvm.h16
-rw-r--r--sys/uvm/uvm_anon.c4
-rw-r--r--sys/uvm/uvm_object.c4
-rw-r--r--sys/uvm/uvm_page.c18
-rw-r--r--sys/uvm/uvm_pdaemon.c4
5 files changed, 35 insertions, 11 deletions
diff --git a/sys/uvm/uvm.h b/sys/uvm/uvm.h
index 8ac7af64c33..40c38ab12b0 100644
--- a/sys/uvm/uvm.h
+++ b/sys/uvm/uvm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm.h,v 1.67 2019/12/06 08:33:25 mpi Exp $ */
+/* $OpenBSD: uvm.h,v 1.68 2020/11/24 13:49:09 mpi Exp $ */
/* $NetBSD: uvm.h,v 1.24 2000/11/27 08:40:02 chs Exp $ */
/*
@@ -44,18 +44,20 @@
/*
* uvm structure (vm global state: collected in one structure for ease
* of reference...)
+ *
+ * Locks used to protect struct members in this file:
+ * Q uvm.pageqlock
*/
-
struct uvm {
/* vm_page related parameters */
/* vm_page queues */
- struct pglist page_active; /* allocated pages, in use */
- struct pglist page_inactive_swp;/* pages inactive (reclaim or free) */
- struct pglist page_inactive_obj;/* pages inactive (reclaim or free) */
+ struct pglist page_active; /* [Q] allocated pages, in use */
+ struct pglist page_inactive_swp;/* [Q] pages inactive (reclaim/free) */
+ struct pglist page_inactive_obj;/* [Q] pages inactive (reclaim/free) */
/* Lock order: pageqlock, then fpageqlock. */
- struct mutex pageqlock; /* lock for active/inactive page q */
- struct mutex fpageqlock; /* lock for free page q + pdaemon */
+ struct mutex pageqlock; /* [] lock for active/inactive page q */
+ struct mutex fpageqlock; /* [] lock for free page q + pdaemon */
boolean_t page_init_done; /* TRUE if uvm_page_init() finished */
struct uvm_pmr_control pmr_control; /* pmemrange data */
diff --git a/sys/uvm/uvm_anon.c b/sys/uvm/uvm_anon.c
index 889d607719b..11e0892a553 100644
--- a/sys/uvm/uvm_anon.c
+++ b/sys/uvm/uvm_anon.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_anon.c,v 1.49 2020/01/04 16:17:29 beck Exp $ */
+/* $OpenBSD: uvm_anon.c,v 1.50 2020/11/24 13:49:09 mpi Exp $ */
/* $NetBSD: uvm_anon.c,v 1.10 2000/11/25 06:27:59 chs Exp $ */
/*
@@ -106,7 +106,9 @@ uvm_anfree_list(struct vm_anon *anon, struct pglist *pgl)
* clean page, and put on on pglist
* for later freeing.
*/
+ uvm_lock_pageq();
uvm_pageclean(pg);
+ uvm_unlock_pageq();
TAILQ_INSERT_HEAD(pgl, pg, pageq);
} else {
uvm_lock_pageq(); /* lock out pagedaemon */
diff --git a/sys/uvm/uvm_object.c b/sys/uvm/uvm_object.c
index 5fa2f970abc..a2a13753bd1 100644
--- a/sys/uvm/uvm_object.c
+++ b/sys/uvm/uvm_object.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_object.c,v 1.17 2020/10/21 09:08:14 mpi Exp $ */
+/* $OpenBSD: uvm_object.c,v 1.18 2020/11/24 13:49:09 mpi Exp $ */
/*
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -172,7 +172,9 @@ uvm_objfree(struct uvm_object *uobj)
* this pg from the uobj we are throwing away
*/
atomic_clearbits_int(&pg->pg_flags, PG_TABLED);
+ uvm_lock_pageq();
uvm_pageclean(pg);
+ uvm_unlock_pageq();
TAILQ_INSERT_TAIL(&pgl, pg, pageq);
}
uvm_pmr_freepageq(&pgl);
diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c
index 57111599b33..2a7b4e1d65e 100644
--- a/sys/uvm/uvm_page.c
+++ b/sys/uvm/uvm_page.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_page.c,v 1.150 2020/09/22 14:31:08 mpi Exp $ */
+/* $OpenBSD: uvm_page.c,v 1.151 2020/11/24 13:49:09 mpi Exp $ */
/* $NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $ */
/*
@@ -973,6 +973,10 @@ uvm_pageclean(struct vm_page *pg)
{
u_int flags_to_clear = 0;
+#if all_pmap_are_fixed
+ MUTEX_ASSERT_LOCKED(&uvm.pageqlock);
+#endif
+
#ifdef DEBUG
if (pg->uobject == (void *)0xdeadbeef &&
pg->uanon == (void *)0xdeadbeef) {
@@ -1037,6 +1041,10 @@ uvm_pageclean(struct vm_page *pg)
void
uvm_pagefree(struct vm_page *pg)
{
+#if all_pmap_are_fixed
+ MUTEX_ASSERT_LOCKED(&uvm.pageqlock);
+#endif
+
uvm_pageclean(pg);
uvm_pmr_freepages(pg, 1);
}
@@ -1229,6 +1237,8 @@ uvm_pagelookup(struct uvm_object *obj, voff_t off)
void
uvm_pagewire(struct vm_page *pg)
{
+ MUTEX_ASSERT_LOCKED(&uvm.pageqlock);
+
if (pg->wire_count == 0) {
if (pg->pg_flags & PQ_ACTIVE) {
TAILQ_REMOVE(&uvm.page_active, pg, pageq);
@@ -1257,6 +1267,8 @@ uvm_pagewire(struct vm_page *pg)
void
uvm_pageunwire(struct vm_page *pg)
{
+ MUTEX_ASSERT_LOCKED(&uvm.pageqlock);
+
pg->wire_count--;
if (pg->wire_count == 0) {
TAILQ_INSERT_TAIL(&uvm.page_active, pg, pageq);
@@ -1276,6 +1288,8 @@ uvm_pageunwire(struct vm_page *pg)
void
uvm_pagedeactivate(struct vm_page *pg)
{
+ MUTEX_ASSERT_LOCKED(&uvm.pageqlock);
+
if (pg->pg_flags & PQ_ACTIVE) {
TAILQ_REMOVE(&uvm.page_active, pg, pageq);
atomic_clearbits_int(&pg->pg_flags, PQ_ACTIVE);
@@ -1310,6 +1324,8 @@ uvm_pagedeactivate(struct vm_page *pg)
void
uvm_pageactivate(struct vm_page *pg)
{
+ MUTEX_ASSERT_LOCKED(&uvm.pageqlock);
+
if (pg->pg_flags & PQ_INACTIVE) {
if (pg->pg_flags & PQ_SWAPBACKED)
TAILQ_REMOVE(&uvm.page_inactive_swp, pg, pageq);
diff --git a/sys/uvm/uvm_pdaemon.c b/sys/uvm/uvm_pdaemon.c
index d8cb8081004..ea0bd2e00cd 100644
--- a/sys/uvm/uvm_pdaemon.c
+++ b/sys/uvm/uvm_pdaemon.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_pdaemon.c,v 1.87 2020/09/29 11:47:41 mpi Exp $ */
+/* $OpenBSD: uvm_pdaemon.c,v 1.88 2020/11/24 13:49:09 mpi Exp $ */
/* $NetBSD: uvm_pdaemon.c,v 1.23 2000/08/20 10:24:14 bjh21 Exp $ */
/*
@@ -822,6 +822,8 @@ uvmpd_scan(void)
struct uvm_object *uobj;
boolean_t got_it;
+ MUTEX_ASSERT_LOCKED(&uvm.pageqlock);
+
uvmexp.pdrevs++; /* counter */
uobj = NULL;