From 049efd109023427e1aee64089e8620d7a46bbcad Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 25 Apr 2016 10:16:07 +0000 Subject: [PATCH] hyperv/hn: Synchronize sub-channel offers MFC after: 1 week Sponsored by: Microsoft OSTC --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 47d52460407..757ea409725 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -421,7 +421,7 @@ static int netvsc_attach(device_t dev) { struct hv_device *device_ctx = vmbus_get_devctx(dev); - struct hv_vmbus_channel *chan; + struct hv_vmbus_channel *pri_chan; netvsc_device_info device_info; hn_softc_t *sc; int unit = device_get_unit(dev); @@ -502,12 +502,12 @@ netvsc_attach(device_t dev) /* * Associate the first TX/RX ring w/ the primary channel. */ - chan = device_ctx->channel; - KASSERT(HV_VMBUS_CHAN_ISPRIMARY(chan), ("not primary channel")); - KASSERT(chan->offer_msg.offer.sub_channel_index == 0, + pri_chan = device_ctx->channel; + KASSERT(HV_VMBUS_CHAN_ISPRIMARY(pri_chan), ("not primary channel")); + KASSERT(pri_chan->offer_msg.offer.sub_channel_index == 0, ("primary channel subidx %u", - chan->offer_msg.offer.sub_channel_index)); - hn_channel_attach(sc, chan); + pri_chan->offer_msg.offer.sub_channel_index)); + hn_channel_attach(sc, pri_chan); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = hn_ioctl; @@ -547,6 +547,19 @@ netvsc_attach(device_t dev) error = hv_rf_on_device_add(device_ctx, &device_info, ring_cnt); if (error) goto failed; + + if (sc->net_dev->num_channel > 1) { + struct hv_vmbus_channel **subchan; + int subchan_cnt = sc->net_dev->num_channel - 1; + + /* + * Wait for sub-channels setup to complete. + */ + subchan = vmbus_get_subchan(pri_chan, subchan_cnt); + vmbus_rel_subchan(subchan, subchan_cnt); + device_printf(dev, "%d sub-channels setup done\n", subchan_cnt); + } + KASSERT(sc->net_dev->num_channel > 0 && sc->net_dev->num_channel <= sc->hn_rx_ring_inuse, ("invalid channel count %u, should be less than %d",