diff options
Diffstat (limited to 'drivers/net/virtio_net.c')
| -rw-r--r-- | drivers/net/virtio_net.c | 31 | 
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 64c87bb48a41..7646ddd9bef7 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -503,6 +503,7 @@ struct virtio_net_common_hdr {  static struct virtio_net_common_hdr xsk_hdr;  static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf); +static void virtnet_sq_free_unused_buf_done(struct virtqueue *vq);  static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,  			       struct net_device *dev,  			       unsigned int *xdp_xmit, @@ -3054,7 +3055,6 @@ static int virtnet_enable_queue_pair(struct virtnet_info *vi, int qp_index)  	if (err < 0)  		goto err_xdp_reg_mem_model; -	netdev_tx_reset_queue(netdev_get_tx_queue(vi->dev, qp_index));  	virtnet_napi_enable(vi->rq[qp_index].vq, &vi->rq[qp_index].napi);  	virtnet_napi_tx_enable(vi, vi->sq[qp_index].vq, &vi->sq[qp_index].napi); @@ -3332,7 +3332,7 @@ static int virtnet_rx_resize(struct virtnet_info *vi,  	virtnet_rx_pause(vi, rq); -	err = virtqueue_resize(rq->vq, ring_num, virtnet_rq_unmap_free_buf); +	err = virtqueue_resize(rq->vq, ring_num, virtnet_rq_unmap_free_buf, NULL);  	if (err)  		netdev_err(vi->dev, "resize rx fail: rx queue index: %d err: %d\n", qindex, err); @@ -3395,7 +3395,8 @@ static int virtnet_tx_resize(struct virtnet_info *vi, struct send_queue *sq,  	virtnet_tx_pause(vi, sq); -	err = virtqueue_resize(sq->vq, ring_num, virtnet_sq_free_unused_buf); +	err = virtqueue_resize(sq->vq, ring_num, virtnet_sq_free_unused_buf, +			       virtnet_sq_free_unused_buf_done);  	if (err)  		netdev_err(vi->dev, "resize tx fail: tx queue index: %d err: %d\n", qindex, err); @@ -5710,7 +5711,7 @@ static int virtnet_rq_bind_xsk_pool(struct virtnet_info *vi, struct receive_queu  	virtnet_rx_pause(vi, rq); -	err = virtqueue_reset(rq->vq, virtnet_rq_unmap_free_buf); +	err = virtqueue_reset(rq->vq, virtnet_rq_unmap_free_buf, NULL);  	if (err) {  		netdev_err(vi->dev, "reset rx fail: rx queue index: %d err: %d\n", qindex, err); @@ -5739,7 +5740,8 @@ static int virtnet_sq_bind_xsk_pool(struct virtnet_info *vi,  	virtnet_tx_pause(vi, sq); -	err = virtqueue_reset(sq->vq, virtnet_sq_free_unused_buf); +	err = virtqueue_reset(sq->vq, virtnet_sq_free_unused_buf, +			      virtnet_sq_free_unused_buf_done);  	if (err) {  		netdev_err(vi->dev, "reset tx fail: tx queue index: %d err: %d\n", qindex, err);  		pool = NULL; @@ -6214,7 +6216,7 @@ static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf)  {  	struct virtnet_info *vi = vq->vdev->priv;  	struct send_queue *sq; -	int i = vq2rxq(vq); +	int i = vq2txq(vq);  	sq = &vi->sq[i]; @@ -6234,6 +6236,14 @@ static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf)  	}  } +static void virtnet_sq_free_unused_buf_done(struct virtqueue *vq) +{ +	struct virtnet_info *vi = vq->vdev->priv; +	int i = vq2txq(vq); + +	netdev_tx_reset_queue(netdev_get_tx_queue(vi->dev, i)); +} +  static void free_unused_bufs(struct virtnet_info *vi)  {  	void *buf; @@ -6966,11 +6976,20 @@ free:  static void remove_vq_common(struct virtnet_info *vi)  { +	int i; +  	virtio_reset_device(vi->vdev);  	/* Free unused buffers in both send and recv, if any. */  	free_unused_bufs(vi); +	/* +	 * Rule of thumb is netdev_tx_reset_queue() should follow any +	 * skb freeing not followed by netdev_tx_completed_queue() +	 */ +	for (i = 0; i < vi->max_queue_pairs; i++) +		netdev_tx_reset_queue(netdev_get_tx_queue(vi->dev, i)); +  	free_receive_bufs(vi);  	free_receive_page_frags(vi);  | 
