All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stanislav Fomichev <stfomichev@gmail.com>
To: Lorenzo Bianconi <lorenzo@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	John Fastabend <john.fastabend@gmail.com>,
	Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Eduard Zingerman <eddyz87@gmail.com>, Song Liu <song@kernel.org>,
	Yonghong Song <yonghong.song@linux.dev>,
	KP Singh <kpsingh@kernel.org>,
	Stanislav Fomichev <sdf@fomichev.me>, Hao Luo <haoluo@google.com>,
	Jiri Olsa <jolsa@kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	Jesper Dangaard Brouer <hawk@kernel.org>,
	bpf@vger.kernel.org, netdev@vger.kernel.org
Subject: Re: [PATCH bpf-next] bpf: Allow XDP dev bounded program to perform XDP_REDIRECT into maps
Date: Wed, 23 Apr 2025 07:33:04 -0700	[thread overview]
Message-ID: <aAj6IBZ4hsUS12f4@mini-arch> (raw)
In-Reply-To: <aAi80as6PpOeuWJU@lore-desk>

On 04/23, Lorenzo Bianconi wrote:
> On Apr 22, Stanislav Fomichev wrote:
> > On 04/22, Lorenzo Bianconi wrote:
> > > In the current implementation if the program is bounded to a specific
> > > device, it will not be possible to perform XDP_REDIRECT into a DEVMAP
> > > or CPUMAP even if the program is not attached to the map entry. This
> > > seems in contrast with the explanation available in
> > > bpf_prog_map_compatible routine. Fix the issue taking into account
> > > even the attach program type and allow XDP dev bounded program to
> > > perform XDP_REDIRECT into maps if the attach type is not BPF_XDP_DEVMAP
> > > or BPF_XDP_CPUMAP.
> > > 
> > > Fixes: 3d76a4d3d4e59 ("bpf: XDP metadata RX kfuncs")
> > > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > > ---
> > >  kernel/bpf/core.c | 22 +++++++++++++++++++++-
> > >  1 file changed, 21 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> > > index ba6b6118cf504041278d05417c4212d57be6fca0..a33175efffc377edbfe281397017eb467bfbcce9 100644
> > > --- a/kernel/bpf/core.c
> > > +++ b/kernel/bpf/core.c
> > > @@ -2358,6 +2358,26 @@ static unsigned int __bpf_prog_ret0_warn(const void *ctx,
> > >  	return 0;
> > >  }
> > >  
> > > +static bool bpf_prog_dev_bound_map_compatible(struct bpf_map *map,
> > > +					      const struct bpf_prog *prog)
> > > +{
> > > +	if (!bpf_prog_is_dev_bound(prog->aux))
> > > +		return true;
> > > +
> > > +	if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY)
> > > +		return false;
> > 
> > [..]
> > 
> > > +	if (map->map_type == BPF_MAP_TYPE_DEVMAP &&
> > > +	    prog->expected_attach_type != BPF_XDP_DEVMAP)
> > > +		return true;
> > > +
> > > +	if (map->map_type == BPF_MAP_TYPE_CPUMAP &&
> > > +	    prog->expected_attach_type != BPF_XDP_CPUMAP)
> > > +		return true;
> > 
> > Not sure I understand, what does it mean exactly? That it's ok to add
> > a dev-bound program to the dev/cpumap if the program itself is gonna
> > be attached only to the real device? Can you expand more on the specific
> > use-case?
> > 
> > The existing check makes sure that the dev-bound programs run only in the
> > contexts that have hw descriptors. devmap and cpumap don't satisfy
> > this constraint afaiu.
> 
> My use-case is to use a hw-metadata kfunc like bpf_xdp_metadata_rx_timestamp()
> to read hw timestamp from the NIC and then redirect the xdp_buff into a DEVMP
> (please note there are no programs attached to any DEVMAP entries):
> 
> extern int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx,
> 					 __u64 *timestamp) __ksym;
> 
> struct {
> 	__uint(type, BPF_MAP_TYPE_DEVMAP);
> 	__uint(key_size, sizeof(__u32));
> 	__uint(value_size, sizeof(struct bpf_devmap_val));
> 	__uint(max_entries, 1);
> } dev_map SEC(".maps");
> 
> SEC("xdp")
> int xdp_meta_redirect(struct xdp_md *ctx)
> {
> 	__u64 timestamp;
> 
> 	...
> 	bpf_xdp_metadata_rx_timestamp(ctx, &timestamp);
> 	...
> 
> 	return bpf_redirect_map(&dev_map, ctx->rx_queue_index, XDP_PASS);
> }
> 
> According to my understanding this is feasible just if the "xdp_meta_redirect"
> program is bounded to a device otherwise the program is reject with the following
> error at load time:
> 
> libbpf: prog 'xdp_meta_redirect': BPF program load failed: -EINVAL
> libbpf: prog 'xdp_meta_redirect': -- BEGIN PROG LOAD LOG --
> metadata kfuncs require device-bound program
> processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0
> peak_states 0 mark_read 0
> -- END PROG LOAD LOG --
> 
> in order to fix it:
> 
> 	...
> 	index = if_nametoindex(DEV); 
> 	bpf_program__set_ifindex(prog, index);
> 	bpf_program__set_flags(prog, BPF_F_XDP_DEV_BOUND_ONLY);
> 	...
> 
> Doing so the program load still fails for the check in bpf_prog_map_compatible():
> 
> 	bool bpf_prog_map_compatible()
> 	{
> 		...
> 		if (bpf_prog_is_dev_bound(aux))
> 			return false;
> 		...

[..]
 
> In other words, a dev-bound XDP program can't interact with a DEVMAP (or
> CPUMAP) even if it is not attached to a map entry.
> I think if the XDP program is just running in the driver NAPI context
> it should be doable to use a hw-metada kfunc and perform a redirect into
> a DEVMAP or CPUMAP, right? Am I missing something?

Thanks for the info! Yes, that should work. I wonder if you hit
bpf_prog_select_runtime->bpf_check_tail_call->bpf_prog_map_compatible
path? Looks like we should not do bpf_prog_is_dev_bound in that case (the rest
of the bpf_prog_map_compatible callers should).

When doing a follow up, can you also extend tools/testing/selftests/bpf/prog_tests/xdp_metadata.c
to cover these conditions? (redirect to empty map -> nop, adding
dev-bound program to devmap is einval).

  reply	other threads:[~2025-04-23 14:33 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-22 21:14 [PATCH bpf-next] bpf: Allow XDP dev bounded program to perform XDP_REDIRECT into maps Lorenzo Bianconi
2025-04-22 22:49 ` Stanislav Fomichev
2025-04-23  0:03   ` Jakub Kicinski
2025-04-23 10:11   ` Lorenzo Bianconi
2025-04-23 14:33     ` Stanislav Fomichev [this message]
2025-04-23 14:54       ` Lorenzo Bianconi
2025-04-23 15:09         ` Stanislav Fomichev

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=aAj6IBZ4hsUS12f4@mini-arch \
    --to=stfomichev@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=eddyz87@gmail.com \
    --cc=haoluo@google.com \
    --cc=hawk@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kpsingh@kernel.org \
    --cc=kuba@kernel.org \
    --cc=lorenzo@kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=netdev@vger.kernel.org \
    --cc=sdf@fomichev.me \
    --cc=song@kernel.org \
    --cc=yonghong.song@linux.dev \
    /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.