All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 net-next] virtio-net: support XDP_TX when not more queues
@ 2021-02-25  8:22 Xuan Zhuo
  2021-02-25 17:01   ` Jesper Dangaard Brouer
  0 siblings, 1 reply; 4+ messages in thread
From: Xuan Zhuo @ 2021-02-25  8:22 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Jakub Kicinski,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, virtualization, bpf

The number of queues implemented by many virtio backends is limited,
especially some machines have a large number of CPUs. In this case, it
is often impossible to allocate a separate queue for XDP_TX.

This patch allows XDP_TX to run by reuse the existing SQ with
__netif_tx_lock() hold when there are not enough queues.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 48 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index ba8e637..c66ce4c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -195,6 +195,9 @@ struct virtnet_info {
 	/* # of XDP queue pairs currently used by the driver */
 	u16 xdp_queue_pairs;
 
+	/* xdp_queue_pairs may be 0, when xdp is already loaded. So add this. */
+	bool xdp_enabled;
+
 	/* I like... big packets and I cannot lie! */
 	bool big_packets;
 
@@ -481,14 +484,34 @@ static int __virtnet_xdp_xmit_one(struct virtnet_info *vi,
 	return 0;
 }
 
-static struct send_queue *virtnet_xdp_sq(struct virtnet_info *vi)
+static struct send_queue *virtnet_get_xdp_sq(struct virtnet_info *vi)
 {
+	struct netdev_queue *txq;
 	unsigned int qp;
 
-	qp = vi->curr_queue_pairs - vi->xdp_queue_pairs + smp_processor_id();
+	if (vi->curr_queue_pairs > nr_cpu_ids) {
+		qp = vi->curr_queue_pairs - vi->xdp_queue_pairs + smp_processor_id();
+	} else {
+		qp = smp_processor_id() % vi->curr_queue_pairs;
+		txq = netdev_get_tx_queue(vi->dev, qp);
+		__netif_tx_lock(txq, raw_smp_processor_id());
+	}
+
 	return &vi->sq[qp];
 }
 
+static void virtnet_put_xdp_sq(struct virtnet_info *vi, struct send_queue *sq)
+{
+	struct netdev_queue *txq;
+	unsigned int qp;
+
+	if (vi->curr_queue_pairs <= nr_cpu_ids) {
+		qp = sq - vi->sq;
+		txq = netdev_get_tx_queue(vi->dev, qp);
+		__netif_tx_unlock(txq);
+	}
+}
+
 static int virtnet_xdp_xmit(struct net_device *dev,
 			    int n, struct xdp_frame **frames, u32 flags)
 {
@@ -512,7 +535,7 @@ static int virtnet_xdp_xmit(struct net_device *dev,
 	if (!xdp_prog)
 		return -ENXIO;
 
-	sq = virtnet_xdp_sq(vi);
+	sq = virtnet_get_xdp_sq(vi);
 
 	if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) {
 		ret = -EINVAL;
@@ -560,12 +583,13 @@ static int virtnet_xdp_xmit(struct net_device *dev,
 	sq->stats.kicks += kicks;
 	u64_stats_update_end(&sq->stats.syncp);
 
+	virtnet_put_xdp_sq(vi, sq);
 	return ret;
 }
 
 static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
 {
-	return vi->xdp_queue_pairs ? VIRTIO_XDP_HEADROOM : 0;
+	return vi->xdp_enabled ? VIRTIO_XDP_HEADROOM : 0;
 }
 
 /* We copy the packet for XDP in the following cases:
@@ -1457,12 +1481,13 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
 		xdp_do_flush();
 
 	if (xdp_xmit & VIRTIO_XDP_TX) {
-		sq = virtnet_xdp_sq(vi);
+		sq = virtnet_get_xdp_sq(vi);
 		if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) {
 			u64_stats_update_begin(&sq->stats.syncp);
 			sq->stats.kicks++;
 			u64_stats_update_end(&sq->stats.syncp);
 		}
+		virtnet_put_xdp_sq(vi, sq);
 	}
 
 	return received;
@@ -2416,12 +2441,8 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
 		xdp_qp = nr_cpu_ids;
 
 	/* XDP requires extra queues for XDP_TX */
-	if (curr_qp + xdp_qp > vi->max_queue_pairs) {
-		NL_SET_ERR_MSG_MOD(extack, "Too few free TX rings available");
-		netdev_warn(dev, "request %i queues but max is %i\n",
-			    curr_qp + xdp_qp, vi->max_queue_pairs);
-		return -ENOMEM;
-	}
+	if (curr_qp + xdp_qp > vi->max_queue_pairs)
+		xdp_qp = 0;
 
 	old_prog = rtnl_dereference(vi->rq[0].xdp_prog);
 	if (!prog && !old_prog)
@@ -2454,11 +2475,14 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
 	vi->xdp_queue_pairs = xdp_qp;
 
 	if (prog) {
+		vi->xdp_enabled = true;
 		for (i = 0; i < vi->max_queue_pairs; i++) {
 			rcu_assign_pointer(vi->rq[i].xdp_prog, prog);
 			if (i == 0 && !old_prog)
 				virtnet_clear_guest_offloads(vi);
 		}
+	} else {
+		vi->xdp_enabled = false;
 	}
 
 	for (i = 0; i < vi->max_queue_pairs; i++) {
@@ -2526,7 +2550,7 @@ static int virtnet_set_features(struct net_device *dev,
 	int err;
 
 	if ((dev->features ^ features) & NETIF_F_LRO) {
-		if (vi->xdp_queue_pairs)
+		if (vi->xdp_enabled)
 			return -EBUSY;
 
 		if (features & NETIF_F_LRO)
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 net-next] virtio-net: support XDP_TX when not more queues
  2021-02-25  8:22 [PATCH v2 net-next] virtio-net: support XDP_TX when not more queues Xuan Zhuo
@ 2021-02-25 17:01   ` Jesper Dangaard Brouer
  0 siblings, 0 replies; 4+ messages in thread
