diff options
| -rw-r--r-- | drivers/net/virtio_net.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 90a23e410d1b..82dba5aaf423 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
| @@ -446,6 +446,20 @@ static void skb_recv_done(struct virtqueue *rvq) | |||
| 446 | } | 446 | } |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | static void virtnet_napi_enable(struct virtnet_info *vi) | ||
| 450 | { | ||
| 451 | napi_enable(&vi->napi); | ||
| 452 | |||
| 453 | /* If all buffers were filled by other side before we napi_enabled, we | ||
| 454 | * won't get another interrupt, so process any outstanding packets | ||
| 455 | * now. virtnet_poll wants re-enable the queue, so we disable here. | ||
| 456 | * We synchronize against interrupts via NAPI_STATE_SCHED */ | ||
| 457 | if (napi_schedule_prep(&vi->napi)) { | ||
| 458 | virtqueue_disable_cb(vi->rvq); | ||
| 459 | __napi_schedule(&vi->napi); | ||
| 460 | } | ||
| 461 | } | ||
| 462 | |||
| 449 | static void refill_work(struct work_struct *work) | 463 | static void refill_work(struct work_struct *work) |
| 450 | { | 464 | { |
| 451 | struct virtnet_info *vi; | 465 | struct virtnet_info *vi; |
| @@ -454,7 +468,7 @@ static void refill_work(struct work_struct *work) | |||
| 454 | vi = container_of(work, struct virtnet_info, refill.work); | 468 | vi = container_of(work, struct virtnet_info, refill.work); |
| 455 | napi_disable(&vi->napi); | 469 | napi_disable(&vi->napi); |
| 456 | still_empty = !try_fill_recv(vi, GFP_KERNEL); | 470 | still_empty = !try_fill_recv(vi, GFP_KERNEL); |
| 457 | napi_enable(&vi->napi); | 471 | virtnet_napi_enable(vi); |
| 458 | 472 | ||
| 459 | /* In theory, this can happen: if we don't get any buffers in | 473 | /* In theory, this can happen: if we don't get any buffers in |
| 460 | * we will *never* try to fill again. */ | 474 | * we will *never* try to fill again. */ |
| @@ -638,16 +652,7 @@ static int virtnet_open(struct net_device *dev) | |||
| 638 | { | 652 | { |
| 639 | struct virtnet_info *vi = netdev_priv(dev); | 653 | struct virtnet_info *vi = netdev_priv(dev); |
| 640 | 654 | ||
| 641 | napi_enable(&vi->napi); | 655 | virtnet_napi_enable(vi); |
| 642 | |||
| 643 | /* If all buffers were filled by other side before we napi_enabled, we | ||
| 644 | * won't get another interrupt, so process any outstanding packets | ||
| 645 | * now. virtnet_poll wants re-enable the queue, so we disable here. | ||
| 646 | * We synchronize against interrupts via NAPI_STATE_SCHED */ | ||
| 647 | if (napi_schedule_prep(&vi->napi)) { | ||
| 648 | virtqueue_disable_cb(vi->rvq); | ||
| 649 | __napi_schedule(&vi->napi); | ||
| 650 | } | ||
| 651 | return 0; | 656 | return 0; |
| 652 | } | 657 | } |
| 653 | 658 | ||
