diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2014-07-01 01:56:40 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2014-07-01 01:56:40 +0000 |
commit | 22ea77ffb1deda5334731ff2e287dd63b0d0e9e3 (patch) | |
tree | 3810e7d171932201e9e4d4b350ea308e6588ec3e /sys/scsi | |
parent | 45e2bc9e88e1f16597c25dd89675dd0fd0dc3577 (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/scsi')
-rw-r--r-- | sys/scsi/scsi_base.c | 35 |
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); |