Page MenuHomeFreeBSD

D8368.id21818.diff
No OneTemporary

D8368.id21818.diff

Index: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -414,7 +414,8 @@
static void hn_nvs_handle_rxbuf(struct hn_rx_ring *rxr,
struct vmbus_channel *chan,
const struct vmbus_chanpkt_hdr *pkthdr);
-static void hn_nvs_ack_rxbuf(struct vmbus_channel *chan, uint64_t tid);
+static void hn_nvs_ack_rxbuf(struct hn_rx_ring *, struct vmbus_channel *,
+ uint64_t);
static int hn_transmit(struct ifnet *, struct mbuf *);
static void hn_xmit_qflush(struct ifnet *);
@@ -2843,6 +2844,10 @@
CTLTYPE_ULONG | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
__offsetof(struct hn_rx_ring, hn_small_pkts),
hn_rx_stat_ulong_sysctl, "LU", "# of small packets received");
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_ack_failed",
+ CTLTYPE_ULONG | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
+ __offsetof(struct hn_rx_ring, hn_ack_failed),
+ hn_rx_stat_ulong_sysctl, "LU", "# of RXBUF ack failures");
SYSCTL_ADD_INT(ctx, child, OID_AUTO, "rx_ring_cnt",
CTLFLAG_RD, &sc->hn_rx_ring_cnt, 0, "# created RX rings");
SYSCTL_ADD_INT(ctx, child, OID_AUTO, "rx_ring_inuse",
@@ -4499,43 +4504,43 @@
}
/*
- * Moved completion call back here so that all received
- * messages (not just data messages) will trigger a response
- * message back to the host.
+ * Ack the consumed RXBUF associated w/ this channel packet,
+ * so that this RXBUF can be recycled by the hypervisor.
*/
- hn_nvs_ack_rxbuf(chan, pkt->cp_hdr.cph_xactid);
+ hn_nvs_ack_rxbuf(rxr, chan, pkt->cp_hdr.cph_xactid);
}
-/*
- * Net VSC on receive completion
- *
- * Send a receive completion packet to RNDIS device (ie NetVsp)
- */
static void
-hn_nvs_ack_rxbuf(struct vmbus_channel *chan, uint64_t tid)
+hn_nvs_ack_rxbuf(struct hn_rx_ring *rxr, struct vmbus_channel *chan,
+ uint64_t tid)
{
struct hn_nvs_rndis_ack ack;
- int retries = 0;
- int ret = 0;
+ int retries, error;
ack.nvs_type = HN_NVS_TYPE_RNDIS_ACK;
ack.nvs_status = HN_NVS_STATUS_OK;
-retry_send_cmplt:
- /* Send the completion */
- ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP,
+ retries = 0;
+again:
+ error = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP,
VMBUS_CHANPKT_FLAG_NONE, &ack, sizeof(ack), tid);
- if (ret == 0) {
- /* success */
- /* no-op */
- } else if (ret == EAGAIN) {
- /* no more room... wait a bit and attempt to retry 3 times */
+ if (__predict_false(error == EAGAIN)) {
+ /*
+ * NOTE:
+ * This should _not_ happen in real world, since the
+ * consumption of the TX bufring from the TX path is
+ * controlled.
+ */
+ if (rxr->hn_ack_failed == 0)
+ if_printf(rxr->hn_ifp, "RXBUF ack retry\n");
+ rxr->hn_ack_failed++;
retries++;
-
- if (retries < 4) {
+ if (retries < 10) {
DELAY(100);
- goto retry_send_cmplt;
+ goto again;
}
+ /* RXBUF leaks! */
+ if_printf(rxr->hn_ifp, "RXBUF ack failed\n");
}
}
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
@@ -77,6 +77,7 @@
u_long hn_small_pkts;
u_long hn_pkts;
u_long hn_rss_pkts;
+ u_long hn_ack_failed;
/* Rarely used stuffs */
struct sysctl_oid *hn_rx_sysctl_tree;

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 6, 11:54 AM (21 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14485500
Default Alt Text
D8368.id21818.diff (3 KB)

Event Timeline