From 22cf3f4dc18f4ca08d182c94036a857ca85ae64e Mon Sep 17 00:00:00 2001 From: Martin Pieuchot Date: Tue, 24 Nov 2020 13:49:10 +0000 Subject: 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@ --- sys/uvm/uvm.h | 16 +++++++++------- sys/uvm/uvm_anon.c | 4 +++- sys/uvm/uvm_object.c | 4 +++- sys/uvm/uvm_page.c | 18 +++++++++++++++++- sys/uvm/uvm_pdaemon.c | 4 +++- 5 files changed, 35 insertions(+), 11 deletions(-) (limited to 'sys/uvm') 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; -- cgit v1.2.3