summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorVitaliy Makkoveev <mvs@cvs.openbsd.org>2023-10-25 09:36:48 +0000
committerVitaliy Makkoveev <mvs@cvs.openbsd.org>2023-10-25 09:36:48 +0000
commitde766daeafc40564c8f26aa2e3f060623ebbbfc6 (patch)
treebdd67f4da3a584439c4614d59af0f489ec025750 /sys/dev
parentec78e67f563567925b22a707d2c5685642d03221 (diff)
Make `vscsi_filtops' mpsafe. filt_vscsiread() checks `sc_ccb_i2t'
protected by `sc_state_mtx' mutex(9), so use it to protect `sc_klist' knotes list too. ok claudio
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/vscsi.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/sys/dev/vscsi.c b/sys/dev/vscsi.c
index 0c39f1a0897..53adb499ac7 100644
--- a/sys/dev/vscsi.c
+++ b/sys/dev/vscsi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vscsi.c,v 1.61 2022/07/02 08:50:41 visa Exp $ */
+/* $OpenBSD: vscsi.c,v 1.62 2023/10/25 09:36:47 mvs Exp $ */
/*
* Copyright (c) 2008 David Gwynne <dlg@openbsd.org>
@@ -27,13 +27,18 @@
#include <sys/pool.h>
#include <sys/task.h>
#include <sys/ioctl.h>
-#include <sys/selinfo.h>
+#include <sys/event.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#include <dev/vscsivar.h>
+/*
+ * Locks used to protect struct members and global data
+ * s sc_state_mtx
+ */
+
int vscsi_match(struct device *, void *, void *);
void vscsi_attach(struct device *, struct device *, void *);
void vscsi_shutdown(void *);
@@ -64,14 +69,13 @@ struct vscsi_softc {
struct scsi_iopool sc_iopool;
- struct vscsi_ccb_list sc_ccb_i2t;
+ struct vscsi_ccb_list sc_ccb_i2t; /* [s] */
struct vscsi_ccb_list sc_ccb_t2i;
int sc_ccb_tag;
struct mutex sc_poll_mtx;
struct rwlock sc_ioc_lock;
- struct selinfo sc_sel;
- struct mutex sc_sel_mtx;
+ struct klist sc_klist; /* [s] */
};
#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
@@ -110,12 +114,16 @@ void vscsi_ccb_put(void *, void *);
void filt_vscsidetach(struct knote *);
int filt_vscsiread(struct knote *, long);
+int filt_vscsimodify(struct kevent *, struct knote *);
+int filt_vscsiprocess(struct knote *, struct kevent *);
const struct filterops vscsi_filtops = {
- .f_flags = FILTEROP_ISFD,
+ .f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE,
.f_attach = NULL,
.f_detach = filt_vscsidetach,
.f_event = filt_vscsiread,
+ .f_modify = filt_vscsimodify,
+ .f_process = filt_vscsiprocess,
};
@@ -133,15 +141,15 @@ vscsi_attach(struct device *parent, struct device *self, void *aux)
printf("\n");
- mtx_init(&sc->sc_state_mtx, IPL_BIO);
+ mtx_init(&sc->sc_state_mtx, IPL_MPFLOOR);
sc->sc_state = VSCSI_S_CLOSED;
TAILQ_INIT(&sc->sc_ccb_i2t);
TAILQ_INIT(&sc->sc_ccb_t2i);
mtx_init(&sc->sc_poll_mtx, IPL_BIO);
- mtx_init(&sc->sc_sel_mtx, IPL_BIO);
rw_init(&sc->sc_ioc_lock, "vscsiioc");
scsi_iopool_init(&sc->sc_iopool, sc, vscsi_ccb_get, vscsi_ccb_put);
+ klist_init_mutex(&sc->sc_klist, &sc->sc_state_mtx);
saa.saa_adapter = &vscsi_switch;
saa.saa_adapter_softc = sc;
@@ -181,6 +189,7 @@ vscsi_cmd(struct scsi_xfer *xs)
running = 1;
TAILQ_INSERT_TAIL(&sc->sc_ccb_i2t, ccb, ccb_entry);
}
+ knote_locked(&sc->sc_klist, 0);
mtx_leave(&sc->sc_state_mtx);
if (!running) {
@@ -189,8 +198,6 @@ vscsi_cmd(struct scsi_xfer *xs)
return;
}
- selwakeup(&sc->sc_sel);
-
if (polled) {
mtx_enter(&sc->sc_poll_mtx);
while (ccb->ccb_xs != NULL)
@@ -530,13 +537,10 @@ int
vscsikqfilter(dev_t dev, struct knote *kn)
{
struct vscsi_softc *sc = DEV2SC(dev);
- struct klist *klist;
if (sc == NULL)
return (ENXIO);
- klist = &sc->sc_sel.si_note;
-
switch (kn->kn_filter) {
case EVFILT_READ:
kn->kn_fop = &vscsi_filtops;
@@ -547,10 +551,7 @@ vscsikqfilter(dev_t dev, struct knote *kn)
}
kn->kn_hook = sc;
-
- mtx_enter(&sc->sc_sel_mtx);
- klist_insert_locked(klist, kn);
- mtx_leave(&sc->sc_sel_mtx);
+ klist_insert(&sc->sc_klist, kn);
/* device ref is given to the knote in the klist */
@@ -561,12 +562,8 @@ void
filt_vscsidetach(struct knote *kn)
{
struct vscsi_softc *sc = kn->kn_hook;
- struct klist *klist = &sc->sc_sel.si_note;
-
- mtx_enter(&sc->sc_sel_mtx);
- klist_remove_locked(klist, kn);
- mtx_leave(&sc->sc_sel_mtx);
+ klist_remove(&sc->sc_klist, kn);
device_unref(&sc->sc_dev);
}
@@ -574,14 +571,34 @@ int
filt_vscsiread(struct knote *kn, long hint)
{
struct vscsi_softc *sc = kn->kn_hook;
- int event = 0;
+
+ return (!TAILQ_EMPTY(&sc->sc_ccb_i2t));
+}
+
+int
+filt_vscsimodify(struct kevent *kev, struct knote *kn)
+{
+ struct vscsi_softc *sc = kn->kn_hook;
+ int active;
+
+ mtx_enter(&sc->sc_state_mtx);
+ active = knote_modify(kev, kn);
+ mtx_leave(&sc->sc_state_mtx);
+
+ return (active);
+}
+
+int
+filt_vscsiprocess(struct knote *kn, struct kevent *kev)
+{
+ struct vscsi_softc *sc = kn->kn_hook;
+ int active;
mtx_enter(&sc->sc_state_mtx);
- if (!TAILQ_EMPTY(&sc->sc_ccb_i2t))
- event = 1;
+ active = knote_process(kn, kev);
mtx_leave(&sc->sc_state_mtx);
- return (event);
+ return (active);
}
int