Skip to content

Commit

Permalink
staging: hv: Fix GARP not sent after Quick Migration
Browse files Browse the repository at this point in the history
After Quick Migration, the network is not immediately operational in the
current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, I added
another netif_notify_peers() into a scheduled work, otherwise GARP packet will
not be sent after quick migration, and cause network disconnection.

Thanks to Mike Surcouf <mike@surcouf.co.uk> for reporting the bug and
testing the patch.

Reported-by: Mike Surcouf <mike@surcouf.co.uk>
Tested-by: Mike Surcouf <mike@surcouf.co.uk>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Hank Janssen <hjanssen@microsoft.com>
Signed-off-by: Abhishek Kane <v-abkane@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Haiyang Zhang authored and Greg Kroah-Hartman committed Apr 6, 2011
1 parent 6a6ec62 commit c996edc
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions drivers/staging/hv/netvsc_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct net_device_context {
/* point back to our device context */
struct hv_device *device_ctx;
unsigned long avail;
struct work_struct work;
};


Expand Down Expand Up @@ -219,6 +220,7 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj,
unsigned int status)
{
struct net_device *net = dev_get_drvdata(&device_obj->device);
struct net_device_context *ndev_ctx;

if (!net) {
DPRINT_ERR(NETVSC_DRV, "got link status but net device "
Expand All @@ -230,6 +232,8 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj,
netif_carrier_on(net);
netif_wake_queue(net);
netif_notify_peers(net);
ndev_ctx = netdev_priv(net);
schedule_work(&ndev_ctx->work);
} else {
netif_carrier_off(net);
netif_stop_queue(net);
Expand Down Expand Up @@ -328,6 +332,25 @@ static const struct net_device_ops device_ops = {
.ndo_set_mac_address = eth_mac_addr,
};

/*
* Send GARP packet to network peers after migrations.
* After Quick Migration, the network is not immediately operational in the
* current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add
* another netif_notify_peers() into a scheduled work, otherwise GARP packet
* will not be sent after quick migration, and cause network disconnection.
*/
static void netvsc_send_garp(struct work_struct *w)
{
struct net_device_context *ndev_ctx;
struct net_device *net;

msleep(20);
ndev_ctx = container_of(w, struct net_device_context, work);
net = dev_get_drvdata(&ndev_ctx->device_ctx->device);
netif_notify_peers(net);
}


static int netvsc_probe(struct device *device)
{
struct hv_driver *drv =
Expand All @@ -353,6 +376,7 @@ static int netvsc_probe(struct device *device)
net_device_ctx->device_ctx = device_obj;
net_device_ctx->avail = ring_size;
dev_set_drvdata(device, net);
INIT_WORK(&net_device_ctx->work, netvsc_send_garp);

/* Notify the netvsc driver of the new device */
ret = net_drv_obj->base.dev_add(device_obj, &device_info);
Expand Down

0 comments on commit c996edc

Please sign in to comment.