mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jon Kohler <jon@nutanix.com>
To: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Cc: "ast@kernel.org" <ast@kernel.org>,
	"daniel@iogearbox.net" <daniel@iogearbox.net>,
	"davem@davemloft.net" <davem@davemloft.net>,
	"kuba@kernel.org" <kuba@kernel.org>,
	"hawk@kernel.org" <hawk@kernel.org>,
	"john.fastabend@gmail.com" <john.fastabend@gmail.com>,
	"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
	"bpf@vger.kernel.org" <bpf@vger.kernel.org>,
	"aleksander.lobakin@intel.com" <aleksander.lobakin@intel.com>,
	Jason Wang <jasowang@redhat.com>,
	Andrew Lunn <andrew+netdev@lunn.ch>,
	Eric Dumazet <edumazet@google.com>,
	Paolo Abeni <pabeni@redhat.com>,
	open list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH net-next 2/4] tun: optimize skb allocation in tun_xdp_one
Date: Thu, 8 May 2025 03:02:37 +0000	[thread overview]
Message-ID: <3BE7CD63-D019-415D-B711-E508663671FD@nutanix.com> (raw)
In-Reply-To: <681bc78dc5005_20dc6429460@willemb.c.googlers.com.notmuch>



> On May 7, 2025, at 4:50 PM, Willem de Bruijn <willemdebruijn.kernel@gmail.com> wrote:
> 
> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> Jon Kohler wrote:
>> Enhance TUN_MSG_PTR batch processing by leveraging bulk allocation from
>> the per-CPU NAPI cache via napi_skb_cache_get_bulk. This improves
>> efficiency by reducing allocation overhead and is especially useful
>> when using IFF_NAPI and GRO is able to feed the cache entries back.
>> 
>> Handle scenarios where full preallocation of SKBs is not possible by
>> gracefully dropping only the uncovered portion of the batch payload.
>> 
>> Cc: Alexander Lobakin <aleksander.lobakin@intel.com>
>> Signed-off-by: Jon Kohler <jon@nutanix.com>
>> ---
>> drivers/net/tun.c | 39 +++++++++++++++++++++++++++------------
>> 1 file changed, 27 insertions(+), 12 deletions(-)
>> 
>> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
>> index 87fc51916fce..f7f7490e78dc 100644
>> --- a/drivers/net/tun.c
>> +++ b/drivers/net/tun.c
>> @@ -2354,12 +2354,12 @@ static int tun_xdp_one(struct tun_struct *tun,
>>       struct tun_file *tfile,
>>       struct xdp_buff *xdp, int *flush,
>>       struct tun_page *tpage,
>> -       struct bpf_prog *xdp_prog)
>> +       struct bpf_prog *xdp_prog,
>> +       struct sk_buff *skb)
>> {
>> unsigned int datasize = xdp->data_end - xdp->data;
>> struct tun_xdp_hdr *hdr = xdp->data_hard_start;
>> struct virtio_net_hdr *gso = &hdr->gso;
>> - struct sk_buff *skb = NULL;
>> struct sk_buff_head *queue;
>> u32 rxhash = 0, act;
>> int buflen = hdr->buflen;
>> @@ -2381,16 +2381,15 @@ static int tun_xdp_one(struct tun_struct *tun,
>> 
>> act = bpf_prog_run_xdp(xdp_prog, xdp);
>> ret = tun_xdp_act(tun, xdp_prog, xdp, act);
>> - if (ret < 0) {
>> - put_page(virt_to_head_page(xdp->data));
>> + if (ret < 0)
>> return ret;
>> - }
>> 
>> switch (ret) {
>> case XDP_REDIRECT:
>> *flush = true;
>> fallthrough;
>> case XDP_TX:
>> + napi_consume_skb(skb, 1);
>> return 0;
>> case XDP_PASS:
>> break;
>> @@ -2403,13 +2402,14 @@ static int tun_xdp_one(struct tun_struct *tun,
>> tpage->page = page;
>> tpage->count = 1;
>> }
>> + napi_consume_skb(skb, 1);
>> return 0;
>> }
>> }
>> 
>> build:
>> - skb = build_skb(xdp->data_hard_start, buflen);
>> - if (!skb) {
>> + skb = build_skb_around(skb, xdp->data_hard_start, buflen);
>> + if (unlikely(!skb)) {
>> ret = -ENOMEM;
>> goto out;
>> }
>> @@ -2427,7 +2427,6 @@ static int tun_xdp_one(struct tun_struct *tun,
>> 
>> if (tun_vnet_hdr_to_skb(tun->flags, skb, gso)) {
>> atomic_long_inc(&tun->rx_frame_errors);
>> - kfree_skb(skb);
>> ret = -EINVAL;
>> goto out;
>> }
>> @@ -2455,7 +2454,6 @@ static int tun_xdp_one(struct tun_struct *tun,
>> 
>> if (unlikely(tfile->detached)) {
>> spin_unlock(&queue->lock);
>> - kfree_skb(skb);
>> return -EBUSY;
>> }
>> 
>> @@ -2496,7 +2494,9 @@ static int tun_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
>> struct bpf_prog *xdp_prog;
>> struct tun_page tpage;
>> int n = ctl->num;
>> - int flush = 0, queued = 0;
>> + int flush = 0, queued = 0, num_skbs = 0;
>> + /* Max size of VHOST_NET_BATCH */
>> + void *skbs[64];
>> 
>> memset(&tpage, 0, sizeof(tpage));
>> 
>> @@ -2505,12 +2505,27 @@ static int tun_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
>> bpf_net_ctx = bpf_net_ctx_set(&__bpf_net_ctx);
>> xdp_prog = rcu_dereference(tun->xdp_prog);
>> 
>> - for (i = 0; i < n; i++) {
>> + num_skbs = napi_skb_cache_get_bulk(skbs, n);
>> +
>> + for (i = 0; i < num_skbs; i++) {
>> + struct sk_buff *skb = skbs[i];
>> xdp = &((struct xdp_buff *)ctl->ptr)[i];
>> ret = tun_xdp_one(tun, tfile, xdp, &flush, &tpage,
>> -  xdp_prog);
>> +  xdp_prog, skb);
>> if (ret > 0)
>> queued += ret;
>> + else if (ret < 0) {
>> + dev_core_stats_rx_dropped_inc(tun->dev);
>> + napi_consume_skb(skb, 1);
>> + put_page(virt_to_head_page(xdp->data));
>> + }
>> + }
>> +
>> + /* Handle remaining xdp_buff entries if num_skbs < ctl->num */
>> + for (i = num_skbs; i < ctl->num; i++) {
>> + xdp = &((struct xdp_buff *)ctl->ptr)[i];
>> + dev_core_stats_rx_dropped_inc(tun->dev);
>> + put_page(virt_to_head_page(xdp->data));
> 
> The code should attempt to send out packets rather than drop them.
> 

I took a hint from the other two places that currently do bulk SKB
allocation drop at least some of their payloads on allocation failure.
See the other call sites for napi_skb_cache_get_bulk for reference.

Also, this is similar to what the code already does today, because
if build_skb fails today, tun_xdp_one just ENOMEM’s and doesn’t go
any further.

This code is at least somewhat better than today, because this code
will increment the drop counters, vs silently dropped today.

Happy to take a pointer if there is a suggested retry mechanism of
sorts?

  reply	other threads:[~2025-05-08  3:03 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20250506145530.2877229-1-jon@nutanix.com>
2025-05-06 14:55 ` [PATCH net-next 1/4] tun: rcu_deference xdp_prog only once per batch Jon Kohler
2025-05-07 20:43   ` Willem de Bruijn
2025-05-08  3:13     ` Jon Kohler
2025-05-08 13:31       ` Willem de Bruijn
2025-05-08 13:40         ` Jon Kohler
2025-05-06 14:55 ` [PATCH net-next 2/4] tun: optimize skb allocation in tun_xdp_one Jon Kohler
2025-05-07 20:50   ` Willem de Bruijn
2025-05-08  3:02     ` Jon Kohler [this message]
2025-05-06 14:55 ` [PATCH net-next 3/4] tun: use napi_build_skb in __tun_build_skb Jon Kohler
2025-05-07 20:50   ` Willem de Bruijn
2025-05-08  3:08     ` Jon Kohler
2025-05-06 14:55 ` [PATCH net-next 4/4] tun: use napi_consume_skb in tun_do_read Jon Kohler

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=3BE7CD63-D019-415D-B711-E508663671FD@nutanix.com \
    --to=jon@nutanix.com \
    --cc=aleksander.lobakin@intel.com \
    --cc=andrew+netdev@lunn.ch \
    --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=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=willemdebruijn.kernel@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®