summaryrefslogtreecommitdiff
path: root/sys/arch/i386/include
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2015-07-02 16:14:44 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2015-07-02 16:14:44 +0000
commite37d569b09e41ae93bf7ac579345231386b390e2 (patch)
tree550fdf9a0e6364d30bc1ea160b11bed40c978a5c /sys/arch/i386/include
parente3fa8cd9f440441f5f9e23fcc742e8b78ffb3136 (diff)
Make the i386 pmap (almost) mpsafe by protecting the pmap itself, the pv
lists and the apte with a mutex. Rearrange some code to avoid sleeping/spinning with one of these locks held. This should make pmap_enter(9), pmap_remove(9) and pmap_page_protect(9) safe to use without holding the kernel lock. Unfortunately there still seems to be an issue that causes deadlocks under pressure. That shouldn't be an issue as long as uvm still calls the pmap functions with the kernel lock held. Hopefully committed this will help finding the last bugs. ok mlarkin@, deraadt@
Diffstat (limited to 'sys/arch/i386/include')
-rw-r--r--sys/arch/i386/include/pmap.h12
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/arch/i386/include/pmap.h b/sys/arch/i386/include/pmap.h
index b77de930fb5..1acab8dc63d 100644
--- a/sys/arch/i386/include/pmap.h
+++ b/sys/arch/i386/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.75 2015/04/21 00:07:51 mlarkin Exp $ */
+/* $OpenBSD: pmap.h,v 1.76 2015/07/02 16:14:43 kettenis Exp $ */
/* $NetBSD: pmap.h,v 1.44 2000/04/24 17:18:18 thorpej Exp $ */
/*
@@ -38,8 +38,9 @@
#include <machine/cpufunc.h>
#include <machine/segments.h>
#endif
-#include <machine/pte.h>
+#include <sys/mutex.h>
#include <uvm/uvm_object.h>
+#include <machine/pte.h>
/*
* The following defines give the virtual addresses of various MMU
@@ -98,11 +99,14 @@ LIST_HEAD(pmap_head, pmap); /* struct pmap_head: head of a pmap list */
struct pmap {
uint64_t pm_pdidx[4]; /* PDIEs for PAE mode */
+
+ struct mutex pm_mtx;
+ struct mutex pm_apte_mtx;
+
paddr_t pm_pdirpa; /* PA of PD (read-only after create) */
vaddr_t pm_pdir; /* VA of PD (lck by object lock) */
int pm_pdirsize; /* PD size (4k vs 16k on PAE) */
struct uvm_object pm_obj; /* object (lck by object lock) */
-#define pm_lock pm_obj.vmobjlock
LIST_ENTRY(pmap) pm_list; /* list (lck by pm_list lock) */
struct vm_page *pm_ptphint; /* pointer to a PTP in our pmap */
struct pmap_statistics pm_stats; /* pmap stats (lck by object lock) */
@@ -477,10 +481,12 @@ void pmap_ldt_cleanup(struct proc *);
struct pv_entry;
struct vm_page_md {
+ struct mutex pv_mtx;
struct pv_entry *pv_list;
};
#define VM_MDPAGE_INIT(pg) do { \
+ mtx_init(&(pg)->mdpage.pv_mtx, IPL_VM); \
(pg)->mdpage.pv_list = NULL; \
} while (0)