hyperv/hn: Associate TX/RX ring with channel

This fixes the TX/RX ring selection for TX/RX done.

MFC after:	1 week
Sponsored by:	Microsoft OSTC
Differential Revision:	https://reviews.freebsd.org/D5454
This commit is contained in:
Sepherosa Ziehau 2016-02-26 09:41:00 +00:00
parent 6619838c04
commit 3f919777b6
3 changed files with 27 additions and 19 deletions

View File

@ -822,10 +822,12 @@ typedef struct hv_vmbus_channel {
* This will be NULL for the primary channel.
*/
struct hv_vmbus_channel *primary_channel;
/*
* Support per channel state for use by vmbus drivers.
* Driver private data
*/
void *per_channel_state;
void *hv_chan_priv1;
void *hv_chan_priv2;
} hv_vmbus_channel;
#define HV_VMBUS_CHAN_ISPRIMARY(chan) ((chan)->primary_channel == NULL)

View File

@ -1000,6 +1000,7 @@ struct buf_ring;
#endif
struct hn_rx_ring {
struct ifnet *hn_ifp;
struct lro_ctrl hn_lro;
/* Trust csum verification on host side */

View File

@ -117,6 +117,8 @@ __FBSDID("$FreeBSD$");
#include "hv_rndis.h"
#include "hv_rndis_filter.h"
#define hv_chan_rxr hv_chan_priv1
#define hv_chan_txr hv_chan_priv2
/* Short for Hyper-V network interface */
#define NETVSC_DEVNAME "hn"
@ -376,6 +378,7 @@ static int
netvsc_attach(device_t dev)
{
struct hv_device *device_ctx = vmbus_get_devctx(dev);
struct hv_vmbus_channel *chan;
netvsc_device_info device_info;
hn_softc_t *sc;
int unit = device_get_unit(dev);
@ -427,6 +430,13 @@ netvsc_attach(device_t dev)
hn_create_rx_data(sc);
/*
* Associate the first TX/RX ring w/ the primary channel.
*/
chan = device_ctx->channel;
chan->hv_chan_rxr = &sc->hn_rx_ring[0];
chan->hv_chan_txr = &sc->hn_tx_ring[0];
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_dunit = unit;
ifp->if_dname = NETVSC_DEVNAME;
@ -686,11 +696,9 @@ hn_tx_done(void *xpkt)
void
netvsc_channel_rollup(struct hv_vmbus_channel *chan)
{
struct hv_device *device_ctx = chan->device;
struct hn_softc *sc = device_get_softc(device_ctx->device);
struct hn_tx_ring *txr = &sc->hn_tx_ring[0]; /* TODO: vRSS */
struct hn_tx_ring *txr = chan->hv_chan_txr;
#if defined(INET) || defined(INET6)
struct hn_rx_ring *rxr = &sc->hn_rx_ring[0]; /* TODO: vRSS */
struct hn_rx_ring *rxr = chan->hv_chan_rxr;
struct lro_ctrl *lro = &rxr->hn_lro;
struct lro_entry *queued;
@ -700,7 +708,12 @@ netvsc_channel_rollup(struct hv_vmbus_channel *chan)
}
#endif
if (!txr->hn_has_txeof)
/*
* NOTE:
* 'txr' could be NULL, if multiple channels and
* ifnet.if_start method are enabled.
*/
if (txr == NULL || !txr->hn_has_txeof)
return;
txr->hn_has_txeof = 0;
@ -1139,22 +1152,13 @@ int
netvsc_recv(struct hv_vmbus_channel *chan, netvsc_packet *packet,
rndis_tcp_ip_csum_info *csum_info)
{
struct hv_device *device_ctx = chan->device;
struct hn_softc *sc = device_get_softc(device_ctx->device);
struct hn_rx_ring *rxr = &sc->hn_rx_ring[0]; /* TODO: vRSS */
struct hn_rx_ring *rxr = chan->hv_chan_rxr;
struct ifnet *ifp = rxr->hn_ifp;
struct mbuf *m_new;
struct ifnet *ifp;
int size, do_lro = 0, do_csum = 1;
if (sc == NULL) {
return (0); /* TODO: KYS how can this be! */
}
ifp = sc->hn_ifp;
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
return (0);
}
/*
* Bail out if packet contains more data than configured MTU.
@ -2023,6 +2027,7 @@ hn_create_rx_data(struct hn_softc *sc)
rxr->hn_trust_hcsum |= HN_TRUST_HCSUM_UDP;
if (hn_trust_hostip)
rxr->hn_trust_hcsum |= HN_TRUST_HCSUM_IP;
rxr->hn_ifp = sc->hn_ifp;
/*
* Initialize LRO.