netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
To: Alexander Lobakin <aleksander.lobakin@intel.com>
Cc: "David S. Miller" <davem@davemloft.net>,
	"Eric Dumazet" <edumazet@google.com>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Paolo Abeni" <pabeni@redhat.com>,
	"Toke Høiland-Jørgensen" <toke@redhat.com>,
	"Alexei Starovoitov" <ast@kernel.org>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	"John Fastabend" <john.fastabend@gmail.com>,
	"Andrii Nakryiko" <andrii@kernel.org>,
	"Stanislav Fomichev" <sdf@fomichev.me>,
	"Magnus Karlsson" <magnus.karlsson@intel.com>,
	nex.sw.ncis.osdt.itp.upstreaming@intel.com, bpf@vger.kernel.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next v2 16/18] xsk: add helper to get &xdp_desc's DMA and meta pointer in one go
Date: Tue, 22 Oct 2024 17:42:13 +0200	[thread overview]
Message-ID: <ZxfH1VmjcVdLeKUo@boxer> (raw)
In-Reply-To: <20241015145350.4077765-17-aleksander.lobakin@intel.com>

On Tue, Oct 15, 2024 at 04:53:48PM +0200, Alexander Lobakin wrote:
> Currently, when you send an XSk frame without metadata, you need to do

you meant *with* metadata?

> the following:
> 
> * call external xsk_buff_raw_get_dma();
> * call inline xsk_buff_get_metadata(), which calls external
>   xsk_buff_raw_get_data() and then do some inline checks.
> 
> This effectively means that the following piece:
> 
> addr = pool->unaligned ? xp_unaligned_add_offset_to_addr(addr) : addr;
> 
> is done twice per frame, plus you have 2 external calls per frame, plus
> this:
> 
> 	meta = pool->addrs + addr - pool->tx_metadata_len;
> 	if (unlikely(!xsk_buff_valid_tx_metadata(meta)))
> 
> is always inlined, even if there's no meta or it's invalid.

when there is no meta you bail out early in xsk_buff_get_metadata() as
tx_metadata_len was not set, no?

> 
> Add xsk_buff_raw_get_ctx() (xp_raw_get_ctx() to be precise) to do that
> in one go. It returns a small structure with 2 fields: DMA address,
> filled unconditionally, and metadata pointer, valid only if it's
> present. The address correction is performed only once and you also
> have only 1 external call per XSk frame, which does all the calculations
> and checks outside of your hotpath. You only need to check
> `if (ctx.meta)` for the metadata presence.

IMHO adding this might confuse future users which approach should be
preferred.

Thinking out loud...couldn't we export address correction logic and pass
the corrected addr to xsk_buff_get_metadata and then add it to
pool->addrs. But that would require modifying existing callsites +
addressing xp_raw_get_dma() as well :<

Standard question - any perf improvement when micro benchmarking? :P

