summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2017-06-02 20:25:51 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2017-06-02 20:25:51 +0000
commit6f82b06c0ac5c52459be367885599fbe72956f40 (patch)
treeffbfbea1edb3a0dddea34b6ae3fd4472369f900e /sys/dev
parentc1ebcf148b606d29817e85a5f022a3f3f4f7cc6c (diff)
Perform grant table page allocation outside of the table mutex
witness(4) has found that km_alloc will trigger an rw_enter via uvm_map and vm_map_lock. While rw_enter is called with RW_SLEEPFAIL, there's also an msleep in there, so it's easier to avoid getting in the middle of that.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pv/xen.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/sys/dev/pv/xen.c b/sys/dev/pv/xen.c
index 9a469ae513a..96795da2957 100644
--- a/sys/dev/pv/xen.c
+++ b/sys/dev/pv/xen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xen.c,v 1.81 2017/03/19 16:55:31 mikeb Exp $ */
+/* $OpenBSD: xen.c,v 1.82 2017/06/02 20:25:50 mikeb Exp $ */
/*
* Copyright (c) 2015, 2016, 2017 Mike Belopuhov
@@ -988,6 +988,7 @@ xen_grant_table_grow(struct xen_softc *sc)
{
struct xen_add_to_physmap xatp;
struct xen_gntent *ge;
+ void *va;
paddr_t pa;
if (sc->sc_gntcnt == sc->sc_gntmax) {
@@ -996,21 +997,21 @@ xen_grant_table_grow(struct xen_softc *sc)
return (NULL);
}
- mtx_enter(&sc->sc_gntlck);
-
- ge = &sc->sc_gnt[sc->sc_gntcnt];
- ge->ge_table = km_alloc(PAGE_SIZE, &kv_any, &kp_zero, &kd_nowait);
- if (ge->ge_table == NULL) {
- mtx_leave(&sc->sc_gntlck);
+ va = km_alloc(PAGE_SIZE, &kv_any, &kp_zero, &kd_nowait);
+ if (va == NULL)
return (NULL);
- }
- if (!pmap_extract(pmap_kernel(), (vaddr_t)ge->ge_table, &pa)) {
+ if (!pmap_extract(pmap_kernel(), (vaddr_t)va, &pa)) {
printf("%s: grant table page PA extraction failed\n",
sc->sc_dev.dv_xname);
- km_free(ge->ge_table, PAGE_SIZE, &kv_any, &kp_zero);
- mtx_leave(&sc->sc_gntlck);
+ km_free(va, PAGE_SIZE, &kv_any, &kp_zero);
return (NULL);
}
+
+ mtx_enter(&sc->sc_gntlck);
+
+ ge = &sc->sc_gnt[sc->sc_gntcnt];
+ ge->ge_table = va;
+
xatp.domid = DOMID_SELF;
xatp.idx = sc->sc_gntcnt;
xatp.space = XENMAPSPACE_grant_table;