From patchwork Fri Sep 10 16:14:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 509073 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 59DDDC433F5 for ; Fri, 10 Sep 2021 16:15:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4396E6124F for ; Fri, 10 Sep 2021 16:15:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233554AbhIJQQK (ORCPT ); Fri, 10 Sep 2021 12:16:10 -0400 Received: from mail.kernel.org ([198.145.29.99]:41068 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231499AbhIJQQB (ORCPT ); Fri, 10 Sep 2021 12:16:01 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 1C3436124F; Fri, 10 Sep 2021 16:14:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1631290490; bh=OtXy2sqW24wC3do4Jylbo/pDS5yRSQDDAaP9eh3EpT8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IViGwvUmGqybfc98+AAD3lGVuzbiZ55g+BCND1M437Yi/K+H2BkdZvnRJgRFkN7Kk 0p9oFue3fzm/uwBdZX+iPuCWjAmTKeYQeSK2WIQZtfGtFfMyGl7pSi3OdteG7CFr1B MiShMm5Yzm2UJkLfXHgyqUpsdOyPH33USUxrFDLxYB1qtC0MmmzmvpHuxrBuJnuQSe sTFxHM5uko2y6oXQRzHsmLmqRNeo6NOb6YX3SZC5dm00+DoD/W1ukuqrqWosUB3ccj TPRD7F6kNDgilGdhgLNyHpgZQFQ/uj8LGLaMivg7x08hYXMkesfBNw43foSCiKWwxe BB6xyqEm6Z07A== From: Lorenzo Bianconi To: bpf@vger.kernel.org, netdev@vger.kernel.org Cc: lorenzo.bianconi@redhat.com, davem@davemloft.net, kuba@kernel.org, ast@kernel.org, daniel@iogearbox.net, shayagr@amazon.com, john.fastabend@gmail.com, dsahern@kernel.org, brouer@redhat.com, echaudro@redhat.com, jasowang@redhat.com, alexander.duyck@gmail.com, saeed@kernel.org, maciej.fijalkowski@intel.com, magnus.karlsson@intel.com, tirthendu.sarkar@intel.com, toke@redhat.com Subject: [PATCH v14 bpf-next 01/18] net: skbuff: add size metadata to skb_shared_info for xdp Date: Fri, 10 Sep 2021 18:14:07 +0200 Message-Id: <1a6336639c151227b263d6d621c490a8267d4119.1631289870.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Introduce xdp_frags_truesize field in skb_shared_info data structure to store xdp_buff/xdp_frame truesize (xdp_frags_truesize will be used in xdp multi-buff support). In order to not increase skb_shared_info size we will use a hole due to skb_shared_info alignment. Introduce xdp_frags_size field in skb_shared_info data structure reusing gso_type field in order to store xdp_buff/xdp_frame paged size. xdp_frags_size will be used in xdp multi-buff support. Acked-by: John Fastabend Signed-off-by: Lorenzo Bianconi Acked-by: Jesper Dangaard Brouer --- include/linux/skbuff.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 6bdb0db3e825..769ffd09f975 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -522,13 +522,17 @@ struct skb_shared_info { unsigned short gso_segs; struct sk_buff *frag_list; struct skb_shared_hwtstamps hwtstamps; - unsigned int gso_type; + union { + unsigned int gso_type; + unsigned int xdp_frags_size; + }; u32 tskey; /* * Warning : all fields before dataref are cleared in __alloc_skb() */ atomic_t dataref; + unsigned int xdp_frags_truesize; /* Intermediate layers must ensure that destructor_arg * remains valid until skb destructor */ From patchwork Fri Sep 10 16:14:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 509072 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D3CCC433FE for ; Fri, 10 Sep 2021 16:15:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 569336124C for ; Fri, 10 Sep 2021 16:15:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233751AbhIJQQ3 (ORCPT ); Fri, 10 Sep 2021 12:16:29 -0400 Received: from mail.kernel.org ([198.145.29.99]:41206 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233542AbhIJQQK (ORCPT ); Fri, 10 Sep 2021 12:16:10 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id B549561260; Fri, 10 Sep 2021 16:14:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1631290498; bh=cH33syrGBiiLDaSG/+ip0JyfjFpNMMDuSn45hv+/CD4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Gv5Tz+rf1dyx8HjBwK8P5ltS36DOu4hRYioELTPSRwVyR9Q6Z/zXbBts5IeSYuqEa O2E7kvMqLUklrspWaEkOXtt7OPIJ6jTdZbhm8lwD/+U0s+Dxr8WyZuR67pyHawZYYm hVs1AbJqiU8vuQWULKfNynL6gJ0UOiKc8eQEZ/f/4BMfwIm+CKjZE9Q32EE2SPf2xo 6fibg4VrRz6wJkHQU3lvcMfKjaWdZFHpsqP5ViMGNeVUDkS6TzBqPqdlLEGitLMWR1 qhOynqJpACu+drZIKH7408xKWOIn1yTpge3jVt8vLrvRx8W5RpOMAHlziY2x3f0coQ XlO4wKPWzk13w== From: Lorenzo Bianconi To: bpf@vger.kernel.org, netdev@vger.kernel.org Cc: lorenzo.bianconi@redhat.com, davem@davemloft.net, kuba@kernel.org, ast@kernel.org, daniel@iogearbox.net, shayagr@amazon.com, john.fastabend@gmail.com, dsahern@kernel.org, brouer@redhat.com, echaudro@redhat.com, jasowang@redhat.com, alexander.duyck@gmail.com, saeed@kernel.org, maciej.fijalkowski@intel.com, magnus.karlsson@intel.com, tirthendu.sarkar@intel.com, toke@redhat.com Subject: [PATCH v14 bpf-next 03/18] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer Date: Fri, 10 Sep 2021 18:14:09 +0200 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Update multi-buffer bit (mb) in xdp_buff to notify XDP/eBPF layer and XDP remote drivers if this is a "non-linear" XDP buffer. Access skb_shared_info only if xdp_buff mb is set in order to avoid possible cache-misses. Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/marvell/mvneta.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 9d460a270601..0c7b84ca6efc 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -2037,9 +2037,14 @@ mvneta_xdp_put_buff(struct mvneta_port *pp, struct mvneta_rx_queue *rxq, { int i; + if (likely(!xdp_buff_is_mb(xdp))) + goto out; + for (i = 0; i < sinfo->nr_frags; i++) page_pool_put_full_page(rxq->page_pool, skb_frag_page(&sinfo->frags[i]), true); + +out: page_pool_put_page(rxq->page_pool, virt_to_head_page(xdp->data), sync_len, true); } @@ -2241,7 +2246,6 @@ mvneta_swbm_rx_frame(struct mvneta_port *pp, int data_len = -MVNETA_MH_SIZE, len; struct net_device *dev = pp->dev; enum dma_data_direction dma_dir; - struct skb_shared_info *sinfo; if (*size > MVNETA_MAX_RX_BUF_SIZE) { len = MVNETA_MAX_RX_BUF_SIZE; @@ -2261,11 +2265,9 @@ mvneta_swbm_rx_frame(struct mvneta_port *pp, /* Prefetch header */ prefetch(data); + xdp_buff_clear_mb(xdp); xdp_prepare_buff(xdp, data, pp->rx_offset_correction + MVNETA_MH_SIZE, data_len, false); - - sinfo = xdp_get_shared_info_from_buff(xdp); - sinfo->nr_frags = 0; } static void @@ -2299,6 +2301,9 @@ mvneta_swbm_add_rx_fragment(struct mvneta_port *pp, skb_frag_off_set(frag, pp->rx_offset_correction); skb_frag_size_set(frag, data_len); __skb_frag_set_page(frag, page); + + if (!xdp_buff_is_mb(xdp)) + xdp_buff_set_mb(xdp); } else { page_pool_put_full_page(rxq->page_pool, page, true); } @@ -2320,8 +2325,12 @@ mvneta_swbm_build_skb(struct mvneta_port *pp, struct page_pool *pool, struct xdp_buff *xdp, u32 desc_status) { struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp); - int i, num_frags = sinfo->nr_frags; struct sk_buff *skb; + u8 num_frags; + int i; + + if (unlikely(xdp_buff_is_mb(xdp))) + num_frags = sinfo->nr_frags; skb = build_skb(xdp->data_hard_start, PAGE_SIZE); if (!skb) @@ -2333,6 +2342,9 @@ mvneta_swbm_build_skb(struct mvneta_port *pp, struct page_pool *pool, skb_put(skb, xdp->data_end - xdp->data); skb->ip_summed = mvneta_rx_csum(pp, desc_status); + if (likely(!xdp_buff_is_mb(xdp))) + goto out; + for (i = 0; i < num_frags; i++) { skb_frag_t *frag = &sinfo->frags[i]; @@ -2341,6 +2353,7 @@ mvneta_swbm_build_skb(struct mvneta_port *pp, struct page_pool *pool, skb_frag_size(frag), PAGE_SIZE); } +out: return skb; } From patchwork Fri Sep 10 16:14:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 509071 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FD00C433F5 for ; Fri, 10 Sep 2021 16:15:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 68D3E6124F for ; Fri, 10 Sep 2021 16:15:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232418AbhIJQQd (ORCPT ); Fri, 10 Sep 2021 12:16:33 -0400 Received: from mail.kernel.org ([198.145.29.99]:41378 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232711AbhIJQQS (ORCPT ); Fri, 10 Sep 2021 12:16:18 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 7143961262; Fri, 10 Sep 2021 16:15:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1631290507; bh=88ksLbDYty5fWT00WBhxxKcW43ebvyfih1gMTysaJfA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GW0bVV6pxIyQGmxd1YM9mmwIzQ14Dv1HOk/0NTmgz4Sj6GjGZZsvnsUD/oJyhITHW S7XWHsSZBkX8BfujY1IPvhXV3n73eWMHaCLsZsAwQR0sZTbGO/z+porbctpH51xvbA 3lcp22Kz73ohgehavlEvztY9RWxi/2Q6nG2QfUm5t0DFhd/Ad/Wi4KiMm1vi4qxNaV srs1dcbrauoxctyVxLrreLwhOkbj0bGm0/hvjaXwL/rviKSv3HO60eC5aZqLKIT7Yq uKjjIT+ZpqHxb8wg/AH+qBtRj9xlXGjXAhC4njsVmKJqwd9hOe2+rExvqw8S0gdJug mLaaSB4HR7jjg== From: Lorenzo Bianconi To: bpf@vger.kernel.org, netdev@vger.kernel.org Cc: lorenzo.bianconi@redhat.com, davem@davemloft.net, kuba@kernel.org, ast@kernel.org, daniel@iogearbox.net, shayagr@amazon.com, john.fastabend@gmail.com, dsahern@kernel.org, brouer@redhat.com, echaudro@redhat.com, jasowang@redhat.com, alexander.duyck@gmail.com, saeed@kernel.org, maciej.fijalkowski@intel.com, magnus.karlsson@intel.com, tirthendu.sarkar@intel.com, toke@redhat.com Subject: [PATCH v14 bpf-next 05/18] net: xdp: add xdp_update_skb_shared_info utility routine Date: Fri, 10 Sep 2021 18:14:11 +0200 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Introduce xdp_update_skb_shared_info routine to update frags array metadata in skb_shared_info data structure converting to a skb from a xdp_buff or xdp_frame. According to the current skb_shared_info architecture in xdp_frame/xdp_buff and to the xdp multi-buff support, there is no need to run skb_add_rx_frag() and reset frags array converting the buffer to a skb since the frag array will be in the same position for xdp_buff/xdp_frame and for the skb, we just need to update memory metadata. Introduce XDP_FLAGS_PF_MEMALLOC flag in xdp_buff_flags in order to mark the xdp_buff or xdp_frame as under memory-pressure if pages of the frags array are under memory pressure. Doing so we can avoid looping over all fragments in xdp_update_skb_shared_info routine. The driver is expected to set the flag constructing the xdp_buffer using xdp_buff_set_frag_pfmemalloc utility routine. Rely on xdp_update_skb_shared_info in __xdp_build_skb_from_frame routine converting the multi-buff xdp_frame to a skb after performing a XDP_REDIRECT. Acked-by: John Fastabend Acked-by: Jesper Dangaard Brouer Signed-off-by: Lorenzo Bianconi --- include/net/xdp.h | 33 ++++++++++++++++++++++++++++++++- net/core/xdp.c | 17 +++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/net/xdp.h b/include/net/xdp.h index fd31cc33aa4f..c4d68b693431 100644 --- a/include/net/xdp.h +++ b/include/net/xdp.h @@ -67,7 +67,10 @@ struct xdp_txq_info { }; enum xdp_buff_flags { - XDP_FLAGS_MULTI_BUFF = BIT(0), /* non-linear xdp buff */ + XDP_FLAGS_MULTI_BUFF = BIT(0), /* non-linear xdp buff */ + XDP_FLAGS_FRAGS_PF_MEMALLOC = BIT(1), /* xdp multi-buff paged memory + * is under pressure + */ }; struct xdp_buff { @@ -96,6 +99,16 @@ static __always_inline void xdp_buff_clear_mb(struct xdp_buff *xdp) xdp->flags &= ~XDP_FLAGS_MULTI_BUFF; } +static __always_inline bool xdp_buff_is_frag_pfmemalloc(struct xdp_buff *xdp) +{ + return !!(xdp->flags & XDP_FLAGS_FRAGS_PF_MEMALLOC); +} + +static __always_inline void xdp_buff_set_frag_pfmemalloc(struct xdp_buff *xdp) +{ + xdp->flags |= XDP_FLAGS_FRAGS_PF_MEMALLOC; +} + static __always_inline void xdp_init_buff(struct xdp_buff *xdp, u32 frame_sz, struct xdp_rxq_info *rxq) { @@ -151,6 +164,11 @@ static __always_inline bool xdp_frame_is_mb(struct xdp_frame *frame) return !!(frame->flags & XDP_FLAGS_MULTI_BUFF); } +static __always_inline bool xdp_frame_is_frag_pfmemalloc(struct xdp_frame *frame) +{ + return !!(frame->flags & XDP_FLAGS_FRAGS_PF_MEMALLOC); +} + #define XDP_BULK_QUEUE_SIZE 16 struct xdp_frame_bulk { int count; @@ -186,6 +204,19 @@ static inline void xdp_scrub_frame(struct xdp_frame *frame) frame->dev_rx = NULL; } +static inline void +xdp_update_skb_shared_info(struct sk_buff *skb, u8 nr_frags, + unsigned int size, unsigned int truesize, + bool pfmemalloc) +{ + skb_shinfo(skb)->nr_frags = nr_frags; + + skb->len += size; + skb->data_len += size; + skb->truesize += truesize; + skb->pfmemalloc |= pfmemalloc; +} + /* Avoids inlining WARN macro in fast-path */ void xdp_warn(const char *msg, const char *func, const int line); #define XDP_WARN(msg) xdp_warn(msg, __func__, __LINE__) diff --git a/net/core/xdp.c b/net/core/xdp.c index cc92ccb38432..da10b7c25054 100644 --- a/net/core/xdp.c +++ b/net/core/xdp.c @@ -531,8 +531,20 @@ struct sk_buff *__xdp_build_skb_from_frame(struct xdp_frame *xdpf, struct sk_buff *skb, struct net_device *dev) { + unsigned int frag_size, frag_truesize; unsigned int headroom, frame_size; void *hard_start; + u8 nr_frags; + + /* xdp multi-buff frame */ + if (unlikely(xdp_frame_is_mb(xdpf))) { + struct skb_shared_info *sinfo; + + sinfo = xdp_get_shared_info_from_frame(xdpf); + frag_truesize = sinfo->xdp_frags_truesize; + frag_size = sinfo->xdp_frags_size; + nr_frags = sinfo->nr_frags; + } /* Part of headroom was reserved to xdpf */ headroom = sizeof(*xdpf) + xdpf->headroom; @@ -552,6 +564,11 @@ struct sk_buff *__xdp_build_skb_from_frame(struct xdp_frame *xdpf, if (xdpf->metasize) skb_metadata_set(skb, xdpf->metasize); + if (unlikely(xdp_frame_is_mb(xdpf))) + xdp_update_skb_shared_info(skb, nr_frags, + frag_size, frag_truesize, + xdp_frame_is_frag_pfmemalloc(xdpf)); + /* Essential SKB info: protocol and skb->dev */ skb->protocol = eth_type_trans(skb, dev); From patchwork Fri Sep 10 16:14:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 509070 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6AC97C433F5 for ; Fri, 10 Sep 2021 16:15:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 53A0A6124D for ; Fri, 10 Sep 2021 16:15:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234153AbhIJQQr (ORCPT ); Fri, 10 Sep 2021 12:16:47 -0400 Received: from mail.kernel.org ([198.145.29.99]:41496 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233485AbhIJQQ0 (ORCPT ); Fri, 10 Sep 2021 12:16:26 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id B2CED61242; Fri, 10 Sep 2021 16:15:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1631290515; bh=DSKdie9nWXPOFqxMkK0xn/Af4F39LxarlVOdkxa8iYg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MT3PfAkNbZSRp0FMmeQ4Qr7JXOKkvSZZGb9ypXceMKZp1tcVhgJrOD+u5lS1ka7jx AI2A7BLAEZ5F4Di+eCcOgCwsRfotipYHFFQZvCXAw8vIVN+v9XdRIUKF43dY0gJSrr /uMLxb9LV2Za9JY0uyxsZPU0YG+Zh9TeRXAZdVj9fnyCtdKcaCtRhcatLV/C3MMBa5 xLixFf5UkV65/0dAW2cPwBvS/aQGG5DA+9Nt7LEwW9zZydoJ0MvW/Bbe7gYtGEtaXE 5XV04Afjz+IlDdwiWSLHTH7PJ7fAEbA8AE+IkvBTeRjp/8p0l8DbGbUVfneXMvyJkM hOQJDu1wez9qw== From: Lorenzo Bianconi To: bpf@vger.kernel.org, netdev@vger.kernel.org Cc: lorenzo.bianconi@redhat.com, davem@davemloft.net, kuba@kernel.org, ast@kernel.org, daniel@iogearbox.net, shayagr@amazon.com, john.fastabend@gmail.com, dsahern@kernel.org, brouer@redhat.com, echaudro@redhat.com, jasowang@redhat.com, alexander.duyck@gmail.com, saeed@kernel.org, maciej.fijalkowski@intel.com, magnus.karlsson@intel.com, tirthendu.sarkar@intel.com, toke@redhat.com Subject: [PATCH v14 bpf-next 07/18] xdp: add multi-buff support to xdp_return_{buff/frame} Date: Fri, 10 Sep 2021 18:14:13 +0200 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Take into account if the received xdp_buff/xdp_frame is non-linear recycling/returning the frame memory to the allocator or into xdp_frame_bulk. Acked-by: John Fastabend Signed-off-by: Lorenzo Bianconi --- include/net/xdp.h | 18 ++++++++++++++-- net/core/xdp.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/include/net/xdp.h b/include/net/xdp.h index c4d68b693431..e44964329fd1 100644 --- a/include/net/xdp.h +++ b/include/net/xdp.h @@ -306,10 +306,24 @@ void __xdp_release_frame(void *data, struct xdp_mem_info *mem); static inline void xdp_release_frame(struct xdp_frame *xdpf) { struct xdp_mem_info *mem = &xdpf->mem; + struct skb_shared_info *sinfo; + int i; /* Curr only page_pool needs this */ - if (mem->type == MEM_TYPE_PAGE_POOL) - __xdp_release_frame(xdpf->data, mem); + if (mem->type != MEM_TYPE_PAGE_POOL) + return; + + if (likely(!xdp_frame_is_mb(xdpf))) + goto out; + + sinfo = xdp_get_shared_info_from_frame(xdpf); + for (i = 0; i < sinfo->nr_frags; i++) { + struct page *page = skb_frag_page(&sinfo->frags[i]); + + __xdp_release_frame(page_address(page), mem); + } +out: + __xdp_release_frame(xdpf->data, mem); } int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq, diff --git a/net/core/xdp.c b/net/core/xdp.c index da10b7c25054..ffdc776a9e95 100644 --- a/net/core/xdp.c +++ b/net/core/xdp.c @@ -376,12 +376,38 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct, void xdp_return_frame(struct xdp_frame *xdpf) { + struct skb_shared_info *sinfo; + int i; + + if (likely(!xdp_frame_is_mb(xdpf))) + goto out; + + sinfo = xdp_get_shared_info_from_frame(xdpf); + for (i = 0; i < sinfo->nr_frags; i++) { + struct page *page = skb_frag_page(&sinfo->frags[i]); + + __xdp_return(page_address(page), &xdpf->mem, false, NULL); + } +out: __xdp_return(xdpf->data, &xdpf->mem, false, NULL); } EXPORT_SYMBOL_GPL(xdp_return_frame); void xdp_return_frame_rx_napi(struct xdp_frame *xdpf) { + struct skb_shared_info *sinfo; + int i; + + if (likely(!xdp_frame_is_mb(xdpf))) + goto out; + + sinfo = xdp_get_shared_info_from_frame(xdpf); + for (i = 0; i < sinfo->nr_frags; i++) { + struct page *page = skb_frag_page(&sinfo->frags[i]); + + __xdp_return(page_address(page), &xdpf->mem, true, NULL); + } +out: __xdp_return(xdpf->data, &xdpf->mem, true, NULL); } EXPORT_SYMBOL_GPL(xdp_return_frame_rx_napi); @@ -417,7 +443,7 @@ void xdp_return_frame_bulk(struct xdp_frame *xdpf, struct xdp_mem_allocator *xa; if (mem->type != MEM_TYPE_PAGE_POOL) { - __xdp_return(xdpf->data, &xdpf->mem, false, NULL); + xdp_return_frame(xdpf); return; } @@ -436,12 +462,38 @@ void xdp_return_frame_bulk(struct xdp_frame *xdpf, bq->xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); } + if (unlikely(xdp_frame_is_mb(xdpf))) { + struct skb_shared_info *sinfo; + int i; + + sinfo = xdp_get_shared_info_from_frame(xdpf); + for (i = 0; i < sinfo->nr_frags; i++) { + skb_frag_t *frag = &sinfo->frags[i]; + + bq->q[bq->count++] = skb_frag_address(frag); + if (bq->count == XDP_BULK_QUEUE_SIZE) + xdp_flush_frame_bulk(bq); + } + } bq->q[bq->count++] = xdpf->data; } EXPORT_SYMBOL_GPL(xdp_return_frame_bulk); void xdp_return_buff(struct xdp_buff *xdp) { + struct skb_shared_info *sinfo; + int i; + + if (likely(!xdp_buff_is_mb(xdp))) + goto out; + + sinfo = xdp_get_shared_info_from_buff(xdp); + for (i = 0; i < sinfo->nr_frags; i++) { + struct page *page = skb_frag_page(&sinfo->frags[i]); + + __xdp_return(page_address(page), &xdp->rxq->mem, true, xdp); + } +out: __xdp_return(xdp->data, &xdp->rxq->mem, true, xdp); } From patchwork Fri Sep 10 16:14:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 509069 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AFD9CC433F5 for ; Fri, 10 Sep 2021 16:15:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9AB236124C for ; Fri, 10 Sep 2021 16:15:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234273AbhIJQRB (ORCPT ); Fri, 10 Sep 2021 12:17:01 -0400 Received: from mail.kernel.org ([198.145.29.99]:41628 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233643AbhIJQQe (ORCPT ); Fri, 10 Sep 2021 12:16:34 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 380546124C; Fri, 10 Sep 2021 16:15:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1631290523; bh=aXRmDB4ncTQ/NPQYvglVEgPWvvmgCLc7GKzElIqoLHY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A1JjnhlYzq94Coh4K/I26fQ3XkmCQx9+/j5ZKyngV+89YEup7UujDOF99EbAnmW1X RWY2tGsWWU6/+C4wamKbc2OE1LEHlM8VsphtuEQgLutnGxwluNcrLInFLOaXkv4+yu bWAZQCAUvZ7SJ4IbHxXMS3HKx07i5aUoePJHTgFWzca9SDShLnU9gM5FZGfgVAf7QB f+9c1hAGVdlYuRd8IOoLcRGRkOhen3FeIRxI5aLuMiQqy23kFyaWAxh27oZWVgzm3S 76LilDbE0Ut8V7frFgotfP6aAHzllkweKhL9nbFlTP4mzdWeN7YzW15YkqfrZku67d M4lCx3Q8xuSNQ== From: Lorenzo Bianconi To: bpf@vger.kernel.org, netdev@vger.kernel.org Cc: lorenzo.bianconi@redhat.com, davem@davemloft.net, kuba@kernel.org, ast@kernel.org, daniel@iogearbox.net, shayagr@amazon.com, john.fastabend@gmail.com, dsahern@kernel.org, brouer@redhat.com, echaudro@redhat.com, jasowang@redhat.com, alexander.duyck@gmail.com, saeed@kernel.org, maciej.fijalkowski@intel.com, magnus.karlsson@intel.com, tirthendu.sarkar@intel.com, toke@redhat.com Subject: [PATCH v14 bpf-next 09/18] net: mvneta: enable jumbo frames for XDP Date: Fri, 10 Sep 2021 18:14:15 +0200 Message-Id: <2f1ec618b25765df7f4dee97a2ccf63a8133fd4d.1631289870.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Enable the capability to receive jumbo frames even if the interface is running in XDP mode Acked-by: John Fastabend Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/marvell/mvneta.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 25f63f9efdf0..f7a39cfb0f1a 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -3767,11 +3767,6 @@ static int mvneta_change_mtu(struct net_device *dev, int mtu) mtu = ALIGN(MVNETA_RX_PKT_SIZE(mtu), 8); } - if (pp->xdp_prog && mtu > MVNETA_MAX_RX_BUF_SIZE) { - netdev_info(dev, "Illegal MTU value %d for XDP mode\n", mtu); - return -EINVAL; - } - dev->mtu = mtu; if (!netif_running(dev)) { @@ -4481,11 +4476,6 @@ static int mvneta_xdp_setup(struct net_device *dev, struct bpf_prog *prog, struct mvneta_port *pp = netdev_priv(dev); struct bpf_prog *old_prog; - if (prog && dev->mtu > MVNETA_MAX_RX_BUF_SIZE) { - NL_SET_ERR_MSG_MOD(extack, "MTU too large for XDP"); - return -EOPNOTSUPP; - } - if (pp->bm_priv) { NL_SET_ERR_MSG_MOD(extack, "Hardware Buffer Management not supported on XDP"); From patchwork Fri Sep 10 16:14:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 509068 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA9AAC433EF for ; Fri, 10 Sep 2021 16:16:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8F3DD6124D for ; Fri, 10 Sep 2021 16:16:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234356AbhIJQRK (ORCPT ); Fri, 10 Sep 2021 12:17:10 -0400 Received: from mail.kernel.org ([198.145.29.99]:41700 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233936AbhIJQQm (ORCPT ); Fri, 10 Sep 2021 12:16:42 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id ADE3E61262; Fri, 10 Sep 2021 16:15:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1631290530; bh=TtT9lfm2SQG+xo6m+8GUVzq9pbrd5KPuXQdmBrg35Aw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vNp8RXByJgiHjBIeHwgeoQZRr33KVeANbqN3Km8jQ/dT7+B36c545AwCSHp9EJEKK VMgkrT8Ro8+367AAjpa9h8MzjvLTNT+3LJMbwChkszHuuym6H9HqayujP/aulI37E1 g8hiFsYAjtiaTWOmhRW2PR+F74jDHi34oaMbMjr7vZeGH4iLgF9/jq+NSPlRVAvaMq 7D7oCXOy16EQJ0We+U1gGpogwpsVeTzHiarRY9PhERW1AVZSCRprM3jWFt1FYiT7bf ZfPhrJFk6fsqyuzNS0n+8fnjAFTy6Upnjvp8e3ayTjBpG0or0MF1gR214wOTV2nv0J fLNBSJJ+ElYIQ== From: Lorenzo Bianconi To: bpf@vger.kernel.org, netdev@vger.kernel.org Cc: lorenzo.bianconi@redhat.com, davem@davemloft.net, kuba@kernel.org, ast@kernel.org, daniel@iogearbox.net, shayagr@amazon.com, john.fastabend@gmail.com, dsahern@kernel.org, brouer@redhat.com, echaudro@redhat.com, jasowang@redhat.com, alexander.duyck@gmail.com, saeed@kernel.org, maciej.fijalkowski@intel.com, magnus.karlsson@intel.com, tirthendu.sarkar@intel.com, toke@redhat.com Subject: [PATCH v14 bpf-next 11/18] bpf: introduce bpf_xdp_get_buff_len helper Date: Fri, 10 Sep 2021 18:14:17 +0200 Message-Id: <5dd10bffff5db6808c51ba971c618ea4c4631ac3.1631289870.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Introduce bpf_xdp_get_buff_len helper in order to return the xdp buffer total size (linear and paged area) Acked-by: John Fastabend Signed-off-by: Lorenzo Bianconi --- include/uapi/linux/bpf.h | 7 +++++++ net/core/filter.c | 23 +++++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 7 +++++++ 3 files changed, 37 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 791f31dd0abe..1fd87bd5848b 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -4877,6 +4877,12 @@ union bpf_attr { * Get the struct pt_regs associated with **task**. * Return * A pointer to struct pt_regs. + * + * u64 bpf_xdp_get_buff_len(struct xdp_buff *xdp_md) + * Description + * Get the total size of a given xdp buff (linear and paged area) + * Return + * The total size of a given xdp buffer. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -5055,6 +5061,7 @@ union bpf_attr { FN(get_func_ip), \ FN(get_attach_cookie), \ FN(task_pt_regs), \ + FN(xdp_get_buff_len), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/net/core/filter.c b/net/core/filter.c index 49feba8f8966..d4982a20c8bd 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3784,6 +3784,27 @@ static const struct bpf_func_proto sk_skb_change_head_proto = { .arg2_type = ARG_ANYTHING, .arg3_type = ARG_ANYTHING, }; + +BPF_CALL_1(bpf_xdp_get_buff_len, struct xdp_buff*, xdp) +{ + u64 len = xdp->data_end - xdp->data; + + if (unlikely(xdp_buff_is_mb(xdp))) { + struct skb_shared_info *sinfo; + + sinfo = xdp_get_shared_info_from_buff(xdp); + len += sinfo->xdp_frags_size; + } + return len; +} + +static const struct bpf_func_proto bpf_xdp_get_buff_len_proto = { + .func = bpf_xdp_get_buff_len, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, +}; + static unsigned long xdp_get_metalen(const struct xdp_buff *xdp) { return xdp_data_meta_unsupported(xdp) ? 0 : @@ -7531,6 +7552,8 @@ xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_xdp_redirect_map_proto; case BPF_FUNC_xdp_adjust_tail: return &bpf_xdp_adjust_tail_proto; + case BPF_FUNC_xdp_get_buff_len: + return &bpf_xdp_get_buff_len_proto; case BPF_FUNC_fib_lookup: return &bpf_xdp_fib_lookup_proto; case BPF_FUNC_check_mtu: diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 791f31dd0abe..1fd87bd5848b 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -4877,6 +4877,12 @@ union bpf_attr { * Get the struct pt_regs associated with **task**. * Return * A pointer to struct pt_regs. + * + * u64 bpf_xdp_get_buff_len(struct xdp_buff *xdp_md) + * Description + * Get the total size of a given xdp buff (linear and paged area) + * Return + * The total size of a given xdp buffer. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -5055,6 +5061,7 @@ union bpf_attr { FN(get_func_ip), \ FN(get_attach_cookie), \ FN(task_pt_regs), \ + FN(xdp_get_buff_len), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper From patchwork Fri Sep 10 16:14:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 509067 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9690FC433EF for ; Fri, 10 Sep 2021 16:16:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7A9166124C for ; Fri, 10 Sep 2021 16:16:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233352AbhIJQRR (ORCPT ); Fri, 10 Sep 2021 12:17:17 -0400 Received: from mail.kernel.org ([198.145.29.99]:41378 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233542AbhIJQQt (ORCPT ); Fri, 10 Sep 2021 12:16:49 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 67DBF61251; Fri, 10 Sep 2021 16:15:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1631290538; bh=jXRJohW49aOvCJRKXGIZOWo0KIPLrWPndf9PLtC2uik=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BLZ+VFpnDIf2Mrr4mq6potALSbeZBftwAcohuIp9MHUox8zyxpzDAT9yO3AgqjDRr a1AbCszC2zsNgqU9IVjfB9Pq7zt011Q4wzV8WzwpsL9sL7nrxbhQUVNwnRpQdrnRsn vnlIQ1wARwpm9jz33s0ep9kkNQR2+ORkuqmJt5Gc0gnJsO4yeUdnbC9Hx4Fh4JJ6so 1GvLOiTCajUb9qLulBhYas1bcNRwQhQkpjznNQJLK9+mzTUaCk69i/9tXKR97gDdEx Onl7Fx7OH2g5bm+t4r3bz+k/+wn8epaTKC7y1xx6zCGs1PVsi8p/0O4v0V3h5oj2VS zb9sXfbZ8MZVw== From: Lorenzo Bianconi To: bpf@vger.kernel.org, netdev@vger.kernel.org Cc: lorenzo.bianconi@redhat.com, davem@davemloft.net, kuba@kernel.org, ast@kernel.org, daniel@iogearbox.net, shayagr@amazon.com, john.fastabend@gmail.com, dsahern@kernel.org, brouer@redhat.com, echaudro@redhat.com, jasowang@redhat.com, alexander.duyck@gmail.com, saeed@kernel.org, maciej.fijalkowski@intel.com, magnus.karlsson@intel.com, tirthendu.sarkar@intel.com, toke@redhat.com Subject: [PATCH v14 bpf-next 13/18] bpf: move user_size out of bpf_test_init Date: Fri, 10 Sep 2021 18:14:19 +0200 Message-Id: <868c7ba063d5d1a2da4dc572643c3ad1acb47f3b.1631289870.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Rely on data_size_in in bpf_test_init routine signature. This is a preliminary patch to introduce xdp multi-buff selftest Signed-off-by: Lorenzo Bianconi --- net/bpf/test_run.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 1153b89c9d93..82b34632a66c 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -246,11 +246,10 @@ bool bpf_prog_test_check_kfunc_call(u32 kfunc_id) return btf_id_set_contains(&test_sk_kfunc_ids, kfunc_id); } -static void *bpf_test_init(const union bpf_attr *kattr, u32 size, - u32 headroom, u32 tailroom) +static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size, + u32 size, u32 headroom, u32 tailroom) { void __user *data_in = u64_to_user_ptr(kattr->test.data_in); - u32 user_size = kattr->test.data_size_in; void *data; if (size < ETH_HLEN || size > PAGE_SIZE - headroom - tailroom) @@ -569,7 +568,8 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, if (kattr->test.flags || kattr->test.cpu) return -EINVAL; - data = bpf_test_init(kattr, size, NET_SKB_PAD + NET_IP_ALIGN, + data = bpf_test_init(kattr, kattr->test.data_size_in, + size, NET_SKB_PAD + NET_IP_ALIGN, SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); if (IS_ERR(data)) return PTR_ERR(data); @@ -780,7 +780,8 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, /* XDP have extra tailroom as (most) drivers use full page */ max_data_sz = 4096 - headroom - tailroom; - data = bpf_test_init(kattr, max_data_sz, headroom, tailroom); + data = bpf_test_init(kattr, kattr->test.data_size_in, + max_data_sz, headroom, tailroom); if (IS_ERR(data)) { ret = PTR_ERR(data); goto free_ctx; @@ -864,7 +865,7 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, if (size < ETH_HLEN) return -EINVAL; - data = bpf_test_init(kattr, size, 0, 0); + data = bpf_test_init(kattr, kattr->test.data_size_in, size, 0, 0); if (IS_ERR(data)) return PTR_ERR(data); From patchwork Fri Sep 10 16:14:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 509066 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ADCE7C43219 for ; Fri, 10 Sep 2021 16:16:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9BCFD61242 for ; Fri, 10 Sep 2021 16:16:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229501AbhIJQRa (ORCPT ); Fri, 10 Sep 2021 12:17:30 -0400 Received: from mail.kernel.org ([198.145.29.99]:41944 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234247AbhIJQQ6 (ORCPT ); Fri, 10 Sep 2021 12:16:58 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 0D8756127B; Fri, 10 Sep 2021 16:15:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1631290546; bh=fDNYIV5E1sKfiE8E6spTtCAoKNSawHF37x4hVlB4UFA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bKj8ayDIL4DkQ2KYYQGTtzUt4CAySRGfxWFpEZr2utXK6GnuiqO3R70mtzoQTozqR I1zlLWVjXGrXZB2MQFopRXYPY5q5BYv9pwlQo9gwnd6e7nZ6PAJ3W89YtjRF6LfjaP PgLStSCJ+aRfUeG1Vx/hzebAWpjob0yXCesgnNcGV19cxlqBylu/5KLXyUnsi2NUbf pzviGf8nnniucLTs4mc0pKKE4bFJcA/BfHTmW79oT/hKQnDE/kSNszZt4TMyfZkYVz kfJw+cURC157JRPTrvJCoRdmB4JCQV8PvsT8DmheUfcXxW++w6XHPkp4dIxw3XhB9Z /GzM/2nCF+4Zg== From: Lorenzo Bianconi To: bpf@vger.kernel.org, netdev@vger.kernel.org Cc: lorenzo.bianconi@redhat.com, davem@davemloft.net, kuba@kernel.org, ast@kernel.org, daniel@iogearbox.net, shayagr@amazon.com, john.fastabend@gmail.com, dsahern@kernel.org, brouer@redhat.com, echaudro@redhat.com, jasowang@redhat.com, alexander.duyck@gmail.com, saeed@kernel.org, maciej.fijalkowski@intel.com, magnus.karlsson@intel.com, tirthendu.sarkar@intel.com, toke@redhat.com Subject: [PATCH v14 bpf-next 15/18] bpf: test_run: add xdp_shared_info pointer in bpf_test_finish signature Date: Fri, 10 Sep 2021 18:14:21 +0200 Message-Id: <967200325708dba328ed097f7e3ce52ecbd6525d.1631289870.git.lorenzo@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org introduce xdp_shared_info pointer in bpf_test_finish signature in order to copy back paged data from a xdp multi-buff frame to userspace buffer Signed-off-by: Lorenzo Bianconi --- net/bpf/test_run.c | 48 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index d4200dc63f5f..4f5c28c4f888 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -129,7 +129,8 @@ static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat, static int bpf_test_finish(const union bpf_attr *kattr, union bpf_attr __user *uattr, const void *data, - u32 size, u32 retval, u32 duration) + struct skb_shared_info *sinfo, u32 size, + u32 retval, u32 duration) { void __user *data_out = u64_to_user_ptr(kattr->test.data_out); int err = -EFAULT; @@ -144,8 +145,36 @@ static int bpf_test_finish(const union bpf_attr *kattr, err = -ENOSPC; } - if (data_out && copy_to_user(data_out, data, copy_size)) - goto out; + if (data_out) { + int len = sinfo ? copy_size - sinfo->xdp_frags_size : copy_size; + + if (copy_to_user(data_out, data, len)) + goto out; + + if (sinfo) { + int i, offset = len, data_len; + + for (i = 0; i < sinfo->nr_frags; i++) { + skb_frag_t *frag = &sinfo->frags[i]; + + if (offset >= copy_size) { + err = -ENOSPC; + break; + } + + data_len = min_t(int, copy_size - offset, + skb_frag_size(frag)); + + if (copy_to_user(data_out + offset, + skb_frag_address(frag), + data_len)) + goto out; + + offset += data_len; + } + } + } + if (copy_to_user(&uattr->test.data_size_out, &size, sizeof(size))) goto out; if (copy_to_user(&uattr->test.retval, &retval, sizeof(retval))) @@ -672,7 +701,8 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, /* bpf program can never convert linear skb to non-linear */ if (WARN_ON_ONCE(skb_is_nonlinear(skb))) size = skb_headlen(skb); - ret = bpf_test_finish(kattr, uattr, skb->data, size, retval, duration); + ret = bpf_test_finish(kattr, uattr, skb->data, NULL, size, retval, + duration); if (!ret) ret = bpf_ctx_finish(kattr, uattr, ctx, sizeof(struct __sk_buff)); @@ -840,8 +870,8 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, goto out; size = xdp.data_end - xdp.data_meta + sinfo->xdp_frags_size; - ret = bpf_test_finish(kattr, uattr, xdp.data_meta, size, retval, - duration); + ret = bpf_test_finish(kattr, uattr, xdp.data_meta, sinfo, size, + retval, duration); if (!ret) ret = bpf_ctx_finish(kattr, uattr, ctx, sizeof(struct xdp_md)); @@ -932,8 +962,8 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, if (ret < 0) goto out; - ret = bpf_test_finish(kattr, uattr, &flow_keys, sizeof(flow_keys), - retval, duration); + ret = bpf_test_finish(kattr, uattr, &flow_keys, NULL, + sizeof(flow_keys), retval, duration); if (!ret) ret = bpf_ctx_finish(kattr, uattr, user_ctx, sizeof(struct bpf_flow_keys)); @@ -1037,7 +1067,7 @@ int bpf_prog_test_run_sk_lookup(struct bpf_prog *prog, const union bpf_attr *kat user_ctx->cookie = sock_gen_cookie(ctx.selected_sk); } - ret = bpf_test_finish(kattr, uattr, NULL, 0, retval, duration); + ret = bpf_test_finish(kattr, uattr, NULL, NULL, 0, retval, duration); if (!ret) ret = bpf_ctx_finish(kattr, uattr, user_ctx, sizeof(*user_ctx)); From patchwork Fri Sep 10 16:14:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 509065 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5B6BC433EF for ; Fri, 10 Sep 2021 16:16:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 89977611C7 for ; Fri, 10 Sep 2021 16:16:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234323AbhIJQRr (ORCPT ); Fri, 10 Sep 2021 12:17:47 -0400 Received: from mail.kernel.org ([198.145.29.99]:42072 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233912AbhIJQRE (ORCPT ); Fri, 10 Sep 2021 12:17:04 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 4EE2161268; Fri, 10 Sep 2021 16:15:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1631290553; bh=KkKZj2r+XqWmCjVeMcigXefsw07qvS/Oo0LaqmXlZ+s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aS2mdFSc8jKT1GBvw0sTZpE8e0UMurdj235AhTCbb20TPHiKKw2mqXNcBHV/MMYuQ EK2dbUj1bP7+Iy2s9MC6zzNqUEg9LZqL3+23OBjwR7Bf3xQclHJLYyi1mKYuF6cSfy x/YeTW6csheX/fzOxLahkPUnwfiff2drTfSHF6y+XddPjakYGyf3XuSh9AnX5bLwyG 3IIieydZ04tkNmjsqPbBx4xDxmDu1rXSSbflK4c7CYpZobqc+kxQmrf/G+JSJ8EoVd /O68OACS9Rx3c3ghlp5C2wBhAtMaW9g3IQObCPIdpY6PkrRlcuqgqgYxfHdTG2TMey 1TMzqKo779eng== From: Lorenzo Bianconi To: bpf@vger.kernel.org, netdev@vger.kernel.org Cc: lorenzo.bianconi@redhat.com, davem@davemloft.net, kuba@kernel.org, ast@kernel.org, daniel@iogearbox.net, shayagr@amazon.com, john.fastabend@gmail.com, dsahern@kernel.org, brouer@redhat.com, echaudro@redhat.com, jasowang@redhat.com, alexander.duyck@gmail.com, saeed@kernel.org, maciej.fijalkowski@intel.com, magnus.karlsson@intel.com, tirthendu.sarkar@intel.com, toke@redhat.com Subject: [PATCH v14 bpf-next 17/18] net: xdp: introduce bpf_xdp_adjust_data helper Date: Fri, 10 Sep 2021 18:14:23 +0200 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org For XDP frames split over multiple buffers, the xdp_md->data and xdp_md->data_end pointers will point to the start and end of the first fragment only. bpf_xdp_adjust_data can be used to access subsequent fragments by moving the data pointers. To use, an XDP program can call this helper with the byte offset of the packet payload that it wants to access; the helper will move xdp_md->data and xdp_md ->data_end so they point to the requested payload offset and to the end of the fragment containing this byte offset, and return the byte offset of the start of the fragment. To move back to the beginning of the packet, simply call the helper with an offset of '0'. Note also that the helpers that modify the packet boundaries (bpf_xdp_adjust_head(), bpf_xdp_adjust_tail() and bpf_xdp_adjust_meta()) will fail if the pointers have been moved; it is the responsibility of the BPF program to move them back before using these helpers. Suggested-by: John Fastabend Signed-off-by: Lorenzo Bianconi --- include/net/xdp.h | 8 +++++ include/uapi/linux/bpf.h | 32 +++++++++++++++++ net/bpf/test_run.c | 8 +++++ net/core/filter.c | 65 +++++++++++++++++++++++++++++++++- tools/include/uapi/linux/bpf.h | 32 +++++++++++++++++ 5 files changed, 144 insertions(+), 1 deletion(-) diff --git a/include/net/xdp.h b/include/net/xdp.h index 789251e464de..9d8f4c1dc8e0 100644 --- a/include/net/xdp.h +++ b/include/net/xdp.h @@ -82,6 +82,11 @@ struct xdp_buff { struct xdp_txq_info *txq; u32 frame_sz; /* frame size to deduce data_hard_end/reserved tailroom*/ u32 flags; /* supported values defined in xdp_buff_flags */ + /* xdp multi-buff metadata used for frags iteration */ + struct { + u16 headroom; /* frame headroom: data - data_hard_start */ + u16 headlen; /* first buffer length: data_end - data */ + } mb; }; static __always_inline bool xdp_buff_is_mb(struct xdp_buff *xdp) @@ -127,6 +132,9 @@ xdp_prepare_buff(struct xdp_buff *xdp, unsigned char *hard_start, xdp->data = data; xdp->data_end = data + data_len; xdp->data_meta = meta_valid ? data : data + 1; + /* mb metadata for frags iteration */ + xdp->mb.headroom = headroom; + xdp->mb.headlen = data_len; } /* Reserve memory area at end-of data area. diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 1fd87bd5848b..4f56ba0fd1dd 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -4883,6 +4883,37 @@ union bpf_attr { * Get the total size of a given xdp buff (linear and paged area) * Return * The total size of a given xdp buffer. + * + * long bpf_xdp_adjust_data(struct xdp_buff *xdp_md, u32 offset) + * Description + * For XDP frames split over multiple buffers, the + * *xdp_md*\ **->data** and *xdp_md *\ **->data_end** pointers + * will point to the start and end of the first fragment only. + * This helper can be used to access subsequent fragments by + * moving the data pointers. To use, an XDP program can call + * this helper with the byte offset of the packet payload that + * it wants to access; the helper will move *xdp_md*\ **->data** + * and *xdp_md *\ **->data_end** so they point to the requested + * payload offset and to the end of the fragment containing this + * byte offset, and return the byte offset of the start of the + * fragment. + * To move back to the beginning of the packet, simply call the + * helper with an offset of '0'. + * Note also that the helpers that modify the packet boundaries + * (*bpf_xdp_adjust_head()*, *bpf_xdp_adjust_tail()* and + * *bpf_xdp_adjust_meta()*) will fail if the pointers have been + * moved; it is the responsibility of the BPF program to move them + * back before using these helpers. + * + * A call to this helper is susceptible to change the underlying + * packet buffer. Therefore, at load time, all checks on pointers + * previously done by the verifier are invalidated and must be + * performed again, if the helper is used in combination with + * direct packet access. + * Return + * offset between the beginning of the current fragment and + * original *xdp_md*\ **->data** on success, or a negative error + * in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -5062,6 +5093,7 @@ union bpf_attr { FN(get_attach_cookie), \ FN(task_pt_regs), \ FN(xdp_get_buff_len), \ + FN(xdp_adjust_data), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 4f5c28c4f888..9e6f156e6c24 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -755,6 +755,8 @@ static int xdp_convert_md_to_buff(struct xdp_md *xdp_md, struct xdp_buff *xdp) } xdp->data = xdp->data_meta + xdp_md->data; + xdp->mb.headroom = xdp->data - xdp->data_hard_start; + xdp->mb.headlen = xdp->data_end - xdp->data; return 0; free_dev: @@ -869,6 +871,12 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, if (ret) goto out; + /* data pointers need to be reset after frag iteration */ + if (unlikely(xdp.data_hard_start + xdp.mb.headroom != xdp.data)) { + ret = -EFAULT; + goto out; + } + size = xdp.data_end - xdp.data_meta + sinfo->xdp_frags_size; ret = bpf_test_finish(kattr, uattr, xdp.data_meta, sinfo, size, retval, duration); diff --git a/net/core/filter.c b/net/core/filter.c index e1dc86f0930f..6111e95b50df 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3827,6 +3827,10 @@ BPF_CALL_2(bpf_xdp_adjust_head, struct xdp_buff *, xdp, int, offset) void *data_start = xdp_frame_end + metalen; void *data = xdp->data + offset; + /* data pointers need to be reset after frag iteration */ + if (unlikely(xdp->data_hard_start + xdp->mb.headroom != xdp->data)) + return -EFAULT; + if (unlikely(data < data_start || data > xdp->data_end - ETH_HLEN)) return -EINVAL; @@ -3836,6 +3840,9 @@ BPF_CALL_2(bpf_xdp_adjust_head, struct xdp_buff *, xdp, int, offset) xdp->data_meta, metalen); xdp->data_meta += offset; xdp->data = data; + /* update metada for multi-buff frag iteration */ + xdp->mb.headroom = xdp->data - xdp->data_hard_start; + xdp->mb.headlen = xdp->data_end - xdp->data; return 0; } @@ -3910,6 +3917,10 @@ BPF_CALL_2(bpf_xdp_adjust_tail, struct xdp_buff *, xdp, int, offset) void *data_hard_end = xdp_data_hard_end(xdp); /* use xdp->frame_sz */ void *data_end = xdp->data_end + offset; + /* data pointer needs to be reset after frag iteration */ + if (unlikely(xdp->data + xdp->mb.headlen != xdp->data_end)) + return -EFAULT; + if (unlikely(xdp_buff_is_mb(xdp))) return bpf_xdp_mb_adjust_tail(xdp, offset); @@ -3949,6 +3960,10 @@ BPF_CALL_2(bpf_xdp_adjust_meta, struct xdp_buff *, xdp, int, offset) void *meta = xdp->data_meta + offset; unsigned long metalen = xdp->data - meta; + /* data pointer needs to be reset after frag iteration */ + if (unlikely(xdp->data_hard_start + xdp->mb.headroom != xdp->data)) + return -EFAULT; + if (xdp_data_meta_unsupported(xdp)) return -ENOTSUPP; if (unlikely(meta < xdp_frame_end || @@ -3970,6 +3985,51 @@ static const struct bpf_func_proto bpf_xdp_adjust_meta_proto = { .arg2_type = ARG_ANYTHING, }; +BPF_CALL_2(bpf_xdp_adjust_data, struct xdp_buff *, xdp, u32, offset) +{ + struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp); + u32 base_offset = xdp->mb.headlen, max_offset = xdp->mb.headlen; + int i; + + if (xdp_buff_is_mb(xdp)) + max_offset += sinfo->xdp_frags_size; + + if (offset > max_offset) + return -EINVAL; + + if (offset < xdp->mb.headlen) { + /* linear area */ + xdp->data = xdp->data_hard_start + xdp->mb.headroom + offset; + xdp->data_end = xdp->data_hard_start + xdp->mb.headroom + + xdp->mb.headlen; + return 0; + } + + for (i = 0; i < sinfo->nr_frags; i++) { + /* paged area */ + skb_frag_t *frag = &sinfo->frags[i]; + unsigned int size = skb_frag_size(frag); + + if (offset < base_offset + size) { + u8 *addr = skb_frag_address(frag); + + xdp->data = addr + offset - base_offset; + xdp->data_end = addr + size; + break; + } + base_offset += size; + } + return base_offset; +} + +static const struct bpf_func_proto bpf_xdp_adjust_data_proto = { + .func = bpf_xdp_adjust_data, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + /* XDP_REDIRECT works by a three-step process, implemented in the functions * below: * @@ -7261,7 +7321,8 @@ bool bpf_helper_changes_pkt_data(void *func) func == bpf_sock_ops_store_hdr_opt || #endif func == bpf_lwt_in_push_encap || - func == bpf_lwt_xmit_push_encap) + func == bpf_lwt_xmit_push_encap || + func == bpf_xdp_adjust_data) return true; return false; @@ -7614,6 +7675,8 @@ xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_xdp_adjust_tail_proto; case BPF_FUNC_xdp_get_buff_len: return &bpf_xdp_get_buff_len_proto; + case BPF_FUNC_xdp_adjust_data: + return &bpf_xdp_adjust_data_proto; case BPF_FUNC_fib_lookup: return &bpf_xdp_fib_lookup_proto; case BPF_FUNC_check_mtu: diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 1fd87bd5848b..4f56ba0fd1dd 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -4883,6 +4883,37 @@ union bpf_attr { * Get the total size of a given xdp buff (linear and paged area) * Return * The total size of a given xdp buffer. + * + * long bpf_xdp_adjust_data(struct xdp_buff *xdp_md, u32 offset) + * Description + * For XDP frames split over multiple buffers, the + * *xdp_md*\ **->data** and *xdp_md *\ **->data_end** pointers + * will point to the start and end of the first fragment only. + * This helper can be used to access subsequent fragments by + * moving the data pointers. To use, an XDP program can call + * this helper with the byte offset of the packet payload that + * it wants to access; the helper will move *xdp_md*\ **->data** + * and *xdp_md *\ **->data_end** so they point to the requested + * payload offset and to the end of the fragment containing this + * byte offset, and return the byte offset of the start of the + * fragment. + * To move back to the beginning of the packet, simply call the + * helper with an offset of '0'. + * Note also that the helpers that modify the packet boundaries + * (*bpf_xdp_adjust_head()*, *bpf_xdp_adjust_tail()* and + * *bpf_xdp_adjust_meta()*) will fail if the pointers have been + * moved; it is the responsibility of the BPF program to move them + * back before using these helpers. + * + * A call to this helper is susceptible to change the underlying + * packet buffer. Therefore, at load time, all checks on pointers + * previously done by the verifier are invalidated and must be + * performed again, if the helper is used in combination with + * direct packet access. + * Return + * offset between the beginning of the current fragment and + * original *xdp_md*\ **->data** on success, or a negative error + * in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -5062,6 +5093,7 @@ union bpf_attr { FN(get_attach_cookie), \ FN(task_pt_regs), \ FN(xdp_get_buff_len), \ + FN(xdp_adjust_data), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper