summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2014-07-01 01:56:40 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2014-07-01 01:56:40 +0000
commit22ea77ffb1deda5334731ff2e287dd63b0d0e9e3 (patch)
tree3810e7d171932201e9e4d4b350ea308e6588ec3e /sys
parent45e2bc9e88e1f16597c25dd89675dd0fd0dc3577 (diff)
start on being able to safely run io through the midlayer without
the kernel biglock. the plan is to have the midlayer assume its running without the biglock, but that it cant call adapters or devices without taking the biglock first. this diff just wraps the calls to the adapter iopool get and put handlers up in the biglock. this is safe now because of kettenis' commit to src/sys/kern/init_main.c r1.120. ive been running this in various places since early 2011.
Diffstat (limited to 'sys')
-rw-r--r--sys/scsi/scsi_base.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c
index 769815b7cf7..0ff951ae498 100644
--- a/sys/scsi/scsi_base.c
+++ b/sys/scsi/scsi_base.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsi_base.c,v 1.211 2014/04/22 07:29:11 dlg Exp $ */
+/* $OpenBSD: scsi_base.c,v 1.212 2014/07/01 01:56:39 dlg Exp $ */
/* $NetBSD: scsi_base.c,v 1.43 1997/04/02 02:29:36 mycroft Exp $ */
/*
@@ -86,6 +86,9 @@ void scsi_xsh_ioh(void *, void *);
int scsi_link_open(struct scsi_link *);
void scsi_link_close(struct scsi_link *);
+void * scsi_iopool_get(struct scsi_iopool *);
+void scsi_iopool_put(struct scsi_iopool *, void *);
+
/* ioh/xsh queue state */
#define RUNQ_IDLE 0
#define RUNQ_LINKQ 1
@@ -235,6 +238,26 @@ scsi_iopool_init(struct scsi_iopool *iopl, void *iocookie,
mtx_init(&iopl->mtx, IPL_BIO);
}
+void *
+scsi_iopool_get(struct scsi_iopool *iopl)
+{
+ void *io;
+
+ KERNEL_LOCK();
+ io = iopl->io_get(iopl->iocookie);
+ KERNEL_UNLOCK();
+
+ return (io);
+}
+
+void
+scsi_iopool_put(struct scsi_iopool *iopl, void *io)
+{
+ KERNEL_LOCK();
+ iopl->io_put(iopl->iocookie, io);
+ KERNEL_UNLOCK();
+}
+
void
scsi_iopool_destroy(struct scsi_iopool *iopl)
{
@@ -385,13 +408,13 @@ scsi_iopool_run(struct scsi_iopool *iopl)
return;
do {
while (scsi_ioh_pending(iopl)) {
- io = iopl->io_get(iopl->iocookie);
+ io = scsi_iopool_get(iopl);
if (io == NULL)
break;
ioh = scsi_ioh_deq(iopl);
if (ioh == NULL) {
- iopl->io_put(iopl->iocookie, io);
+ scsi_iopool_put(iopl, io);
break;
}
@@ -437,7 +460,7 @@ scsi_io_get(struct scsi_iopool *iopl, int flags)
void *io;
/* try and sneak an io off the backend immediately */
- io = iopl->io_get(iopl->iocookie);
+ io = scsi_iopool_get(iopl);
if (io != NULL)
return (io);
else if (ISSET(flags, SCSI_NOSLEEP))
@@ -460,7 +483,7 @@ scsi_io_get_done(void *cookie, void *io)
void
scsi_io_put(struct scsi_iopool *iopl, void *io)
{
- iopl->io_put(iopl->iocookie, io);
+ scsi_iopool_put(iopl, io);
scsi_iopool_run(iopl);
}
@@ -617,7 +640,7 @@ scsi_xs_get(struct scsi_link *link, int flags)
return (NULL);
io = m.io;
- } else if ((io = iopl->io_get(iopl->iocookie)) == NULL) {
+ } else if ((io = scsi_iopool_get(iopl)) == NULL) {
if (ISSET(flags, SCSI_NOSLEEP)) {
scsi_link_close(link);
return (NULL);