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