diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-11-29 12:12:30 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-11-29 12:12:30 +0000 |
commit | d9177fdc2199b0949b1ebdb193c0d04e60bc10cb (patch) | |
tree | 462d1d2be48b0c14c63da56b3bd51014ce64cbb8 /sys | |
parent | 60d63461a21e4ba80eae9df4eb31ca666d333c55 (diff) |
Replace the hand-rolled semaphore with a read-write lock
This was sitting in my tree for many a month and since the introduction
of interrupt threads, the interrupt vs. process context interlock became
irrelevant. Taking uncontended write locks while "cold" doesn't look
like a big deal as well.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pv/xenstore.c | 40 |
1 files changed, 9 insertions, 31 deletions
diff --git a/sys/dev/pv/xenstore.c b/sys/dev/pv/xenstore.c index b3c2ee9ac18..135db321d75 100644 --- a/sys/dev/pv/xenstore.c +++ b/sys/dev/pv/xenstore.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xenstore.c,v 1.29 2016/07/29 21:05:26 mikeb Exp $ */ +/* $OpenBSD: xenstore.c,v 1.30 2016/11/29 12:12:29 mikeb Exp $ */ /* * Copyright (c) 2015 Mike Belopuhov @@ -23,6 +23,7 @@ #include <sys/malloc.h> #include <sys/device.h> #include <sys/mutex.h> +#include <sys/rwlock.h> #include <sys/ioctl.h> #include <sys/task.h> @@ -166,7 +167,7 @@ struct xs_softc { struct mutex xs_watchlck; struct xs_msg xs_emsg; - uint xs_rngsem; + struct rwlock xs_rnglck; }; struct xs_msg * @@ -243,6 +244,8 @@ xs_attach(struct xen_softc *sc) mtx_init(&xs->xs_rsplck, IPL_NET); mtx_init(&xs->xs_frqlck, IPL_NET); + rw_init(&xs->xs_rnglck, "xsrnglck"); + mtx_init(&xs->xs_watchlck, IPL_NET); TAILQ_INIT(&xs->xs_watches); @@ -265,25 +268,6 @@ xs_attach(struct xen_softc *sc) return (-1); } -static inline int -xs_sem_get(uint *semaphore) -{ - if (atomic_inc_int_nv(semaphore) != 1) { - /* we're out of luck */ - if (atomic_dec_int_nv(semaphore) == 0) - wakeup(semaphore); - return (0); - } - return (1); -} - -static inline void -xs_sem_put(uint *semaphore) -{ - if (atomic_dec_int_nv(semaphore) == 0) - wakeup(semaphore); -} - struct xs_msg * xs_get_msg(struct xs_softc *xs, int waitok) { @@ -386,19 +370,13 @@ xs_start(struct xs_transaction *xst, struct xs_msg *xsm, struct iovec *iov, struct xs_softc *xs = xst->xst_sc; int i; - while (!xs_sem_get(&xs->xs_rngsem)) { - if (xst->xst_flags & XST_POLL) - delay(XST_DELAY * 1000 >> 2); - else - tsleep(&xs->xs_rngsem, PRIBIO, "xsaccess", - XST_DELAY * hz >> 2); - } + rw_enter_write(&xs->xs_rnglck); /* Header */ if (xs_output(xst, (uint8_t *)&xsm->xsm_hdr, sizeof(xsm->xsm_hdr)) == -1) { printf("%s: failed to write the header\n", __func__); - xs_sem_put(&xs->xs_rngsem); + rw_exit_write(&xs->xs_rnglck); return (-1); } @@ -407,7 +385,7 @@ xs_start(struct xs_transaction *xst, struct xs_msg *xsm, struct iovec *iov, if (xs_output(xst, iov[i].iov_base, iov[i].iov_len) == -1) { printf("%s: failed on iovec #%d len %ld\n", __func__, i, iov[i].iov_len); - xs_sem_put(&xs->xs_rngsem); + rw_exit_write(&xs->xs_rnglck); return (-1); } } @@ -418,7 +396,7 @@ xs_start(struct xs_transaction *xst, struct xs_msg *xsm, struct iovec *iov, xen_intr_signal(xs->xs_ih); - xs_sem_put(&xs->xs_rngsem); + rw_exit_write(&xs->xs_rnglck); return (0); } |