Date: Mon, 31 Oct 2016 04:46:02 +0000 (UTC) From: Sepherosa Ziehau <sephe@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r308117 - head/sys/dev/hyperv/netvsc Message-ID: <201610310446.u9V4k29f004210@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sephe Date: Mon Oct 31 04:46:02 2016 New Revision: 308117 URL: https://svnweb.freebsd.org/changeset/base/308117 Log: hyperv/hn: Rework temporary channel packet buffer expanding. And use large default temporary channel packer buffer; we really don't want it to be expanded at run time. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8367 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 01:36:28 2016 (r308116) +++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Mon Oct 31 04:46:02 2016 (r308117) @@ -176,6 +176,8 @@ __FBSDID("$FreeBSD$"); HN_RXINFO_HASHINF | \ HN_RXINFO_HASHVAL) +#define HN_PKTBUF_LEN_DEF (16 * 1024) + struct hn_txdesc { #ifndef HN_USE_TXDESC_BUFRING SLIST_ENTRY(hn_txdesc) link; @@ -2720,7 +2722,8 @@ hn_create_rx_data(struct hn_softc *sc, i rxr->hn_ifp = sc->hn_ifp; if (i < sc->hn_tx_ring_cnt) rxr->hn_txr = &sc->hn_tx_ring[i]; - rxr->hn_pktbuf = malloc(HN_PKTBUF_LEN, M_DEVBUF, M_WAITOK); + rxr->hn_pktbuf_len = HN_PKTBUF_LEN_DEF; + rxr->hn_pktbuf = malloc(rxr->hn_pktbuf_len, M_DEVBUF, M_WAITOK); rxr->hn_rx_idx = i; rxr->hn_rxbuf = sc->hn_rxbuf; @@ -2763,6 +2766,11 @@ hn_create_rx_data(struct hn_softc *sc, i OID_AUTO, "rss_pkts", CTLFLAG_RW, &rxr->hn_rss_pkts, "# of packets w/ RSS info received"); + SYSCTL_ADD_INT(ctx, + SYSCTL_CHILDREN(rxr->hn_rx_sysctl_tree), + OID_AUTO, "pktbuf_len", CTLFLAG_RD, + &rxr->hn_pktbuf_len, 0, + "Temporary channel packet buffer length"); } } } @@ -4536,60 +4544,62 @@ hn_chan_callback(struct vmbus_channel *c { struct hn_rx_ring *rxr = xrxr; struct hn_softc *sc = rxr->hn_ifp->if_softc; - void *buffer; - int bufferlen = HN_PKTBUF_LEN; - buffer = rxr->hn_pktbuf; - do { - struct vmbus_chanpkt_hdr *pkt = buffer; - uint32_t bytes_rxed; - int ret; - - bytes_rxed = bufferlen; - ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed); - if (ret == 0) { - switch (pkt->cph_type) { - case VMBUS_CHANPKT_TYPE_COMP: - hn_nvs_handle_comp(sc, chan, pkt); - break; - case VMBUS_CHANPKT_TYPE_RXBUF: - hn_nvs_handle_rxbuf(rxr, chan, pkt); - break; - case VMBUS_CHANPKT_TYPE_INBAND: - hn_nvs_handle_notify(sc, pkt); - break; - default: - if_printf(rxr->hn_ifp, - "unknown chan pkt %u\n", - pkt->cph_type); - break; - } - } else if (ret == ENOBUFS) { - /* Handle large packet */ - if (bufferlen > HN_PKTBUF_LEN) { - free(buffer, M_DEVBUF); - buffer = NULL; - } + for (;;) { + struct vmbus_chanpkt_hdr *pkt = rxr->hn_pktbuf; + int error, pktlen; + + pktlen = rxr->hn_pktbuf_len; + error = vmbus_chan_recv_pkt(chan, pkt, &pktlen); + if (__predict_false(error == ENOBUFS)) { + void *nbuf; + int nlen; - /* alloc new buffer */ - buffer = malloc(bytes_rxed, M_DEVBUF, M_NOWAIT); - if (buffer == NULL) { - if_printf(rxr->hn_ifp, - "hv_cb malloc buffer failed, len=%u\n", - bytes_rxed); - bufferlen = 0; - break; - } - bufferlen = bytes_rxed; - } else { - /* No more packets */ + /* + * Expand channel packet buffer. + * + * XXX + * Use M_WAITOK here, since allocation failure + * is fatal. + */ + nlen = rxr->hn_pktbuf_len * 2; + while (nlen < pktlen) + nlen *= 2; + nbuf = malloc(nlen, M_DEVBUF, M_WAITOK); + + if_printf(rxr->hn_ifp, "expand pktbuf %d -> %d\n", + rxr->hn_pktbuf_len, nlen); + + free(rxr->hn_pktbuf, M_DEVBUF); + rxr->hn_pktbuf = nbuf; + rxr->hn_pktbuf_len = nlen; + /* Retry! */ + continue; + } else if (__predict_false(error == EAGAIN)) { + /* No more channel packets; done! */ break; } - } while (1); + KASSERT(!error, ("vmbus_chan_recv_pkt failed: %d", error)); + + switch (pkt->cph_type) { + case VMBUS_CHANPKT_TYPE_COMP: + hn_nvs_handle_comp(sc, chan, pkt); + break; - if (bufferlen > HN_PKTBUF_LEN) - free(buffer, M_DEVBUF); + case VMBUS_CHANPKT_TYPE_RXBUF: + hn_nvs_handle_rxbuf(rxr, chan, pkt); + break; + case VMBUS_CHANPKT_TYPE_INBAND: + hn_nvs_handle_notify(sc, pkt); + break; + + default: + if_printf(rxr->hn_ifp, "unknown chan pkt %u\n", + pkt->cph_type); + break; + } + } hn_chan_rollup(rxr, rxr->hn_txr); } Modified: head/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- head/sys/dev/hyperv/netvsc/if_hnvar.h Mon Oct 31 01:36:28 2016 (r308116) +++ head/sys/dev/hyperv/netvsc/if_hnvar.h Mon Oct 31 04:46:02 2016 (r308117) @@ -39,8 +39,6 @@ /* Claimed to be 12232B */ #define HN_MTU_MAX (9 * 1024) -#define HN_PKTBUF_LEN 4096 - #define HN_TXBR_SIZE (128 * PAGE_SIZE) #define HN_RXBR_SIZE (128 * PAGE_SIZE) @@ -63,6 +61,7 @@ struct hn_rx_ring { struct ifnet *hn_ifp; struct hn_tx_ring *hn_txr; void *hn_pktbuf; + int hn_pktbuf_len; uint8_t *hn_rxbuf; /* shadow sc->hn_rxbuf */ int hn_rx_idx;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610310446.u9V4k29f004210>