diff options
| author | David S. Miller <davem@davemloft.net> | 2013-07-09 12:45:43 -0700 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-07-09 12:45:43 -0700 |
| commit | e1d6fbc3dedbb463fc79b48ddb05ab6b20fd088a (patch) | |
| tree | 6d63721222da5d652d2e4e65991a15007a83a520 /drivers/net | |
| parent | 01276ed2424eb78c95461545410923d5da154d31 (diff) | |
| parent | cbdadbbf0c790f79350a8f36029208944c5487d0 (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.c | 5 |
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); |
