summaryrefslogtreecommitdiff
path: root/sys/dev/pci/mpii.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2016-10-21 05:38:54 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2016-10-21 05:38:54 +0000
commitd66165444be3ed84f18a8d5a2fe5afc088beb166 (patch)
tree1304a67f3ac452e9cd927c7d0c6e09b8e6cc79fb /sys/dev/pci/mpii.c
parentfceff95fd1ee05b1d9f92665c8d289ab6d3c91c3 (diff)
mitigate against mpii device attachment racing with mountroot
mpii devices get attached by processing sas discovery events after threads are running, but if you have a lean (in terms of devices) and fast machine, these events might run after mountroot. this change has mpii use config_pending_incr() before it attaches scsibus, and runs config_pending_decr() after the first scan of the bus is complete. to make sure config_pending_decr() is run after the scsi attach/detach events are processed, the MPII_EVENT_SAS_DISCOVERY events are deferred to the same context that the MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST events run in. ok jmatthew@
Diffstat (limited to 'sys/dev/pci/mpii.c')
-rw-r--r--sys/dev/pci/mpii.c54
1 files changed, 42 insertions, 12 deletions
diff --git a/sys/dev/pci/mpii.c b/sys/dev/pci/mpii.c
index 90a24e9dd14..fc5e5ae9fc8 100644
--- a/sys/dev/pci/mpii.c
+++ b/sys/dev/pci/mpii.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpii.c,v 1.105 2016/09/14 01:14:54 jmatthew Exp $ */
+/* $OpenBSD: mpii.c,v 1.106 2016/10/21 05:38:53 dlg Exp $ */
/*
* Copyright (c) 2010, 2012 Mike Belopuhov
* Copyright (c) 2009 James Giannoules
@@ -164,6 +164,7 @@ struct mpii_softc {
int sc_flags;
#define MPII_F_RAID (1<<1)
#define MPII_F_SAS3 (1<<2)
+#define MPII_F_CONFIG_PENDING (1<<3)
struct scsibus_softc *sc_scsibus;
@@ -344,6 +345,8 @@ void mpii_event_done(struct mpii_softc *, struct mpii_rcb *);
void mpii_event_sas(void *);
void mpii_event_raid(struct mpii_softc *,
struct mpii_msg_event_reply *);
+void mpii_event_discovery(struct mpii_softc *,
+ struct mpii_msg_event_reply *);
void mpii_sas_remove_device(struct mpii_softc *, u_int16_t);
@@ -590,6 +593,10 @@ mpii_attach(struct device *parent, struct device *self, void *aux)
if (sc->sc_ih == NULL)
goto free_devs;
+ /* force autoconf to wait for the first sas discovery to complete */
+ SET(sc->sc_flags, MPII_F_CONFIG_PENDING);
+ config_pending_incr();
+
/* config_found() returns the scsibus attached to us */
sc->sc_scsibus = (struct scsibus_softc *) config_found(&sc->sc_dev,
&saa, scsiprint);
@@ -1795,6 +1802,19 @@ mpii_event_sas(void *xsc)
task_add(systq, &sc->sc_evt_sas_task);
enp = (struct mpii_msg_event_reply *)rcb->rcb_reply;
+ switch (lemtoh16(&enp->event)) {
+ case MPII_EVENT_SAS_DISCOVERY:
+ mpii_event_discovery(sc, enp);
+ goto done;
+ case MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
+ /* handle below */
+ break;
+ default:
+ panic("%s: unexpected event %#x in sas event queue",
+ DEVNAME(sc), lemtoh16(&enp->event));
+ /* NOTREACHED */
+ }
+
tcl = (struct mpii_evt_sas_tcl *)(enp + 1);
pe = (struct mpii_evt_phy_entry *)(tcl + 1);
@@ -1846,10 +1866,30 @@ mpii_event_sas(void *xsc)
}
}
+done:
mpii_event_done(sc, rcb);
}
void
+mpii_event_discovery(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
+{
+ struct mpii_evt_sas_discovery *esd =
+ (struct mpii_evt_sas_discovery *)(enp + 1);
+
+ if (esd->reason_code == MPII_EVENT_SAS_DISC_REASON_CODE_COMPLETED) {
+ if (esd->discovery_status != 0) {
+ printf("%s: sas discovery completed with status %#x\n",
+ DEVNAME(sc), esd->discovery_status);
+ }
+
+ if (ISSET(sc->sc_flags, MPII_F_CONFIG_PENDING)) {
+ CLR(sc->sc_flags, MPII_F_CONFIG_PENDING);
+ config_pending_decr();
+ }
+ }
+}
+
+void
mpii_event_process(struct mpii_softc *sc, struct mpii_rcb *rcb)
{
struct mpii_msg_event_reply *enp;
@@ -1863,17 +1903,7 @@ mpii_event_process(struct mpii_softc *sc, struct mpii_rcb *rcb)
case MPII_EVENT_EVENT_CHANGE:
/* should be properly ignored */
break;
- case MPII_EVENT_SAS_DISCOVERY: {
- struct mpii_evt_sas_discovery *esd =
- (struct mpii_evt_sas_discovery *)(enp + 1);
-
- if (esd->reason_code ==
- MPII_EVENT_SAS_DISC_REASON_CODE_COMPLETED &&
- esd->discovery_status != 0)
- printf("%s: sas discovery completed with status %#x\n",
- DEVNAME(sc), esd->discovery_status);
- }
- break;
+ case MPII_EVENT_SAS_DISCOVERY:
case MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
mtx_enter(&sc->sc_evt_sas_mtx);
SIMPLEQ_INSERT_TAIL(&sc->sc_evt_sas_queue, rcb, rcb_link);