svn commit: r308118 - head/sys/dev/hyperv/netvsc
Sepherosa Ziehau
sephe at FreeBSD.org
Mon Oct 31 04:54:16 UTC 2016
Author: sephe
Date: Mon Oct 31 04:54:15 2016
New Revision: 308118
URL: https://svnweb.freebsd.org/changeset/base/308118
Log:
hyperv/hn: Cleanup RXBUF ack processing.
- Increase the # of retries.
- Add comment.
- Log error, if RXBUF ack fails.
- Add stat for RXBUF ack failures.
RXBUF ack really should _not_ fail...
MFC after: 1 week
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D8368
Modified:
head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
head/sys/dev/hyperv/netvsc/if_hnvar.h
Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Mon Oct 31 04:46:02 2016 (r308117)
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Mon Oct 31 04:54:15 2016 (r308118)
@@ -414,7 +414,8 @@ static void hn_nvs_handle_comp(struct hn
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 @@ hn_create_rx_data(struct hn_softc *sc, i
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 @@ hn_nvs_handle_rxbuf(struct hn_rx_ring *r
}
/*
- * 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");
}
}
Modified: head/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hnvar.h Mon Oct 31 04:46:02 2016 (r308117)
+++ head/sys/dev/hyperv/netvsc/if_hnvar.h Mon Oct 31 04:54:15 2016 (r308118)
@@ -77,6 +77,7 @@ struct hn_rx_ring {
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;
More information about the svn-src-all
mailing list