Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F81969662
D8613.id22551.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D8613.id22551.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D8613: hyperv/hn: Fix detach error handling.
Attached
Detach File
Event Timeline
Log In to Comment