diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2017-06-02 20:25:51 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2017-06-02 20:25:51 +0000 |
commit | 6f82b06c0ac5c52459be367885599fbe72956f40 (patch) | |
tree | ffbfbea1edb3a0dddea34b6ae3fd4472369f900e /sys | |
parent | c1ebcf148b606d29817e85a5f022a3f3f4f7cc6c (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')
-rw-r--r-- | sys/dev/pv/xen.c | 23 |
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; |