summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2014-09-09 03:08:31 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2014-09-09 03:08:31 +0000
commite53bf16d9b38d7d93c5dd1cefe25ee6f4a5b8086 (patch)
treeb5daedc12418f77b54b6e5c65710bed3febcd9a4
parenta5b3fd83d62eb29fb2f7392b62789473fe817dbf (diff)
mark the interrupt handler mpsafe, and give up biglock in the scsi cmd
submission paths. take biglock again when calling back into the scsi stack. tested on a variety of cards here, including the skinny mfis on the firewall next to mpsafe myx.
-rw-r--r--sys/dev/ic/mfi.c17
-rw-r--r--sys/dev/pci/mfi_pci.c6
2 files changed, 19 insertions, 4 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c
index 8ec4c95d8a2..ef97bc86cbc 100644
--- a/sys/dev/ic/mfi.c
+++ b/sys/dev/ic/mfi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfi.c,v 1.155 2014/08/15 02:27:02 yasuoka Exp $ */
+/* $OpenBSD: mfi.c,v 1.156 2014/09/09 03:08:30 dlg Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -199,6 +199,8 @@ mfi_get_ccb(void *cookie)
struct mfi_softc *sc = cookie;
struct mfi_ccb *ccb;
+ KERNEL_UNLOCK();
+
mtx_enter(&sc->sc_ccb_mtx);
ccb = SLIST_FIRST(&sc->sc_ccb_freeq);
if (ccb != NULL) {
@@ -208,6 +210,7 @@ mfi_get_ccb(void *cookie)
mtx_leave(&sc->sc_ccb_mtx);
DNPRINTF(MFI_D_CCB, "%s: mfi_get_ccb: %p\n", DEVNAME(sc), ccb);
+ KERNEL_LOCK();
return (ccb);
}
@@ -220,9 +223,11 @@ mfi_put_ccb(void *cookie, void *io)
DNPRINTF(MFI_D_CCB, "%s: mfi_put_ccb: %p\n", DEVNAME(sc), ccb);
+ KERNEL_UNLOCK();
mtx_enter(&sc->sc_ccb_mtx);
SLIST_INSERT_HEAD(&sc->sc_ccb_freeq, ccb, ccb_link);
mtx_leave(&sc->sc_ccb_mtx);
+ KERNEL_LOCK();
}
void
@@ -1108,7 +1113,9 @@ mfi_scsi_xs_done(struct mfi_softc *sc, struct mfi_ccb *ccb)
break;
}
+ KERNEL_LOCK();
scsi_done(xs);
+ KERNEL_UNLOCK();
}
int
@@ -1174,6 +1181,8 @@ mfi_scsi_cmd(struct scsi_xfer *xs)
DNPRINTF(MFI_D_CMD, "%s: mfi_scsi_cmd opcode: %#x\n",
DEVNAME(sc), xs->cmd->opcode);
+ KERNEL_UNLOCK();
+
if (!sc->sc_ld[target].ld_present) {
DNPRINTF(MFI_D_CMD, "%s: invalid target %d\n",
DEVNAME(sc), target);
@@ -1236,11 +1245,13 @@ mfi_scsi_cmd(struct scsi_xfer *xs)
else
mfi_start(sc, ccb);
+ KERNEL_LOCK();
return;
stuffup:
xs->error = XS_DRIVER_STUFFUP;
complete:
+ KERNEL_LOCK();
scsi_done(xs);
}
@@ -2492,6 +2503,8 @@ mfi_pd_scsi_cmd(struct scsi_xfer *xs)
struct mfi_pass_frame *pf = &ccb->ccb_frame->mfr_pass;
struct mfi_pd_link *pl = sc->sc_pd->pd_links[link->target];
+ KERNEL_UNLOCK();
+
mfi_scrub_ccb(ccb);
xs->error = XS_NOERROR;
@@ -2532,9 +2545,11 @@ mfi_pd_scsi_cmd(struct scsi_xfer *xs)
else
mfi_start(sc, ccb);
+ KERNEL_LOCK();
return;
stuffup:
xs->error = XS_DRIVER_STUFFUP;
+ KERNEL_LOCK();
scsi_done(xs);
}
diff --git a/sys/dev/pci/mfi_pci.c b/sys/dev/pci/mfi_pci.c
index c2f475ffb00..787c2344b80 100644
--- a/sys/dev/pci/mfi_pci.c
+++ b/sys/dev/pci/mfi_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfi_pci.c,v 1.28 2012/08/14 04:10:14 dlg Exp $ */
+/* $OpenBSD: mfi_pci.c,v 1.29 2014/09/09 03:08:30 dlg Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -133,8 +133,8 @@ mfi_pci_attach(struct device *parent, struct device *self, void *aux)
}
printf(": %s\n", pci_intr_string(pa->pa_pc, ih));
- sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, mfi_intr, sc,
- sc->sc_dev.dv_xname);
+ sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO | IPL_MPSAFE,
+ mfi_intr, sc, sc->sc_dev.dv_xname);
if (!sc->sc_ih) {
printf("%s: can't establish interrupt\n", DEVNAME(sc));
goto unmap;