diff options
Diffstat (limited to 'drivers/net/virtio_net.c')
| -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 90a23e410d1..82dba5aaf42 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)  	}  } +static void virtnet_napi_enable(struct virtnet_info *vi) +{ +	napi_enable(&vi->napi); + +	/* If all buffers were filled by other side before we napi_enabled, we +	 * won't get another interrupt, so process any outstanding packets +	 * now.  virtnet_poll wants re-enable the queue, so we disable here. +	 * We synchronize against interrupts via NAPI_STATE_SCHED */ +	if (napi_schedule_prep(&vi->napi)) { +		virtqueue_disable_cb(vi->rvq); +		__napi_schedule(&vi->napi); +	} +} +  static void refill_work(struct work_struct *work)  {  	struct virtnet_info *vi; @@ -454,7 +468,7 @@ static void refill_work(struct work_struct *work)  	vi = container_of(work, struct virtnet_info, refill.work);  	napi_disable(&vi->napi);  	still_empty = !try_fill_recv(vi, GFP_KERNEL); -	napi_enable(&vi->napi); +	virtnet_napi_enable(vi);  	/* In theory, this can happen: if we don't get any buffers in  	 * we will *never* try to fill again. */ @@ -638,16 +652,7 @@ static int virtnet_open(struct net_device *dev)  {  	struct virtnet_info *vi = netdev_priv(dev); -	napi_enable(&vi->napi); - -	/* If all buffers were filled by other side before we napi_enabled, we -	 * won't get another interrupt, so process any outstanding packets -	 * now.  virtnet_poll wants re-enable the queue, so we disable here. -	 * We synchronize against interrupts via NAPI_STATE_SCHED */ -	if (napi_schedule_prep(&vi->napi)) { -		virtqueue_disable_cb(vi->rvq); -		__napi_schedule(&vi->napi); -	} +	virtnet_napi_enable(vi);  	return 0;  }  |