summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-07-09 12:45:43 -0700
committerDavid S. Miller <davem@davemloft.net>2013-07-09 12:45:43 -0700
commite1d6fbc3dedbb463fc79b48ddb05ab6b20fd088a (patch)
tree6d63721222da5d652d2e4e65991a15007a83a520 /drivers/net
parent01276ed2424eb78c95461545410923d5da154d31 (diff)
parentcbdadbbf0c790f79350a8f36029208944c5487d0 (diff)
virtio_net: fix race in RX VQ processing
Michael S. Tsirkin says: ==================== Jason Wang reported a race in RX VQ processing: virtqueue_enable_cb is called outside napi lock, violating virtio serialization rules. The race has been there from day 1, but it got especially nasty in 3.0 when commit a5c262c5fd83ece01bd649fb08416c501d4c59d7 "virtio_ring: support event idx feature" added more dependency on vq state. Please review, and consider for 3.11 and stable. Changes from v1: - Added Jason's Tested-by tag - minor coding style fix ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/virtio_net.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c9e00387d999..42d670a468f8 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -602,7 +602,7 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
container_of(napi, struct receive_queue, napi);
struct virtnet_info *vi = rq->vq->vdev->priv;
void *buf;
- unsigned int len, received = 0;
+ unsigned int r, len, received = 0;
again:
while (received < budget &&
@@ -619,8 +619,9 @@ again:
/* Out of packets? */
if (received < budget) {
+ r = virtqueue_enable_cb_prepare(rq->vq);
napi_complete(napi);
- if (unlikely(!virtqueue_enable_cb(rq->vq)) &&
+ if (unlikely(virtqueue_poll(rq->vq, r)) &&
napi_schedule_prep(napi)) {
virtqueue_disable_cb(rq->vq);
__napi_schedule(napi);