diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-07-02 16:14:44 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-07-02 16:14:44 +0000 |
commit | e37d569b09e41ae93bf7ac579345231386b390e2 (patch) | |
tree | 550fdf9a0e6364d30bc1ea160b11bed40c978a5c /sys/arch/i386/include | |
parent | e3fa8cd9f440441f5f9e23fcc742e8b78ffb3136 (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.h | 12 |
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) |