svn commit: r306073 - head/sys/dev/hyperv/netvsc

Sepherosa Ziehau sephe at FreeBSD.org
Wed Sep 21 06:27:43 UTC 2016


Author: sephe
Date: Wed Sep 21 06:27:42 2016
New Revision: 306073
URL: https://svnweb.freebsd.org/changeset/base/306073

Log:
  hyperv/hn: Allocate bufrings in attach DEVMETHOD.
  
  So that reinitialization, e.g. MTU change, will not fail when the system
  memory is excessively fragmented.
  
  MFC after:	1 week
  Sponsored by:	Microsoft
  Differential Revision:	https://reviews.freebsd.org/D7961

Modified:
  head/sys/dev/hyperv/netvsc/hv_net_vsc.h
  head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c

Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.h	Wed Sep 21 05:56:47 2016	(r306072)
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.h	Wed Sep 21 06:27:42 2016	(r306073)
@@ -136,6 +136,9 @@ struct hn_rx_ring {
 	/* Rarely used stuffs */
 	struct sysctl_oid *hn_rx_sysctl_tree;
 	int		hn_rx_flags;
+
+	void		*hn_br;		/* TX/RX bufring */
+	struct hyperv_dma hn_br_dma;
 } __aligned(CACHE_LINE_SIZE);
 
 #define HN_TRUST_HCSUM_IP	0x0001

Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Wed Sep 21 05:56:47 2016	(r306072)
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Wed Sep 21 06:27:42 2016	(r306073)
@@ -2372,6 +2372,16 @@ hn_create_rx_data(struct hn_softc *sc, i
 	for (i = 0; i < sc->hn_rx_ring_cnt; ++i) {
 		struct hn_rx_ring *rxr = &sc->hn_rx_ring[i];
 
+		rxr->hn_br = hyperv_dmamem_alloc(bus_get_dma_tag(dev),
+		    PAGE_SIZE, 0,
+		    NETVSC_DEVICE_RING_BUFFER_SIZE +
+		    NETVSC_DEVICE_RING_BUFFER_SIZE,
+		    &rxr->hn_br_dma, BUS_DMA_WAITOK);
+		if (rxr->hn_br == NULL) {
+			device_printf(dev, "allocate bufring failed\n");
+			return (ENOMEM);
+		}
+
 		if (hn_trust_hosttcp)
 			rxr->hn_trust_hcsum |= HN_TRUST_HCSUM_TCP;
 		if (hn_trust_hostudp)
@@ -2520,6 +2530,11 @@ hn_destroy_rx_data(struct hn_softc *sc)
 	for (i = 0; i < sc->hn_rx_ring_cnt; ++i) {
 		struct hn_rx_ring *rxr = &sc->hn_rx_ring[i];
 
+		if (rxr->hn_br == NULL)
+			continue;
+		hyperv_dmamem_free(&rxr->hn_br_dma, rxr->hn_br);
+		rxr->hn_br = NULL;
+
 #if defined(INET) || defined(INET6)
 		tcp_lro_free(&rxr->hn_lro);
 #endif
@@ -3125,6 +3140,7 @@ hn_xmit_txeof_taskfunc(void *xtxr, int p
 static int
 hn_chan_attach(struct hn_softc *sc, struct vmbus_channel *chan)
 {
+	struct vmbus_chan_br cbr;
 	struct hn_rx_ring *rxr;
 	struct hn_tx_ring *txr = NULL;
 	int idx, error;
@@ -3163,9 +3179,14 @@ hn_chan_attach(struct hn_softc *sc, stru
 	/* Bind this channel to a proper CPU. */
 	vmbus_chan_cpu_set(chan, (sc->hn_cpu + idx) % mp_ncpus);
 
-	/* Open this channel */
-	error = vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE,
-	    NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0, hn_chan_callback, rxr);
+	/*
+	 * Open this channel
+	 */
+	cbr.cbr = rxr->hn_br;
+	cbr.cbr_paddr = rxr->hn_br_dma.hv_paddr;
+	cbr.cbr_txsz = NETVSC_DEVICE_RING_BUFFER_SIZE;
+	cbr.cbr_rxsz = NETVSC_DEVICE_RING_BUFFER_SIZE;
+	error = vmbus_chan_open_br(chan, &cbr, NULL, 0, hn_chan_callback, rxr);
 	if (error) {
 		if_printf(sc->hn_ifp, "open chan%u failed: %d\n",
 		    vmbus_chan_id(chan), error);


More information about the svn-src-head mailing list