diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-01-26 15:35:22 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-01-26 15:35:22 +0000 |
commit | 7f6be3534ee0eb24195e4350ebdf4e352876cfa9 (patch) | |
tree | 316d2a09ed5b1d5d5ac441e28512146dc24d2e9f /sys/dev | |
parent | 4863df7cd3688799de3c274f9e23b864803968f4 (diff) |
Add a grant table reference invalidation spin out check
This debugging check has been helpful in identifying and fixing
a few issues already. Subject to removal in the future however.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pv/xen.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/sys/dev/pv/xen.c b/sys/dev/pv/xen.c index 4c19687e5c6..5cd8b66fd04 100644 --- a/sys/dev/pv/xen.c +++ b/sys/dev/pv/xen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xen.c,v 1.37 2016/01/26 15:31:02 mikeb Exp $ */ +/* $OpenBSD: xen.c,v 1.38 2016/01/26 15:35:21 mikeb Exp $ */ /* * Copyright (c) 2015 Mike Belopuhov @@ -940,6 +940,7 @@ xen_grant_table_remove(struct xen_softc *sc, grant_ref_t ref) { struct xen_gntent *ge; uint32_t flags, *ptr; + int loop; SLIST_FOREACH(ge, &sc->sc_gnts, ge_entry) { if (ref < ge->ge_start || ref > ge->ge_start + GNTTAB_NEPG) @@ -950,8 +951,17 @@ xen_grant_table_remove(struct xen_softc *sc, grant_ref_t ref) /* Invalidate the grant reference */ ptr = (uint32_t *)&ge->ge_table[ref]; flags = (ge->ge_table[ref].flags & ~(GTF_reading | GTF_writing)); - while (atomic_cas_uint(ptr, flags, GTF_invalid) != flags) + 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); + return; + } CPU_BUSY_CYCLE(); + } ge->ge_table[ref].frame = 0xffffffff; mtx_leave(&ge->ge_mtx); break; |