Page MenuHomeFreeBSD

D8613.id22551.diff
No OneTemporary

D8613.id22551.diff

Index: head/sys/dev/hyperv/netvsc/hn_nvs.c
===================================================================
--- head/sys/dev/hyperv/netvsc/hn_nvs.c
+++ head/sys/dev/hyperv/netvsc/hn_nvs.c
@@ -62,8 +62,8 @@
static int hn_nvs_conn_chim(struct hn_softc *);
static int hn_nvs_conn_rxbuf(struct hn_softc *);
-static int hn_nvs_disconn_chim(struct hn_softc *);
-static int hn_nvs_disconn_rxbuf(struct hn_softc *);
+static void hn_nvs_disconn_chim(struct hn_softc *);
+static void hn_nvs_disconn_rxbuf(struct hn_softc *);
static int hn_nvs_conf_ndis(struct hn_softc *, int);
static int hn_nvs_init_ndis(struct hn_softc *);
static int hn_nvs_doinit(struct hn_softc *, uint32_t);
@@ -308,7 +308,7 @@
return (error);
}
-static int
+static void
hn_nvs_disconn_rxbuf(struct hn_softc *sc)
{
int error;
@@ -328,7 +328,12 @@
if (error) {
if_printf(sc->hn_ifp,
"send nvs rxbuf disconn failed: %d\n", error);
- return (error);
+ /*
+ * Fine for a revoked channel, since the hypervisor
+ * does not drain TX bufring for a revoked channel.
+ */
+ if (!vmbus_chan_is_revoked(sc->hn_prichan))
+ sc->hn_flags |= HN_FLAG_RXBUF_REF;
}
sc->hn_flags &= ~HN_FLAG_RXBUF_CONNECTED;
@@ -357,14 +362,13 @@
if (error) {
if_printf(sc->hn_ifp,
"rxbuf gpadl disconn failed: %d\n", error);
- return (error);
+ sc->hn_flags |= HN_FLAG_RXBUF_REF;
}
sc->hn_rxbuf_gpadl = 0;
}
- return (0);
}
-static int
+static void
hn_nvs_disconn_chim(struct hn_softc *sc)
{
int error;
@@ -384,7 +388,12 @@
if (error) {
if_printf(sc->hn_ifp,
"send nvs chim disconn failed: %d\n", error);
- return (error);
+ /*
+ * Fine for a revoked channel, since the hypervisor
+ * does not drain TX bufring for a revoked channel.
+ */
+ if (!vmbus_chan_is_revoked(sc->hn_prichan))
+ sc->hn_flags |= HN_FLAG_CHIM_REF;
}
sc->hn_flags &= ~HN_FLAG_CHIM_CONNECTED;
@@ -414,7 +423,7 @@
if (error) {
if_printf(sc->hn_ifp,
"chim gpadl disconn failed: %d\n", error);
- return (error);
+ sc->hn_flags |= HN_FLAG_CHIM_REF;
}
sc->hn_chim_gpadl = 0;
}
@@ -423,7 +432,6 @@
free(sc->hn_chim_bmap, M_DEVBUF);
sc->hn_chim_bmap = NULL;
}
- return (0);
}
static int
Index: head/sys/dev/hyperv/netvsc/if_hn.c
===================================================================
--- head/sys/dev/hyperv/netvsc/if_hn.c
+++ head/sys/dev/hyperv/netvsc/if_hn.c
@@ -296,6 +296,7 @@
static void hn_synth_detach(struct hn_softc *);
static int hn_synth_alloc_subchans(struct hn_softc *,
int *);
+static bool hn_synth_attachable(const struct hn_softc *);
static void hn_suspend(struct hn_softc *);
static void hn_suspend_data(struct hn_softc *);
static void hn_suspend_mgmt(struct hn_softc *);
@@ -3249,7 +3250,10 @@
int i;
if (sc->hn_rxbuf != NULL) {
- hyperv_dmamem_free(&sc->hn_rxbuf_dma, sc->hn_rxbuf);
+ if ((sc->hn_flags & HN_FLAG_RXBUF_REF) == 0)
+ hyperv_dmamem_free(&sc->hn_rxbuf_dma, sc->hn_rxbuf);
+ else
+ device_printf(sc->hn_dev, "RXBUF is referenced\n");
sc->hn_rxbuf = NULL;
}
@@ -3261,7 +3265,12 @@
if (rxr->hn_br == NULL)
continue;
- hyperv_dmamem_free(&rxr->hn_br_dma, rxr->hn_br);
+ if ((rxr->hn_rx_flags & HN_RX_FLAG_BR_REF) == 0) {
+ hyperv_dmamem_free(&rxr->hn_br_dma, rxr->hn_br);
+ } else {
+ device_printf(sc->hn_dev,
+ "%dth channel bufring is referenced", i);
+ }
rxr->hn_br = NULL;
#if defined(INET) || defined(INET6)
@@ -3730,7 +3739,12 @@
int i;
if (sc->hn_chim != NULL) {
- hyperv_dmamem_free(&sc->hn_chim_dma, sc->hn_chim);
+ if ((sc->hn_flags & HN_FLAG_CHIM_REF) == 0) {
+ hyperv_dmamem_free(&sc->hn_chim_dma, sc->hn_chim);
+ } else {
+ device_printf(sc->hn_dev,
+ "chimney sending buffer is referenced");
+ }
sc->hn_chim = NULL;
}
@@ -4214,7 +4228,7 @@
hn_chan_detach(struct hn_softc *sc, struct vmbus_channel *chan)
{
struct hn_rx_ring *rxr;
- int idx;
+ int idx, error;
idx = vmbus_chan_subidx(chan);
@@ -4243,7 +4257,16 @@
* NOTE:
* Channel closing does _not_ destroy the target channel.
*/
- vmbus_chan_close(chan);
+ error = vmbus_chan_close_direct(chan);
+ if (error == EISCONN) {
+ if_printf(sc->hn_ifp, "chan%u subidx%u "
+ "bufring is connected after being closed\n",
+ vmbus_chan_id(chan), vmbus_chan_subidx(chan));
+ rxr->hn_rx_flags |= HN_RX_FLAG_BR_REF;
+ } else if (error) {
+ if_printf(sc->hn_ifp, "chan%u subidx%u close failed: %d\n",
+ vmbus_chan_id(chan), vmbus_chan_subidx(chan), error);
+ }
}
static int
@@ -4373,6 +4396,23 @@
return (0);
}
+static bool
+hn_synth_attachable(const struct hn_softc *sc)
+{
+ int i;
+
+ if (sc->hn_flags & HN_FLAG_ERRORS)
+ return (false);
+
+ for (i = 0; i < sc->hn_rx_ring_cnt; ++i) {
+ const struct hn_rx_ring *rxr = &sc->hn_rx_ring[i];
+
+ if (rxr->hn_rx_flags & HN_RX_FLAG_BR_REF)
+ return (false);
+ }
+ return (true);
+}
+
static int
hn_synth_attach(struct hn_softc *sc, int mtu)
{
@@ -4383,6 +4423,9 @@
KASSERT((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0,
("synthetic parts were attached"));
+ if (!hn_synth_attachable(sc))
+ return (ENXIO);
+
/* Save capabilities for later verification. */
old_caps = sc->hn_caps;
sc->hn_caps = 0;
Index: head/sys/dev/hyperv/netvsc/if_hnvar.h
===================================================================
--- head/sys/dev/hyperv/netvsc/if_hnvar.h
+++ head/sys/dev/hyperv/netvsc/if_hnvar.h
@@ -91,7 +91,8 @@
#define HN_TRUST_HCSUM_TCP 0x0002
#define HN_TRUST_HCSUM_UDP 0x0004
-#define HN_RX_FLAG_ATTACHED 0x1
+#define HN_RX_FLAG_ATTACHED 0x0001
+#define HN_RX_FLAG_BR_REF 0x0002
struct hn_tx_ring {
#ifndef HN_USE_TXDESC_BUFRING
@@ -162,8 +163,8 @@
struct sysctl_oid *hn_tx_sysctl_tree;
} __aligned(CACHE_LINE_SIZE);
-#define HN_TX_FLAG_ATTACHED 0x1
-#define HN_TX_FLAG_HASHVAL 0x2 /* support HASHVAL pktinfo */
+#define HN_TX_FLAG_ATTACHED 0x0001
+#define HN_TX_FLAG_HASHVAL 0x0002 /* support HASHVAL pktinfo */
/*
* Device-specific softc structure
@@ -237,6 +238,10 @@
#define HN_FLAG_HAS_RSSIND 0x0008
#define HN_FLAG_SYNTH_ATTACHED 0x0010
#define HN_FLAG_NO_SLEEPING 0x0020
+#define HN_FLAG_RXBUF_REF 0x0040
+#define HN_FLAG_CHIM_REF 0x0080
+
+#define HN_FLAG_ERRORS (HN_FLAG_RXBUF_REF | HN_FLAG_CHIM_REF)
#define HN_NO_SLEEPING(sc) \
do { \

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 15, 8:02 AM (2 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
9091576
Default Alt Text
D8613.id22551.diff (6 KB)

Event Timeline