> 
> Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
> ---
>  include/net/xdp_sock_drv.h  | 23 +++++++++++++++++++++
>  include/net/xsk_buff_pool.h |  8 ++++++++
>  net/xdp/xsk_buff_pool.c     | 40 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 71 insertions(+)
> 
> diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h
> index 6aae95b83645..324a4bb04431 100644
> --- a/include/net/xdp_sock_drv.h
> +++ b/include/net/xdp_sock_drv.h
> @@ -205,6 +205,23 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr)
>  	return xp_raw_get_data(pool, addr);
>  }
>  
> +/**
> + * xsk_buff_raw_get_ctx - get &xdp_desc context
> + * @pool: XSk buff pool desc address belongs to
> + * @addr: desc address (from userspace)
> + *
> + * Wrapper for xp_raw_get_ctx() to be used in drivers, see its kdoc for
> + * details.
> + *
> + * Return: new &xdp_desc_ctx struct containing desc's DMA address and metadata
> + * pointer, if it is present and valid (initialized to %NULL otherwise).
> + */
> +static inline struct xdp_desc_ctx
> +xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)
> +{
> +	return xp_raw_get_ctx(pool, addr);
> +}
> +
>  #define XDP_TXMD_FLAGS_VALID ( \
>  		XDP_TXMD_FLAGS_TIMESTAMP | \
>  		XDP_TXMD_FLAGS_CHECKSUM | \
> @@ -402,6 +419,12 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr)
>  	return NULL;
>  }
>  
> +static inline struct xdp_desc_ctx
> +xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)
> +{
> +	return (struct xdp_desc_ctx){ };
> +}
> +
>  static inline bool xsk_buff_valid_tx_metadata(struct xsk_tx_metadata *meta)
>  {
>  	return false;
> diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
> index 3832997cc605..6c540696a299 100644
> --- a/include/net/xsk_buff_pool.h
> +++ b/include/net/xsk_buff_pool.h
> @@ -141,6 +141,14 @@ u32 xp_alloc_batch(struct xsk_buff_pool *pool, struct xdp_buff **xdp, u32 max);
>  bool xp_can_alloc(struct xsk_buff_pool *pool, u32 count);
>  void *xp_raw_get_data(struct xsk_buff_pool *pool, u64 addr);
>  dma_addr_t xp_raw_get_dma(struct xsk_buff_pool *pool, u64 addr);
> +
> +struct xdp_desc_ctx {
> +	dma_addr_t dma;
> +	struct xsk_tx_metadata *meta;
> +};
> +
> +struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr);
> +
>  static inline dma_addr_t xp_get_dma(struct xdp_buff_xsk *xskb)
>  {
>  	return xskb->dma;
> diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
> index ae71da7d2cd6..02c42caec9f4 100644
> --- a/net/xdp/xsk_buff_pool.c
> +++ b/net/xdp/xsk_buff_pool.c
> @@ -715,3 +715,43 @@ dma_addr_t xp_raw_get_dma(struct xsk_buff_pool *pool, u64 addr)
>  		(addr & ~PAGE_MASK);
>  }
>  EXPORT_SYMBOL(xp_raw_get_dma);
> +
> +/**
> + * xp_raw_get_ctx - get &xdp_desc context
> + * @pool: XSk buff pool desc address belongs to
> + * @addr: desc address (from userspace)
> + *
> + * Helper for getting desc's DMA address and metadata pointer, if present.
> + * Saves one call on hotpath, double calculation of the actual address,
> + * and inline checks for metadata presence and sanity.
> + * Please use xsk_buff_raw_get_ctx() in drivers instead.
> + *
> + * Return: new &xdp_desc_ctx struct containing desc's DMA address and metadata
> + * pointer, if it is present and valid (initialized to %NULL otherwise).
> + */
> +struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr)
> +{
> +	struct xsk_tx_metadata *meta;
> +	struct xdp_desc_ctx ret;
> +
> +	addr = pool->unaligned ? xp_unaligned_add_offset_to_addr(addr) : addr;
> +	ret = (typeof(ret)){
> +		/* Same logic as in xp_raw_get_dma() */
> +		.dma	= (pool->dma_pages[addr >> PAGE_SHIFT] &
> +			   ~XSK_NEXT_PG_CONTIG_MASK) + (addr & ~PAGE_MASK),
> +	};
> +
> +	if (!pool->tx_metadata_len)
> +		goto out;
> +
> +	/* Same logic as in xp_raw_get_data() + xsk_buff_get_metadata() */
> +	meta = pool->addrs + addr - pool->tx_metadata_len;
> +	if (unlikely(!xsk_buff_valid_tx_metadata(meta)))
> +		goto out;
> +
> +	ret.meta = meta;
> +
> +out:
> +	return ret;
> +}
> +EXPORT_SYMBOL(xp_raw_get_ctx);
> -- 
> 2.46.2
> 

  reply	other threads:[~2024-10-22 15:42 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-15 14:53 [PATCH net-next v2 00/18] idpf: XDP chapter III: core XDP changes (+libeth_xdp) Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 01/18] jump_label: export static_key_slow_{inc,dec}_cpuslocked() Alexander Lobakin
