aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2013-10-15 11:18:59 +0800
committerDavid S. Miller <davem@davemloft.net>2013-10-17 15:53:09 -0400
commit35ed159bfd96a7547ec277ed8b550c7cbd9841b6 (patch)
tree08d5bade9d21d2457bcc1e19651b16106cafc582 /drivers/net
parent3ab098df35f8b98b6553edc2e40234af512ba877 (diff)
downloadkernel_goldelico_gta04-35ed159bfd96a7547ec277ed8b550c7cbd9841b6.zip
kernel_goldelico_gta04-35ed159bfd96a7547ec277ed8b550c7cbd9841b6.tar.gz
kernel_goldelico_gta04-35ed159bfd96a7547ec277ed8b550c7cbd9841b6.tar.bz2
virtio-net: refill only when device is up during setting queues
We used to schedule the refill work unconditionally after changing the number of queues. This may lead an issue if the device is not up. Since we only try to cancel the work in ndo_stop(), this may cause the refill work still work after removing the device. Fix this by only schedule the work when device is up. The bug were introduce by commit 9b9cd8024a2882e896c65222aa421d461354e3f2. (virtio-net: fix the race between channels setting and refill) Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/virtio_net.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c4bc1cc..9fbdfcd 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -938,7 +938,9 @@ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
return -EINVAL;
} else {
vi->curr_queue_pairs = queue_pairs;
- schedule_delayed_work(&vi->refill, 0);
+ /* virtnet_open() will refill when device is going to up. */
+ if (dev->flags & IFF_UP)
+ schedule_delayed_work(&vi->refill, 0);
}
return 0;
@@ -1741,7 +1743,9 @@ static int virtnet_restore(struct virtio_device *vdev)
vi->config_enable = true;
mutex_unlock(&vi->config_lock);
+ rtnl_lock();
virtnet_set_queues(vi, vi->curr_queue_pairs);
+ rtnl_unlock();
return 0;
}