summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2016-11-29 12:12:30 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2016-11-29 12:12:30 +0000
commitd9177fdc2199b0949b1ebdb193c0d04e60bc10cb (patch)
tree462d1d2be48b0c14c63da56b3bd51014ce64cbb8 /sys
parent60d63461a21e4ba80eae9df4eb31ca666d333c55 (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.c40
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);
}