svn commit: r309229 - head/sys/dev/hyperv/netvsc
Sepherosa Ziehau
sephe at FreeBSD.org
Mon Nov 28 05:46:01 UTC 2016
Author: sephe
Date: Mon Nov 28 05:46:00 2016
New Revision: 309229
URL: https://svnweb.freebsd.org/changeset/base/309229
Log:
hyperv/hn: Fix attach error handling
MFC after: 1 week
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D8620
Modified:
head/sys/dev/hyperv/netvsc/hn_nvs.c
head/sys/dev/hyperv/netvsc/hn_rndis.c
head/sys/dev/hyperv/netvsc/if_hn.c
Modified: head/sys/dev/hyperv/netvsc/hn_nvs.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hn_nvs.c Mon Nov 28 05:31:36 2016 (r309228)
+++ head/sys/dev/hyperv/netvsc/hn_nvs.c Mon Nov 28 05:46:00 2016 (r309229)
@@ -273,8 +273,14 @@ hn_nvs_conn_chim(struct hn_softc *sc)
goto cleanup;
}
if (sectsz == 0) {
+ /*
+ * Can't use chimney sending buffer; done!
+ */
if_printf(sc->hn_ifp, "zero chimney sending buffer "
"section size\n");
+ sc->hn_chim_szmax = 0;
+ sc->hn_chim_cnt = 0;
+ sc->hn_flags |= HN_FLAG_CHIM_CONNECTED;
return (0);
}
@@ -431,6 +437,7 @@ hn_nvs_disconn_chim(struct hn_softc *sc)
if (sc->hn_chim_bmap != NULL) {
free(sc->hn_chim_bmap, M_DEVBUF);
sc->hn_chim_bmap = NULL;
+ sc->hn_chim_bmap_cnt = 0;
}
}
@@ -620,8 +627,10 @@ hn_nvs_attach(struct hn_softc *sc, int m
* Connect chimney sending buffer.
*/
error = hn_nvs_conn_chim(sc);
- if (error)
+ if (error) {
+ hn_nvs_disconn_rxbuf(sc);
return (error);
+ }
return (0);
}
Modified: head/sys/dev/hyperv/netvsc/hn_rndis.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hn_rndis.c Mon Nov 28 05:31:36 2016 (r309228)
+++ head/sys/dev/hyperv/netvsc/hn_rndis.c Mon Nov 28 05:46:00 2016 (r309229)
@@ -979,7 +979,6 @@ hn_rndis_attach(struct hn_softc *sc, int
/*
* Configure NDIS offload settings.
- * XXX no offloading, if error happened?
*/
hn_rndis_conf_offload(sc, mtu);
return (0);
Modified: head/sys/dev/hyperv/netvsc/if_hn.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hn.c Mon Nov 28 05:31:36 2016 (r309228)
+++ head/sys/dev/hyperv/netvsc/if_hn.c Mon Nov 28 05:46:00 2016 (r309229)
@@ -4215,11 +4215,14 @@ hn_chan_attach(struct hn_softc *sc, stru
cbr.cbr_rxsz = HN_RXBR_SIZE;
error = vmbus_chan_open_br(chan, &cbr, NULL, 0, hn_chan_callback, rxr);
if (error) {
- if_printf(sc->hn_ifp, "open chan%u failed: %d\n",
- vmbus_chan_id(chan), error);
- rxr->hn_rx_flags &= ~HN_RX_FLAG_ATTACHED;
- if (txr != NULL)
- txr->hn_tx_flags &= ~HN_TX_FLAG_ATTACHED;
+ if (error == EISCONN) {
+ if_printf(sc->hn_ifp, "bufring is connected after "
+ "chan%u open failure\n", vmbus_chan_id(chan));
+ rxr->hn_rx_flags |= HN_RX_FLAG_BR_REF;
+ } else {
+ if_printf(sc->hn_ifp, "open chan%u failed: %d\n",
+ vmbus_chan_id(chan), error);
+ }
}
return (error);
}
@@ -4276,15 +4279,18 @@ hn_attach_subchans(struct hn_softc *sc)
int subchan_cnt = sc->hn_rx_ring_inuse - 1;
int i, error = 0;
- if (subchan_cnt == 0)
- return (0);
+ KASSERT(subchan_cnt > 0, ("no sub-channels"));
/* Attach the sub-channels. */
subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt);
for (i = 0; i < subchan_cnt; ++i) {
- error = hn_chan_attach(sc, subchans[i]);
- if (error)
- break;
+ int error1;
+
+ error1 = hn_chan_attach(sc, subchans[i]);
+ if (error1) {
+ error = error1;
+ /* Move on; all channels will be detached later. */
+ }
}
vmbus_subchan_rel(subchans, subchan_cnt);
@@ -4416,9 +4422,12 @@ hn_synth_attachable(const struct hn_soft
static int
hn_synth_attach(struct hn_softc *sc, int mtu)
{
+#define ATTACHED_NVS 0x0002
+#define ATTACHED_RNDIS 0x0004
+
struct ndis_rssprm_toeplitz *rss = &sc->hn_rss;
int error, nsubch, nchan, i;
- uint32_t old_caps;
+ uint32_t old_caps, attached = 0;
KASSERT((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0,
("synthetic parts were attached"));
@@ -4439,21 +4448,23 @@ hn_synth_attach(struct hn_softc *sc, int
*/
error = hn_chan_attach(sc, sc->hn_prichan);
if (error)
- return (error);
+ goto failed;
/*
* Attach NVS.
*/
error = hn_nvs_attach(sc, mtu);
if (error)
- return (error);
+ goto failed;
+ attached |= ATTACHED_NVS;
/*
* Attach RNDIS _after_ NVS is attached.
*/
error = hn_rndis_attach(sc, mtu);
if (error)
- return (error);
+ goto failed;
+ attached |= ATTACHED_RNDIS;
/*
* Make sure capabilities are not changed.
@@ -4461,9 +4472,8 @@ hn_synth_attach(struct hn_softc *sc, int
if (device_is_attached(sc->hn_dev) && old_caps != sc->hn_caps) {
if_printf(sc->hn_ifp, "caps mismatch old 0x%08x, new 0x%08x\n",
old_caps, sc->hn_caps);
- /* Restore old capabilities and abort. */
- sc->hn_caps = old_caps;
- return ENXIO;
+ error = ENXIO;
+ goto failed;
}
/*
@@ -4476,19 +4486,32 @@ hn_synth_attach(struct hn_softc *sc, int
nsubch = sc->hn_rx_ring_cnt - 1;
error = hn_synth_alloc_subchans(sc, &nsubch);
if (error)
- return (error);
+ goto failed;
+ /* NOTE: _Full_ synthetic parts detach is required now. */
+ sc->hn_flags |= HN_FLAG_SYNTH_ATTACHED;
+ /*
+ * Set the # of TX/RX rings that could be used according to
+ * the # of channels that NVS offered.
+ */
nchan = nsubch + 1;
+ hn_set_ring_inuse(sc, nchan);
if (nchan == 1) {
/* Only the primary channel can be used; done */
goto back;
}
/*
- * Configure RSS key and indirect table _after_ all sub-channels
- * are allocated.
+ * Attach the sub-channels.
*/
+ error = hn_attach_subchans(sc);
+ if (error)
+ goto failed;
+ /*
+ * Configure RSS key and indirect table _after_ all sub-channels
+ * are attached.
+ */
if ((sc->hn_flags & HN_FLAG_HAS_RSSKEY) == 0) {
/*
* RSS key is not set yet; set it to the default RSS key.
@@ -4521,34 +4544,31 @@ hn_synth_attach(struct hn_softc *sc, int
}
error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_NONE);
- if (error) {
- /*
- * Failed to configure RSS key or indirect table; only
- * the primary channel can be used.
- */
- nchan = 1;
- }
-back:
- /*
- * Set the # of TX/RX rings that could be used according to
- * the # of channels that NVS offered.
- */
- hn_set_ring_inuse(sc, nchan);
-
- /*
- * Attach the sub-channels, if any.
- */
- error = hn_attach_subchans(sc);
if (error)
- return (error);
-
+ goto failed;
+back:
/*
* Fixup transmission aggregation setup.
*/
hn_set_txagg(sc);
-
- sc->hn_flags |= HN_FLAG_SYNTH_ATTACHED;
return (0);
+
+failed:
+ if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) {
+ hn_synth_detach(sc);
+ } else {
+ if (attached & ATTACHED_RNDIS)
+ hn_rndis_detach(sc);
+ if (attached & ATTACHED_NVS)
+ hn_nvs_detach(sc);
+ hn_chan_detach(sc, sc->hn_prichan);
+ /* Restore old capabilities. */
+ sc->hn_caps = old_caps;
+ }
+ return (error);
+
+#undef ATTACHED_RNDIS
+#undef ATTACHED_NVS
}
/*
@@ -4559,7 +4579,6 @@ back:
static void
hn_synth_detach(struct hn_softc *sc)
{
- HN_LOCK_ASSERT(sc);
KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED,
("synthetic parts were not attached"));
More information about the svn-src-all
mailing list