From: Jesper Dangaard Brouer @ 2021-02-25 17:01 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: brouer, netdev, Michael S. Tsirkin, Jason Wang, David S. Miller,
	Jakub Kicinski, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf,
	Marek Majtyka

On Thu, 25 Feb 2021 16:22:29 +0800
Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:

> The number of queues implemented by many virtio backends is limited,
> especially some machines have a large number of CPUs. In this case, it
> is often impossible to allocate a separate queue for XDP_TX.
> 
> This patch allows XDP_TX to run by reuse the existing SQ with
> __netif_tx_lock() hold when there are not enough queues.
> 
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
> ---
>  drivers/net/virtio_net.c | 48 ++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 36 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
[...]
> @@ -2416,12 +2441,8 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
>  		xdp_qp = nr_cpu_ids;
>  
>  	/* XDP requires extra queues for XDP_TX */
> -	if (curr_qp + xdp_qp > vi->max_queue_pairs) {
> -		NL_SET_ERR_MSG_MOD(extack, "Too few free TX rings available");
> -		netdev_warn(dev, "request %i queues but max is %i\n",
> -			    curr_qp + xdp_qp, vi->max_queue_pairs);
> -		return -ENOMEM;
> -	}
> +	if (curr_qp + xdp_qp > vi->max_queue_pairs)
> +		xdp_qp = 0;

I think we should keep a netdev_warn message, but as a warning (not
error) that this will cause XDP_TX and XDP_REDIRECT to be slower on
this device due to too few free TX rings available.

In the future, we can mark a XDP features flag that this device is
operating in a slower "locked" Tx mode.

>  
>  	old_prog = rtnl_dereference(vi->rq[0].xdp_prog);
>  	if (!prog && !old_prog)



