summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-04-26 05:08:55 +0000
committersephe <sephe@FreeBSD.org>2016-04-26 05:08:55 +0000
commit936be7c264e1adf7cbdf8c16de9329d51e72332a (patch)
tree42987f4ac54c35ae4609d7d90bbd691af717069f /sys/dev
parent35bcf1a1373adbb433f9eb46de9b81de3db7627b (diff)
downloadFreeBSD-src-936be7c264e1adf7cbdf8c16de9329d51e72332a.zip
FreeBSD-src-936be7c264e1adf7cbdf8c16de9329d51e72332a.tar.gz
hyperv/hn: Avoid sub-channel creation callback.
Since the sub-channel offers are synchronized, we can do our own channel setup without using the sub-channel creation callback. This paves the way to whack the sub-channel creation callback. MFC after: 1 week Sponsored by: Microsoft OSTC
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.c25
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.h1
-rw-r--r--sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c38
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis.h2
4 files changed, 27 insertions, 39 deletions
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c
index c193a7b..2e3e5cf 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -661,30 +661,12 @@ hv_nv_disconnect_from_vsp(netvsc_dev *net_dev)
hv_nv_destroy_send_buffer(net_dev);
}
-/*
- * Callback handler for subchannel offer
- * @@param context new subchannel
- */
-static void
-hv_nv_subchan_callback(void *xchan)
+void
+hv_nv_subchan_attach(struct hv_vmbus_channel *chan)
{
- struct hv_vmbus_channel *chan = xchan;
- netvsc_dev *net_dev;
- uint16_t chn_index = chan->offer_msg.offer.sub_channel_index;
- struct hv_device *device = chan->device;
- hn_softc_t *sc = device_get_softc(device->device);
- int ret;
-
- net_dev = sc->net_dev;
-
- if (chn_index >= net_dev->num_channel) {
- /* Would this ever happen? */
- return;
- }
- netvsc_subchan_callback(sc, chan);
chan->hv_chan_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK);
- ret = hv_vmbus_channel_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE,
+ hv_vmbus_channel_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE,
NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0,
hv_nv_on_channel_callback, chan);
}
@@ -721,7 +703,6 @@ hv_nv_on_device_add(struct hv_device *device, void *additional_info)
free(chan->hv_chan_rdbuf, M_NETVSC);
goto cleanup;
}
- chan->sc_creation_callback = hv_nv_subchan_callback;
/*
* Connect with the NetVsp
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h
index e1a034c..3dbd6ef 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.h
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h
@@ -1266,6 +1266,7 @@ int hv_nv_on_device_remove(struct hv_device *device,
boolean_t destroy_channel);
int hv_nv_on_send(struct hv_vmbus_channel *chan, netvsc_packet *pkt);
int hv_nv_get_next_send_section(netvsc_dev *net_dev);
+void hv_nv_subchan_attach(struct hv_vmbus_channel *chan);
#endif /* __HV_NET_VSC_H__ */
diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
index 757ea40..909177a 100644
--- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -332,6 +332,7 @@ static void hn_create_rx_data(struct hn_softc *sc, int);
static void hn_destroy_rx_data(struct hn_softc *sc);
static void hn_set_tx_chimney_size(struct hn_softc *, int);
static void hn_channel_attach(struct hn_softc *, struct hv_vmbus_channel *);
+static void hn_subchan_attach(struct hn_softc *, struct hv_vmbus_channel *);
static int hn_transmit(struct ifnet *, struct mbuf *);
static void hn_xmit_qflush(struct ifnet *);
@@ -547,19 +548,6 @@ 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",
@@ -575,6 +563,26 @@ netvsc_attach(device_t dev)
device_printf(dev, "%d TX ring, %d RX ring\n",
sc->hn_tx_ring_inuse, sc->hn_rx_ring_inuse);
+ if (sc->net_dev->num_channel > 1) {
+ struct hv_vmbus_channel **subchan;
+ int subchan_cnt = sc->net_dev->num_channel - 1;
+ int i;
+
+ /* Wait for sub-channels setup to complete. */
+ subchan = vmbus_get_subchan(pri_chan, subchan_cnt);
+
+ /* Attach the sub-channels. */
+ for (i = 0; i < subchan_cnt; ++i) {
+ /* NOTE: Calling order is critical. */
+ hn_subchan_attach(sc, subchan[i]);
+ hv_nv_subchan_attach(subchan[i]);
+ }
+
+ /* Release the sub-channels */
+ vmbus_rel_subchan(subchan, subchan_cnt);
+ device_printf(dev, "%d sub-channels setup done\n", subchan_cnt);
+ }
+
#if __FreeBSD_version >= 1100099
if (sc->hn_rx_ring_inuse > 1) {
/*
@@ -2867,8 +2875,8 @@ hn_channel_attach(struct hn_softc *sc, struct hv_vmbus_channel *chan)
vmbus_channel_cpu_set(chan, (sc->hn_cpu + idx) % mp_ncpus);
}
-void
-netvsc_subchan_callback(struct hn_softc *sc, struct hv_vmbus_channel *chan)
+static void
+hn_subchan_attach(struct hn_softc *sc, struct hv_vmbus_channel *chan)
{
KASSERT(!HV_VMBUS_CHAN_ISPRIMARY(chan),
diff --git a/sys/dev/hyperv/netvsc/hv_rndis.h b/sys/dev/hyperv/netvsc/hv_rndis.h
index 4749953..8ece1d0 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis.h
+++ b/sys/dev/hyperv/netvsc/hv_rndis.h
@@ -1068,8 +1068,6 @@ struct hv_vmbus_channel;
int netvsc_recv(struct hv_vmbus_channel *chan,
netvsc_packet *packet, rndis_tcp_ip_csum_info *csum_info);
void netvsc_channel_rollup(struct hv_vmbus_channel *chan);
-void netvsc_subchan_callback(struct hn_softc *sc,
- struct hv_vmbus_channel *chan);
void* hv_set_rppi_data(rndis_msg *rndis_mesg,
uint32_t rppi_size,
OpenPOWER on IntegriCloud