From c929981af89042071b1ca9f54a2d9249eacba930 Mon Sep 17 00:00:00 2001 From: mikeb Date: Fri, 2 Jun 2017 20:25:50 +0000 Subject: [PATCH] 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. --- sys/dev/pv/xen.c | 23 ++++++++++++----------- 1 file 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; -- 2.20.1