From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
To: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Cc: <netdev@vger.kernel.org>, "David S. Miller" <davem@davemloft.net>,
"Eric Dumazet" <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
"Michael S. Tsirkin" <mst@redhat.com>,
Jason Wang <jasowang@redhat.com>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Jesper Dangaard Brouer <hawk@kernel.org>,
"John Fastabend" <john.fastabend@gmail.com>,
<virtualization@lists.linux-foundation.org>,
<bpf@vger.kernel.org>
Subject: Re: [PATCH net-next v2 18/21] virtio_net: xsk: rx: introduce receive_xsk() to recv xsk buffer
Date: Mon, 13 Nov 2023 17:11:04 +0100 [thread overview]
Message-ID: <ZVJKmGvQWhhwUvvP@boxer> (raw)
In-Reply-To: <20231107031227.100015-19-xuanzhuo@linux.alibaba.com>
On Tue, Nov 07, 2023 at 11:12:24AM +0800, Xuan Zhuo wrote:
> The virtnet_xdp_handler() is re-used. But
>
> 1. We need to copy data to create skb for XDP_PASS.
> 2. We need to call xsk_buff_free() to release the buffer.
> 3. The handle for xdp_buff is difference.
>
> If we pushed this logic into existing receive handle(merge and small),
> we would have to maintain code scattered inside merge and small (and big).
> So I think it is a good choice for us to put the xsk code into an
> independent function.
>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> ---
> drivers/net/virtio/main.c | 12 ++--
> drivers/net/virtio/virtio_net.h | 4 ++
> drivers/net/virtio/xsk.c | 120 ++++++++++++++++++++++++++++++++
> drivers/net/virtio/xsk.h | 4 ++
> 4 files changed, 135 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/virtio/main.c b/drivers/net/virtio/main.c
> index a318b2533b94..095f4acb0577 100644
> --- a/drivers/net/virtio/main.c
> +++ b/drivers/net/virtio/main.c
> @@ -831,10 +831,10 @@ static void put_xdp_frags(struct xdp_buff *xdp)
> }
> }
>
> -static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
> - struct net_device *dev,
> - unsigned int *xdp_xmit,
> - struct virtnet_rq_stats *stats)
> +int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
> + struct net_device *dev,
> + unsigned int *xdp_xmit,
> + struct virtnet_rq_stats *stats)
> {
> struct xdp_frame *xdpf;
> int err;
> @@ -1598,7 +1598,9 @@ static void receive_buf(struct virtnet_info *vi, struct virtnet_rq *rq,
> return;
> }
>
> - if (vi->mergeable_rx_bufs)
> + if (rq->xsk.pool)
> + skb = virtnet_receive_xsk(dev, vi, rq, buf, len, xdp_xmit, stats);
> + else if (vi->mergeable_rx_bufs)
> skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
> stats);
> else if (vi->big_packets)
> diff --git a/drivers/net/virtio/virtio_net.h b/drivers/net/virtio/virtio_net.h
> index 2005d0cd22e2..f520fec06662 100644
> --- a/drivers/net/virtio/virtio_net.h
> +++ b/drivers/net/virtio/virtio_net.h
> @@ -339,4 +339,8 @@ void virtnet_tx_pause(struct virtnet_info *vi, struct virtnet_sq *sq);
> void virtnet_tx_resume(struct virtnet_info *vi, struct virtnet_sq *sq);
> void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf);
> void virtnet_rq_free_unused_buf(struct virtqueue *vq, void *buf);
> +int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
> + struct net_device *dev,
> + unsigned int *xdp_xmit,
> + struct virtnet_rq_stats *stats);
> #endif
> diff --git a/drivers/net/virtio/xsk.c b/drivers/net/virtio/xsk.c
> index b09c473c29fb..5c7eb19ab04b 100644
> --- a/drivers/net/virtio/xsk.c
> +++ b/drivers/net/virtio/xsk.c
> @@ -14,6 +14,18 @@ static void sg_fill_dma(struct scatterlist *sg, dma_addr_t addr, u32 len)
> sg->length = len;
> }
>
> +static unsigned int virtnet_receive_buf_num(struct virtnet_info *vi, char *buf)
> +{
> + struct virtio_net_hdr_mrg_rxbuf *hdr;
> +
> + if (vi->mergeable_rx_bufs) {
> + hdr = (struct virtio_net_hdr_mrg_rxbuf *)buf;
> + return virtio16_to_cpu(vi->vdev, hdr->num_buffers);
> + }
> +
> + return 1;
> +}
> +
> static void virtnet_xsk_check_queue(struct virtnet_sq *sq)
> {
> struct virtnet_info *vi = sq->vq->vdev->priv;
> @@ -38,6 +50,114 @@ static void virtnet_xsk_check_queue(struct virtnet_sq *sq)
> netif_stop_subqueue(dev, qnum);
> }
>
> +static void merge_drop_follow_xdp(struct net_device *dev,
> + struct virtnet_rq *rq,
> + u32 num_buf,
> + struct virtnet_rq_stats *stats)
> +{
> + struct xdp_buff *xdp;
> + u32 len;
> +
> + while (num_buf-- > 1) {
> + xdp = virtqueue_get_buf(rq->vq, &len);
> + if (unlikely(!xdp)) {
> + pr_debug("%s: rx error: %d buffers missing\n",
> + dev->name, num_buf);
> + dev->stats.rx_length_errors++;
> + break;
> + }
> + u64_stats_add(&stats->bytes, len);
> + xsk_buff_free(xdp);
> + }
> +}
> +
> +static struct sk_buff *construct_skb(struct virtnet_rq *rq,
could you name this to virtnet_construct_skb_zc
> + struct xdp_buff *xdp)
> +{
> + unsigned int metasize = xdp->data - xdp->data_meta;
> + struct sk_buff *skb;
> + unsigned int size;
> +
> + size = xdp->data_end - xdp->data_hard_start;
> + skb = napi_alloc_skb(&rq->napi, size);
> + if (unlikely(!skb))
> + return NULL;
> +
> + skb_reserve(skb, xdp->data_meta - xdp->data_hard_start);
> +
> + size = xdp->data_end - xdp->data_meta;
> + memcpy(__skb_put(skb, size), xdp->data_meta, size);
> +
> + if (metasize) {
> + __skb_pull(skb, metasize);
> + skb_metadata_set(skb, metasize);
> + }
> +
> + return skb;
> +}
> +
> +struct sk_buff *virtnet_receive_xsk(struct net_device *dev, struct virtnet_info *vi,
> + struct virtnet_rq *rq, void *buf,
> + unsigned int len, unsigned int *xdp_xmit,
> + struct virtnet_rq_stats *stats)
> +{
> + struct virtio_net_hdr_mrg_rxbuf *hdr;
> + struct sk_buff *skb = NULL;
> + u32 ret, headroom, num_buf;
> + struct bpf_prog *prog;
> + struct xdp_buff *xdp;
> +
> + len -= vi->hdr_len;
> +
> + xdp = (struct xdp_buff *)buf;
> +
> + xsk_buff_set_size(xdp, len);
> +
> + hdr = xdp->data - vi->hdr_len;
> +
> + num_buf = virtnet_receive_buf_num(vi, (char *)hdr);
> + if (num_buf > 1)
> + goto drop;
> +
> + headroom = xdp->data - xdp->data_hard_start;
> +
> + xdp_prepare_buff(xdp, xdp->data_hard_start, headroom, len, true);
Please don't.
xsk_buff_pool has ::data_hard_start initialized and you already
initialized ::data and ::data_end within xsk_buff_set_size().
> + xsk_buff_dma_sync_for_cpu(xdp, rq->xsk.pool);
> +
> + ret = XDP_PASS;
> + rcu_read_lock();
We don't need RCU sections for running XDP progs anymore.
> + prog = rcu_dereference(rq->xdp_prog);
> + if (prog)
Prog is always !NULL for ZC case. Just dereference it at the beginning of
rx processing instead of doing it for each buf.
> + ret = virtnet_xdp_handler(prog, xdp, dev, xdp_xmit, stats);
> + rcu_read_unlock();
> +
> + switch (ret) {
> + case XDP_PASS:
> + skb = construct_skb(rq, xdp);
> + xsk_buff_free(xdp);
> + break;
> +
> + case XDP_TX:
> + case XDP_REDIRECT:
> + goto consumed;
> +
> + default:
> + goto drop;
> + }
> +
> + return skb;
> +
> +drop:
> + u64_stats_inc(&stats->drops);
> +
> + xsk_buff_free(xdp);
> +
> + if (num_buf > 1)
> + merge_drop_follow_xdp(dev, rq, num_buf, stats);
> +consumed:
> + return NULL;
> +}
> +
> int virtnet_add_recvbuf_xsk(struct virtnet_info *vi, struct virtnet_rq *rq,
> struct xsk_buff_pool *pool, gfp_t gfp)
> {
> diff --git a/drivers/net/virtio/xsk.h b/drivers/net/virtio/xsk.h
> index bef41a3f954e..dbd2839a5f61 100644
> --- a/drivers/net/virtio/xsk.h
> +++ b/drivers/net/virtio/xsk.h
> @@ -25,4 +25,8 @@ bool virtnet_xsk_xmit(struct virtnet_sq *sq, struct xsk_buff_pool *pool,
> int virtnet_xsk_wakeup(struct net_device *dev, u32 qid, u32 flag);
> int virtnet_add_recvbuf_xsk(struct virtnet_info *vi, struct virtnet_rq *rq,
> struct xsk_buff_pool *pool, gfp_t gfp);
> +struct sk_buff *virtnet_receive_xsk(struct net_device *dev, struct virtnet_info *vi,
> + struct virtnet_rq *rq, void *buf,
> + unsigned int len, unsigned int *xdp_xmit,
> + struct virtnet_rq_stats *stats);
> #endif
> --
> 2.32.0.3.g01195cf9f
>
>
next prev parent reply other threads:[~2023-11-13 16:11 UTC|newest]
Thread overview: 83+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-07 3:12 [PATCH net-next v2 00/21] virtio-net: support AF_XDP zero copy Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 01/21] virtio_net: rename free_old_xmit_skbs to free_old_xmit Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 02/21] virtio_net: unify the code for recycling the xmit ptr Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 03/21] virtio_net: independent directory Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 04/21] virtio_net: move core structures to virtio_net.h Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-09 6:03 ` Jason Wang
2023-11-07 3:12 ` [PATCH net-next v2 05/21] virtio_net: add prefix virtnet to all struct inside virtio_net.h Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-09 6:04 ` Jason Wang
2023-11-07 3:12 ` [PATCH net-next v2 06/21] virtio_net: separate virtnet_rx_resize() Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 07/21] virtio_net: separate virtnet_tx_resize() Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 08/21] virtio_net: sq support premapped mode Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-09 6:37 ` Jason Wang
2023-11-09 10:58 ` Xuan Zhuo
2023-11-14 3:26 ` Jason Wang
2023-11-14 3:28 ` Xuan Zhuo
2023-11-14 3:55 ` Jason Wang
2023-11-14 3:57 ` Xuan Zhuo
2023-11-14 4:27 ` Jason Wang
2023-11-14 4:45 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 09/21] virtio_net: xsk: bind/unbind xsk Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 10/21] virtio_net: xsk: prevent disable tx napi Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 11/21] virtio_net: move some api to header Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 12/21] virtio_net: xsk: tx: support tx Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-09 8:09 ` Michael S. Tsirkin
2023-11-09 11:06 ` Xuan Zhuo
2023-11-09 11:58 ` Michael S. Tsirkin
2023-11-10 1:51 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 13/21] virtio_net: xsk: tx: support wakeup Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 14/21] virtio_net: xsk: tx: virtnet_free_old_xmit() distinguishes xsk buffer Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-09 11:11 ` Michael S. Tsirkin
2023-11-09 11:16 ` Xuan Zhuo
2023-11-09 11:59 ` Michael S. Tsirkin
2023-11-10 1:44 ` Xuan Zhuo
2023-11-10 5:32 ` Michael S. Tsirkin
2023-11-10 5:50 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 15/21] virtio_net: xsk: tx: virtnet_sq_free_unused_buf() check " Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 16/21] virtio_net: xsk: rx: introduce add_recvbuf_xsk() Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-09 8:12 ` Michael S. Tsirkin
2023-11-09 11:11 ` Xuan Zhuo
2023-11-09 16:26 ` Maciej Fijalkowski
2023-11-10 2:38 ` Xuan Zhuo
2023-11-13 16:00 ` Maciej Fijalkowski
2023-11-14 3:16 ` Xuan Zhuo
2023-11-10 3:04 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 17/21] virtio_net: xsk: rx: skip dma unmap when rq is bind with AF_XDP Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-09 8:15 ` Michael S. Tsirkin
2023-11-09 11:10 ` Xuan Zhuo
2023-11-09 12:00 ` Michael S. Tsirkin
2023-11-10 1:47 ` Xuan Zhuo
2023-11-10 5:33 ` Michael S. Tsirkin
2023-11-10 5:51 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 18/21] virtio_net: xsk: rx: introduce receive_xsk() to recv xsk buffer Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-13 16:11 ` Maciej Fijalkowski [this message]
2023-11-14 3:43 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 19/21] virtio_net: xsk: rx: virtnet_rq_free_unused_buf() check " Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 20/21] virtio_net: update tx timeout record Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 3:12 ` [PATCH net-next v2 21/21] virtio_net: xdp_features add NETDEV_XDP_ACT_XSK_ZEROCOPY Xuan Zhuo
2023-11-07 3:12 ` Xuan Zhuo
2023-11-07 18:01 ` [PATCH net-next v2 00/21] virtio-net: support AF_XDP zero copy Jakub Kicinski
2023-11-08 5:49 ` Xuan Zhuo
2023-11-09 8:19 ` Michael S. Tsirkin
2023-11-09 10:37 ` Xuan Zhuo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZVJKmGvQWhhwUvvP@boxer \
--to=maciej.fijalkowski@intel.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hawk@kernel.org \
--cc=jasowang@redhat.com \
--cc=john.fastabend@gmail.com \
--cc=kuba@kernel.org \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=virtualization@lists.linux-foundation.org \
--cc=xuanzhuo@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.