2024-10-17 11:06   ` Maciej Fijalkowski
2024-10-21 13:53     ` Alexander Lobakin
2024-10-22 12:52       ` Maciej Fijalkowski
2024-10-15 14:53 ` [PATCH net-next v2 02/18] skbuff: allow 2-4-argument skb_frag_dma_map() Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 03/18] unroll: add generic loop unroll helpers Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 04/18] bpf, xdp: constify some bpf_prog * function arguments Alexander Lobakin
2024-10-17 11:12   ` Maciej Fijalkowski
2024-10-21 13:56     ` Alexander Lobakin
2024-10-22 12:55       ` Maciej Fijalkowski
2024-10-15 14:53 ` [PATCH net-next v2 05/18] xdp, xsk: constify read-only arguments of some static inline helpers Alexander Lobakin
2024-10-17 11:14   ` Maciej Fijalkowski
2024-10-21 13:57     ` Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 06/18] xdp: allow attaching already registered memory model to xdp_rxq_info Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 07/18] net: Register system page pool as an XDP memory model Alexander Lobakin
2024-10-17 11:32   ` Maciej Fijalkowski
2024-10-21 14:00     ` Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 08/18] page_pool: make page_pool_put_page_bulk() actually handle array of pages Alexander Lobakin
2024-10-17 11:33   ` Maciej Fijalkowski
2024-10-21 14:03     ` Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 09/18] page_pool: allow mixing PPs within one bulk Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 10/18] xdp: get rid of xdp_frame::mem.id Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 11/18] xdp: add generic xdp_buff_add_frag() Alexander Lobakin
2024-10-17 12:26   ` Maciej Fijalkowski
2024-10-21 14:10     ` Alexander Lobakin
2024-10-22 13:00       ` Maciej Fijalkowski
2024-10-15 14:53 ` [PATCH net-next v2 12/18] xdp: add generic xdp_build_skb_from_buff() Alexander Lobakin
2024-10-17 12:34   ` Maciej Fijalkowski
2024-10-21 14:20     ` Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 13/18] xsk: allow attaching XSk pool via xdp_rxq_info_reg_mem_model() Alexander Lobakin
2024-10-17 12:49   ` Maciej Fijalkowski
2024-10-21 14:23     ` Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 14/18] xsk: make xsk_buff_add_frag really add a frag via __xdp_buff_add_frag() Alexander Lobakin
2024-10-17 13:04   ` Maciej Fijalkowski
2024-10-15 14:53 ` [PATCH net-next v2 15/18] xsk: add generic XSk &xdp_buff -> skb conversion Alexander Lobakin
2024-10-18 12:48   ` Maciej Fijalkowski
2024-10-15 14:53 ` [PATCH net-next v2 16/18] xsk: add helper to get &xdp_desc's DMA and meta pointer in one go Alexander Lobakin
2024-10-22 15:42   ` Maciej Fijalkowski [this message]
2024-10-23 14:50     ` Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 17/18] libeth: support native XDP and register memory model Alexander Lobakin
2024-10-15 14:53 ` [PATCH net-next v2 18/18] libeth: add a couple of XDP helpers (libeth_xdp) Alexander Lobakin

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=ZxfH1VmjcVdLeKUo@boxer \
    --to=maciej.fijalkowski@intel.com \
    --cc=aleksander.lobakin@intel.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=john.fastabend@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=magnus.karlsson@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=nex.sw.ncis.osdt.itp.upstreaming@intel.com \
    --cc=pabeni@redhat.com \
    --cc=sdf@fomichev.me \
    --cc=toke@redhat.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;
as well as URLs for NNTP newsgroup(s).