-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 net-next] virtio-net: support XDP_TX when not more queues
@ 2021-02-25 17:01   ` Jesper Dangaard Brouer
  0 siblings, 0 replies; 4+ messages in thread
From: Jesper Dangaard Brouer @ 2021-02-25 17:01 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	netdev, John Fastabend, Alexei Starovoitov, virtualization,
	Marek Majtyka, brouer, Jakub Kicinski, bpf, David S. Miller

On Thu, 25 Feb 2021 16:22:29 +0800
Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:

> The number of queues implemented by many virtio backends is limited,
> especially some machines have a large number of CPUs. In this case, it
> is often impossible to allocate a separate queue for XDP_TX.
> 
> This patch allows XDP_TX to run by reuse the existing SQ with
> __netif_tx_lock() hold when there are not enough queues.
> 
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
> ---
>  drivers/net/virtio_net.c | 48 ++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 36 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
[...]
> @@ -2416,12 +2441,8 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
>  		xdp_qp = nr_cpu_ids;
>  
>  	/* XDP requires extra queues for XDP_TX */
> -	if (curr_qp + xdp_qp > vi->max_queue_pairs) {
> -		NL_SET_ERR_MSG_MOD(extack, "Too few free TX rings available");
> -		netdev_warn(dev, "request %i queues but max is %i\n",
> -			    curr_qp + xdp_qp, vi->max_queue_pairs);
> -		return -ENOMEM;
> -	}
> +	if (curr_qp + xdp_qp > vi->max_queue_pairs)
> +		xdp_qp = 0;

I think we should keep a netdev_warn message, but as a warning (not
error) that this will cause XDP_TX and XDP_REDIRECT to be slower on
this device due to too few free TX rings available.

In the future, we can mark a XDP features flag that this device is
operating in a slower "locked" Tx mode.

>  
>  	old_prog = rtnl_dereference(vi->rq[0].xdp_prog);
>  	if (!prog && !old_prog)



-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 net-next] virtio-net: support XDP_TX when not more queues
@ 2021-02-25 10:45 kernel test robot
  0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-02-25 10:45 UTC (permalink / raw)
  To: kbuild

[-- Attachment #1: Type: text/plain, Size: 3571 bytes --]

CC: kbuild-all(a)lists.01.org
In-Reply-To: <1614241349-77324-1-git-send-email-xuanzhuo@linux.alibaba.com>
References: <1614241349-77324-1-git-send-email-xuanzhuo@linux.alibaba.com>
TO: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
TO: netdev(a)vger.kernel.org
CC: "Michael S. Tsirkin" <mst@redhat.com>
CC: Jason Wang <jasowang@redhat.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Alexei Starovoitov <ast@kernel.org>
CC: Daniel Borkmann <daniel@iogearbox.net>
CC: Jesper Dangaard Brouer <hawk@kernel.org>
CC: John Fastabend <john.fastabend@gmail.com>
CC: virtualization(a)lists.linux-foundation.org
CC: bpf(a)vger.kernel.org

Hi Xuan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Xuan-Zhuo/virtio-net-support-XDP_TX-when-not-more-queues/20210225-162459
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git d310ec03a34e92a77302edb804f7d68ee4f01ba0
:::::: branch date: 2 hours ago
:::::: commit date: 2 hours ago
config: i386-randconfig-s001-20210225 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-229-g60c1f270-dirty
        # https://github.com/0day-ci/linux/commit/a9dbec18799a2aedf34da67f39f02fb2d72e7192
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Xuan-Zhuo/virtio-net-support-XDP_TX-when-not-more-queues/20210225-162459
        git checkout a9dbec18799a2aedf34da67f39f02fb2d72e7192
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


"sparse warnings: (new ones prefixed by >>)"
>> drivers/net/virtio_net.c:500:9: sparse: sparse: context imbalance in 'virtnet_get_xdp_sq' - different lock contexts for basic block
   drivers/net/virtio_net.c:509:17: sparse: sparse: context imbalance in 'virtnet_put_xdp_sq' - unexpected unlock

vim +/virtnet_get_xdp_sq +500 drivers/net/virtio_net.c

56434a01b12e99 John Fastabend  2016-12-15  486  
a9dbec18799a2a Xuan Zhuo       2021-02-25  487  static struct send_queue *virtnet_get_xdp_sq(struct virtnet_info *vi)
2a43565c064653 Toshiaki Makita 2018-07-23  488  {
a9dbec18799a2a Xuan Zhuo       2021-02-25  489  	struct netdev_queue *txq;
2a43565c064653 Toshiaki Makita 2018-07-23  490  	unsigned int qp;
2a43565c064653 Toshiaki Makita 2018-07-23  491  
a9dbec18799a2a Xuan Zhuo       2021-02-25  492  	if (vi->curr_queue_pairs > nr_cpu_ids) {
2a43565c064653 Toshiaki Makita 2018-07-23  493  		qp = vi->curr_queue_pairs - vi->xdp_queue_pairs + smp_processor_id();
a9dbec18799a2a Xuan Zhuo       2021-02-25  494  	} else {
a9dbec18799a2a Xuan Zhuo       2021-02-25  495  		qp = smp_processor_id() % vi->curr_queue_pairs;
a9dbec18799a2a Xuan Zhuo       2021-02-25  496  		txq = netdev_get_tx_queue(vi->dev, qp);
a9dbec18799a2a Xuan Zhuo       2021-02-25  497  		__netif_tx_lock(txq, raw_smp_processor_id());
a9dbec18799a2a Xuan Zhuo       2021-02-25  498  	}
a9dbec18799a2a Xuan Zhuo       2021-02-25  499  
2a43565c064653 Toshiaki Makita 2018-07-23 @500  	return &vi->sq[qp];
2a43565c064653 Toshiaki Makita 2018-07-23  501  }
2a43565c064653 Toshiaki Makita 2018-07-23  502  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 35604 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-02-25 17:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-25  8:22 [PATCH v2 net-next] virtio-net: support XDP_TX when not more queues Xuan Zhuo
2021-02-25 17:01 ` Jesper Dangaard Brouer
2021-02-25 17:01   ` Jesper Dangaard Brouer
2021-02-25 10:45 kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.