aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaiyang Zhang <haiyangz@microsoft.com>2014-12-01 16:28:39 -0500
committerDavid S. Miller <davem@davemloft.net>2014-12-08 20:24:11 -0500
commitc3582a2c4d0baf1fa3955c8b3d3d61308df474c7 (patch)
treebcff2477cb791564cd2189026c088ec69b1ee217
parent6867b17b26d80cfd419e491141feb75082915979 (diff)
hyperv: Add support for vNIC hot removal
This patch adds proper handling of the vNIC hot removal event, which includes a rescind-channel-offer message from the host side that triggers vNIC close and removal. In this case, the notices to the host during close and removal is not necessary because the channel is rescinded. This patch blocks these unnecessary messages, and lets vNIC removal process complete normally. Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> Reviewed-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/hv/channel_mgmt.c2
-rw-r--r--drivers/net/hyperv/netvsc.c3
-rw-r--r--drivers/net/hyperv/rndis_filter.c3
-rw-r--r--include/linux/hyperv.h2
4 files changed, 10 insertions, 0 deletions
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index a2d1a9612c86..191a6a3ae6ca 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -517,6 +517,8 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
517 /* Just return here, no channel found */ 517 /* Just return here, no channel found */
518 return; 518 return;
519 519
520 channel->rescind = true;
521
520 /* work is initialized for vmbus_process_rescind_offer() from 522 /* work is initialized for vmbus_process_rescind_offer() from
521 * vmbus_process_offer() where the channel got created */ 523 * vmbus_process_offer() where the channel got created */
522 queue_work(channel->controlwq, &channel->work); 524 queue_work(channel->controlwq, &channel->work);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 6fc834e4306d..dd867e6cabd6 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -764,6 +764,9 @@ int netvsc_send(struct hv_device *device,
764 out_channel = device->channel; 764 out_channel = device->channel;
765 packet->channel = out_channel; 765 packet->channel = out_channel;
766 766
767 if (out_channel->rescind)
768 return -ENODEV;
769
767 if (packet->page_buf_cnt) { 770 if (packet->page_buf_cnt) {
768 ret = vmbus_sendpacket_pagebuffer(out_channel, 771 ret = vmbus_sendpacket_pagebuffer(out_channel,
769 packet->page_buf, 772 packet->page_buf,
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 7b2c5d1e9bad..ec0c40a8f653 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -958,6 +958,9 @@ static int rndis_filter_close_device(struct rndis_device *dev)
958 return 0; 958 return 0;
959 959
960 ret = rndis_filter_set_packet_filter(dev, 0); 960 ret = rndis_filter_set_packet_filter(dev, 0);
961 if (ret == -ENODEV)
962 ret = 0;
963
961 if (ret == 0) 964 if (ret == 0)
962 dev->state = RNDIS_DEV_INITIALIZED; 965 dev->state = RNDIS_DEV_INITIALIZED;
963 966
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 08cfaff8a072..476c685ca6f9 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -650,6 +650,8 @@ struct vmbus_channel {
650 u8 monitor_grp; 650 u8 monitor_grp;
651 u8 monitor_bit; 651 u8 monitor_bit;
652 652
653 bool rescind; /* got rescind msg */
654
653 u32 ringbuffer_gpadlhandle; 655 u32 ringbuffer_gpadlhandle;
654 656
655 /* Allocated memory for ring buffer */ 657 /* Allocated memory for ring buffer */