Module Name: src
Committed By: rmind
Date: Sun May 22 04:27:16 UTC 2011
Modified Files:
src/sys/arch/xen/xen: xenevt.c
src/sys/arch/xen/xenbus: xenbus_xs.c
Log Message:
- Replace uses of simple_lock and ltsleep with mutex and condvar.
- Improve some parts of the code to be more MP-friendly.
Tested by jakllsch@.
To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/sys/arch/xen/xen/xenevt.c
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/xen/xenbus/xenbus_xs.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/xen/xen/xenevt.c
diff -u src/sys/arch/xen/xen/xenevt.c:1.36 src/sys/arch/xen/xen/xenevt.c:1.37
--- src/sys/arch/xen/xen/xenevt.c:1.36 Sun Dec 20 09:36:05 2009
+++ src/sys/arch/xen/xen/xenevt.c Sun May 22 04:27:15 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: xenevt.c,v 1.36 2009/12/20 09:36:05 dsl Exp $ */
+/* $NetBSD: xenevt.c,v 1.37 2011/05/22 04:27:15 rmind Exp $ */
/*
* Copyright (c) 2005 Manuel Bouyer.
@@ -26,12 +26,13 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1.36 2009/12/20 09:36:05 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xenevt.c,v 1.37 2011/05/22 04:27:15 rmind Exp $");
#include "opt_xen.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/mutex.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/file.h>
@@ -42,7 +43,6 @@
#include <sys/conf.h>
#include <sys/intr.h>
#include <sys/kmem.h>
-#include <sys/simplelock.h>
#include <uvm/uvm_extern.h>
@@ -103,7 +103,8 @@
#define BYTES_PER_PORT (sizeof(evtchn_port_t) / sizeof(uint8_t))
struct xenevt_d {
- struct simplelock lock;
+ kmutex_t lock;
+ kcondvar_t cv;
STAILQ_ENTRY(xenevt_d) pendingq;
bool pending;
evtchn_port_t ring[2048];
@@ -119,9 +120,8 @@
/* pending events */
static void *devevent_sih;
-struct simplelock devevent_pending_lock = SIMPLELOCK_INITIALIZER;
-STAILQ_HEAD(, xenevt_d) devevent_pending =
- STAILQ_HEAD_INITIALIZER(devevent_pending);
+static kmutex_t devevent_lock;
+static STAILQ_HEAD(, xenevt_d) devevent_pending;
static void xenevt_donotify(struct xenevt_d *);
static void xenevt_record(struct xenevt_d *, evtchn_port_t);
@@ -142,6 +142,8 @@
bool mpsafe = (level != IPL_VM);
#endif /* MULTIPROCESSOR */
+ mutex_init(&devevent_lock, MUTEX_DEFAULT, IPL_HIGH);
+ STAILQ_INIT(&devevent_pending);
devevent_sih = softint_establish(SOFTINT_SERIAL,
(void (*)(void *))xenevt_notify, NULL);
@@ -218,10 +220,11 @@
return;
}
- simple_lock(&devevent_pending_lock);
+ mutex_enter(&devevent_lock);
STAILQ_INSERT_TAIL(&devevent_pending, d, pendingq);
- simple_unlock(&devevent_pending_lock);
d->pending = true;
+ mutex_exit(&devevent_lock);
+
softint_schedule(devevent_sih);
}
}
@@ -229,43 +232,31 @@
void
xenevt_notify(void)
{
+ struct xenevt_d *d;
- int s = splhigh();
- simple_lock(&devevent_pending_lock);
- while (/* CONSTCOND */ 1) {
- struct xenevt_d *d;
-
+ for (;;) {
+ mutex_enter(&devevent_lock);
d = STAILQ_FIRST(&devevent_pending);
if (d == NULL) {
+ mutex_exit(&devevent_lock);
break;
}
STAILQ_REMOVE_HEAD(&devevent_pending, pendingq);
- simple_unlock(&devevent_pending_lock);
- splx(s);
-
d->pending = false;
- xenevt_donotify(d);
+ mutex_exit(&devevent_lock);
- s = splhigh();
- simple_lock(&devevent_pending_lock);
+ xenevt_donotify(d);
}
- simple_unlock(&devevent_pending_lock);
- splx(s);
}
static void
xenevt_donotify(struct xenevt_d *d)
{
- int s;
- s = splsoftserial();
- simple_lock(&d->lock);
-
+ mutex_enter(&d->lock);
selnotify(&d->sel, 0, 1);
- wakeup(&d->ring_read);
-
- simple_unlock(&d->lock);
- splx(s);
+ cv_broadcast(&d->cv);
+ mutex_exit(&d->lock);
}
static void
@@ -303,7 +294,8 @@
return error;
d = malloc(sizeof(*d), M_DEVBUF, M_WAITOK | M_ZERO);
- simple_lock_init(&d->lock);
+ mutex_init(&d->lock, MUTEX_DEFAULT, IPL_SOFTSERIAL);
+ cv_init(&d->cv, "xenevt");
selinit(&d->sel);
return fd_clone(fp, fd, flags, &xenevt_fileops, d);
case DEV_XSD:
@@ -380,8 +372,10 @@
}
}
seldestroy(&d->sel);
- free(d, M_DEVBUF);
+ cv_destroy(&d->cv);
+ mutex_destroy(&d->lock);
fp->f_data = NULL;
+ free(d, M_DEVBUF);
return (0);
}
@@ -391,15 +385,11 @@
kauth_cred_t cred, int flags)
{
struct xenevt_d *d = fp->f_data;
- int error;
+ int error, ring_read, ring_write;
size_t len, uio_len;
- int ring_read;
- int ring_write;
- int s;
error = 0;
- s = splsoftserial();
- simple_lock(&d->lock);
+ mutex_enter(&d->lock);
while (error == 0) {
ring_read = d->ring_read;
ring_write = d->ring_write;
@@ -411,18 +401,16 @@
}
/* nothing to read */
- if (fp->f_flag & FNONBLOCK) {
- error = EAGAIN;
+ if ((fp->f_flag & FNONBLOCK) == 0) {
+ error = cv_wait_sig(&d->cv, &d->lock);
} else {
- error = ltsleep(&d->ring_read, PRIBIO | PCATCH,
- "xenevt", 0, &d->lock);
+ error = EAGAIN;
}
}
if (error == 0 && (d->flags & XENEVT_F_OVERFLOW)) {
error = EFBIG;
}
- simple_unlock(&d->lock);
- splx(s);
+ mutex_exit(&d->lock);
if (error) {
return error;
@@ -452,11 +440,9 @@
ring_read = (ring_read + len) & XENEVT_RING_MASK;
done:
- s = splsoftserial();
- simple_lock(&d->lock);
+ mutex_enter(&d->lock);
d->ring_read = ring_read;
- simple_unlock(&d->lock);
- splx(s);
+ mutex_exit(&d->lock);
return 0;
}
@@ -591,10 +577,8 @@
{
struct xenevt_d *d = fp->f_data;
int revents = events & (POLLOUT | POLLWRNORM); /* we can always write */
- int s;
- s = splsoftserial();
- simple_lock(&d->lock);
+ mutex_enter(&d->lock);
if (events & (POLLIN | POLLRDNORM)) {
if (d->ring_read != d->ring_write) {
revents |= events & (POLLIN | POLLRDNORM);
@@ -603,7 +587,6 @@
selrecord(curlwp, &d->sel);
}
}
- simple_unlock(&d->lock);
- splx(s);
+ mutex_exit(&d->lock);
return (revents);
}
Index: src/sys/arch/xen/xenbus/xenbus_xs.c
diff -u src/sys/arch/xen/xenbus/xenbus_xs.c:1.18 src/sys/arch/xen/xenbus/xenbus_xs.c:1.19
--- src/sys/arch/xen/xenbus/xenbus_xs.c:1.18 Tue Apr 28 05:44:43 2009
+++ src/sys/arch/xen/xenbus/xenbus_xs.c Sun May 22 04:27:15 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: xenbus_xs.c,v 1.18 2009/04/28 05:44:43 cegger Exp $ */
+/* $NetBSD: xenbus_xs.c,v 1.19 2011/05/22 04:27:15 rmind Exp $ */
/******************************************************************************
* xenbus_xs.c
*
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xenbus_xs.c,v 1.18 2009/04/28 05:44:43 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xenbus_xs.c,v 1.19 2011/05/22 04:27:15 rmind Exp $");
#if 0
#define DPRINTK(fmt, args...) \
@@ -48,7 +48,6 @@
#include <sys/proc.h>
#include <sys/mutex.h>
#include <sys/kthread.h>
-#include <sys/simplelock.h>
#include <machine/stdarg.h>
@@ -81,7 +80,8 @@
struct xs_handle {
/* A list of replies. Currently only one will ever be outstanding. */
SIMPLEQ_HEAD(, xs_stored_msg) reply_list;
- struct simplelock reply_lock;
+ kmutex_t reply_lock;
+ kcondvar_t reply_cv;
kmutex_t xs_lock; /* serialize access to xenstore */
int suspend_spl;
@@ -90,14 +90,13 @@
static struct xs_handle xs_state;
/* List of registered watches, and a lock to protect it. */
-static SLIST_HEAD(, xenbus_watch) watches =
- SLIST_HEAD_INITIALIZER(watches);
-static struct simplelock watches_lock = SIMPLELOCK_INITIALIZER;
+static SLIST_HEAD(, xenbus_watch) watches;
+static kmutex_t watches_lock;
/* List of pending watch callback events, and a lock to protect it. */
-static SIMPLEQ_HEAD(, xs_stored_msg) watch_events =
- SIMPLEQ_HEAD_INITIALIZER(watch_events);
-static struct simplelock watch_events_lock = SIMPLELOCK_INITIALIZER;
+static SIMPLEQ_HEAD(, xs_stored_msg) watch_events;
+static kmutex_t watch_events_lock;
+static kcondvar_t watch_cv;
static int
get_error(const char *errorstring)
@@ -120,21 +119,14 @@
{
struct xs_stored_msg *msg;
char *body;
- int s;
-
- simple_lock(&xs_state.reply_lock);
- s = spltty();
+ mutex_enter(&xs_state.reply_lock);
while (SIMPLEQ_EMPTY(&xs_state.reply_list)) {
- ltsleep(&xs_state.reply_list, PRIBIO, "rplq", 0,
- &xs_state.reply_lock);
+ cv_wait(&xs_state.reply_cv, &xs_state.reply_lock);
}
-
msg = SIMPLEQ_FIRST(&xs_state.reply_list);
SIMPLEQ_REMOVE_HEAD(&xs_state.reply_list, msg_next);
-
- splx(s);
- simple_unlock(&xs_state.reply_lock);
+ mutex_exit(&xs_state.reply_lock);
*type = msg->hdr.type;
if (len)
@@ -649,67 +641,64 @@
/* Pointer in ascii is the token. */
char token[sizeof(watch) * 2 + 1];
int err;
- int s;
snprintf(token, sizeof(token), "%lX", (long)watch);
- s = spltty();
-
- simple_lock(&watches_lock);
+ mutex_enter(&watches_lock);
KASSERT(find_watch(token) == 0);
SLIST_INSERT_HEAD(&watches, watch, watch_next);
- simple_unlock(&watches_lock);
+ mutex_exit(&watches_lock);
err = xs_watch(watch->node, token);
/* Ignore errors due to multiple registration. */
if ((err != 0) && (err != EEXIST)) {
- simple_lock(&watches_lock);
+ mutex_enter(&watches_lock);
SLIST_REMOVE(&watches, watch, xenbus_watch, watch_next);
- simple_unlock(&watches_lock);
+ mutex_exit(&watches_lock);
}
-
- splx(s);
-
return err;
}
void
unregister_xenbus_watch(struct xenbus_watch *watch)
{
+ SIMPLEQ_HEAD(, xs_stored_msg) gclist;
struct xs_stored_msg *msg, *next_msg;
char token[sizeof(watch) * 2 + 1];
- int err, s;
+ int err;
snprintf(token, sizeof(token), "%lX", (long)watch);
- s = spltty();
-
- simple_lock(&watches_lock);
+ mutex_enter(&watches_lock);
KASSERT(find_watch(token));
SLIST_REMOVE(&watches, watch, xenbus_watch, watch_next);
- simple_unlock(&watches_lock);
+ mutex_exit(&watches_lock);
err = xs_unwatch(watch->node, token);
- if (err)
+ if (err) {
printf(
"XENBUS Failed to release watch %s: %i\n",
watch->node, err);
-
- splx(s);
+ }
/* Cancel pending watch events. */
- simple_lock(&watch_events_lock);
+ SIMPLEQ_INIT(&gclist);
+ mutex_enter(&watch_events_lock);
for (msg = SIMPLEQ_FIRST(&watch_events); msg != NULL; msg = next_msg) {
next_msg = SIMPLEQ_NEXT(msg, msg_next);
if (msg->u.watch.handle != watch)
continue;
SIMPLEQ_REMOVE(&watch_events, msg, xs_stored_msg, msg_next);
+ SIMPLEQ_INSERT_TAIL(&gclist, msg, msg_next);
+ }
+ mutex_exit(&watch_events_lock);
+
+ while ((msg = SIMPLEQ_FIRST(&gclist)) != NULL) {
+ SIMPLEQ_REMOVE(&gclist, msg, xs_stored_msg, msg_next);
free(msg->u.watch.vec, M_DEVBUF);
free(msg, M_DEVBUF);
}
- simple_unlock(&watch_events_lock);
-
}
void
@@ -735,20 +724,20 @@
static void
xenwatch_thread(void *unused)
{
+ SIMPLEQ_HEAD(, xs_stored_msg) events_to_proces;
struct xs_stored_msg *msg;
- int s;
+ SIMPLEQ_INIT(&events_to_proces);
for (;;) {
- tsleep(&watch_events, PRIBIO, "evtsq", 0);
- s = spltty(); /* to block IPL_CTRL */
- while (!SIMPLEQ_EMPTY(&watch_events)) {
- msg = SIMPLEQ_FIRST(&watch_events);
-
- simple_lock(&watch_events_lock);
- SIMPLEQ_REMOVE_HEAD(&watch_events, msg_next);
- simple_unlock(&watch_events_lock);
- DPRINTK("xenwatch_thread: got event");
+ mutex_enter(&watch_events_lock);
+ cv_wait(&watch_cv, &watch_events_lock);
+ SIMPLEQ_CONCAT(&events_to_proces, &watch_events);
+ mutex_exit(&watch_events_lock);
+ DPRINTK("xenwatch_thread: processing events");
+
+ while ((msg = SIMPLEQ_FIRST(&events_to_proces)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&events_to_proces, msg_next);
msg->u.watch.handle->xbw_callback(
msg->u.watch.handle,
(const char **)msg->u.watch.vec,
@@ -756,8 +745,6 @@
free(msg->u.watch.vec, M_DEVBUF);
free(msg, M_DEVBUF);
}
-
- splx(s);
}
}
@@ -766,7 +753,7 @@
{
struct xs_stored_msg *msg;
char *body;
- int err, s;
+ int err;
msg = malloc(sizeof(*msg), M_DEVBUF, M_NOWAIT);
if (msg == NULL)
@@ -795,6 +782,8 @@
body[msg->hdr.len] = '\0';
if (msg->hdr.type == XS_WATCH_EVENT) {
+ bool found;
+
DPRINTK("process_msg: XS_WATCH_EVENT");
msg->u.watch.vec = split(body, msg->hdr.len,
&msg->u.watch.vec_size);
@@ -803,31 +792,29 @@
return ENOMEM;
}
- simple_lock(&watches_lock);
- s = spltty();
+ mutex_enter(&watches_lock);
msg->u.watch.handle = find_watch(
- msg->u.watch.vec[XS_WATCH_TOKEN]);
- if (msg->u.watch.handle != NULL) {
- simple_lock(&watch_events_lock);
+ msg->u.watch.vec[XS_WATCH_TOKEN]);
+ found = (msg->u.watch.handle != NULL);
+ if (found) {
+ mutex_enter(&watch_events_lock);
SIMPLEQ_INSERT_TAIL(&watch_events, msg, msg_next);
- wakeup(&watch_events);
- simple_unlock(&watch_events_lock);
- } else {
+ cv_broadcast(&watch_cv);
+ mutex_exit(&watch_events_lock);
+ }
+ mutex_exit(&watches_lock);
+ if (!found) {
free(msg->u.watch.vec, M_DEVBUF);
free(msg, M_DEVBUF);
}
- splx(s);
- simple_unlock(&watches_lock);
} else {
DPRINTK("process_msg: type %d body %s", msg->hdr.type, body);
-
+
msg->u.reply.body = body;
- simple_lock(&xs_state.reply_lock);
- s = spltty();
+ mutex_enter(&xs_state.reply_lock);
SIMPLEQ_INSERT_TAIL(&xs_state.reply_list, msg, msg_next);
- splx(s);
- simple_unlock(&xs_state.reply_lock);
- wakeup(&xs_state.reply_list);
+ cv_broadcast(&xs_state.reply_cv);
+ mutex_exit(&xs_state.reply_lock);
}
return 0;
@@ -850,9 +837,17 @@
{
int err;
+ SLIST_INIT(&watches);
+ mutex_init(&watches_lock, MUTEX_DEFAULT, IPL_TTY);
+
+ SIMPLEQ_INIT(&watch_events);
+ mutex_init(&watch_events_lock, MUTEX_DEFAULT, IPL_TTY);
+ cv_init(&watch_cv, "evtsq");
+
SIMPLEQ_INIT(&xs_state.reply_list);
- simple_lock_init(&xs_state.reply_lock);
mutex_init(&xs_state.xs_lock, MUTEX_DEFAULT, IPL_NONE);
+ mutex_init(&xs_state.reply_lock, MUTEX_DEFAULT, IPL_TTY);
+ cv_init(&xs_state.reply_cv, "rplq");
err = kthread_create(PRI_NONE, 0, NULL, xenwatch_thread,
NULL, NULL, "xenwatch");