diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-01-26 15:51:08 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-01-26 15:51:08 +0000 |
commit | 6ad4b45c3bbd0b335877773a3f0824944628605a (patch) | |
tree | ae051cd331ba27c6024782111cc0c3a12e10adcf /sys/dev/pv/xen.c | |
parent | a1fe0bde5148e62c9929743ca593346a2c90f1e2 (diff) |
No need to take a grant table entry mutex in xen_grant_table_{enter,remove}
Grant table API is constructed in a way that once allocated grant table
entries are marked as used and cannot be given away again to some other
user. At the same time xen_grant_table_enter and _remove do not operate
on the same grant reference at the same time, so there's no need for a
lock here. Guard flag operations with memory fences to ensure correct
store/load order. This provides some decent performance improvement as
well.
Diffstat (limited to 'sys/dev/pv/xen.c')
-rw-r--r-- | sys/dev/pv/xen.c | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/sys/dev/pv/xen.c b/sys/dev/pv/xen.c index 5cd8b66fd04..138e5e36c55 100644 --- a/sys/dev/pv/xen.c +++ b/sys/dev/pv/xen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xen.c,v 1.38 2016/01/26 15:35:21 mikeb Exp $ */ +/* $OpenBSD: xen.c,v 1.39 2016/01/26 15:51:07 mikeb Exp $ */ /* * Copyright (c) 2015 Mike Belopuhov @@ -924,12 +924,11 @@ xen_grant_table_enter(struct xen_softc *sc, grant_ref_t ref, paddr_t pa, if (ref < ge->ge_start || ref > ge->ge_start + GNTTAB_NEPG) continue; ref -= ge->ge_start; - mtx_enter(&ge->ge_mtx); ge->ge_table[ref].frame = atop(pa); ge->ge_table[ref].domid = 0; virtio_membar_sync(); ge->ge_table[ref].flags = GTF_permit_access | flags; - mtx_leave(&ge->ge_mtx); + virtio_membar_sync(); return (0); } return (ENOBUFS); @@ -947,14 +946,13 @@ xen_grant_table_remove(struct xen_softc *sc, grant_ref_t ref) continue; ref -= ge->ge_start; - mtx_enter(&ge->ge_mtx); /* Invalidate the grant reference */ + virtio_membar_sync(); ptr = (uint32_t *)&ge->ge_table[ref]; flags = (ge->ge_table[ref].flags & ~(GTF_reading | GTF_writing)); loop = 0; while (atomic_cas_uint(ptr, flags, GTF_invalid) != flags) { if (loop++ > 10000000) { - mtx_leave(&ge->ge_mtx); printf("%s: grant table reference %u is held by " "domain %d\n", sc->sc_dev.dv_xname, ref + ge->ge_start, ge->ge_table[ref].domid); @@ -963,7 +961,6 @@ xen_grant_table_remove(struct xen_softc *sc, grant_ref_t ref) CPU_BUSY_CYCLE(); } ge->ge_table[ref].frame = 0xffffffff; - mtx_leave(&ge->ge_mtx); break; } } |