From: Jesper Dangaard Brouer <hawk@kernel.org>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>,
"Daniel Bristot de Oliveira" <bristot@kernel.org>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Eric Dumazet" <edumazet@google.com>,
"Frederic Weisbecker" <frederic@kernel.org>,
"Ingo Molnar" <mingo@redhat.com>,
"Jakub Kicinski" <kuba@kernel.org>,
"Paolo Abeni" <pabeni@redhat.com>,
"Peter Zijlstra" <peterz@infradead.org>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Waiman Long" <longman@redhat.com>,
"Will Deacon" <will@kernel.org>,
"Alexei Starovoitov" <ast@kernel.org>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Hao Luo" <haoluo@google.com>, "Jiri Olsa" <jolsa@kernel.org>,
"John Fastabend" <john.fastabend@gmail.com>,
"KP Singh" <kpsingh@kernel.org>,
"Martin KaFai Lau" <martin.lau@linux.dev>,
"Song Liu" <song@kernel.org>,
"Stanislav Fomichev" <sdf@google.com>,
"Toke Høiland-Jørgensen" <toke@redhat.com>,
"Yonghong Song" <yonghong.song@linux.dev>,
bpf@vger.kernel.org
Subject: Re: [PATCH v6 net-next 14/15] net: Reference bpf_redirect_info via task_struct on PREEMPT_RT.
Date: Thu, 13 Jun 2024 11:32:04 +0200 [thread overview]
Message-ID: <74985816-3a3a-490e-b8f0-49f795ab2f07@kernel.org> (raw)
In-Reply-To: <20240612170303.3896084-15-bigeasy@linutronix.de>
On 12/06/2024 18.44, Sebastian Andrzej Siewior wrote:
> The XDP redirect process is two staged:
> - bpf_prog_run_xdp() is invoked to run a eBPF program which inspects the
> packet and makes decisions. While doing that, the per-CPU variable
> bpf_redirect_info is used.
>
> - Afterwards xdp_do_redirect() is invoked and accesses bpf_redirect_info
> and it may also access other per-CPU variables like xskmap_flush_list.
>
> At the very end of the NAPI callback, xdp_do_flush() is invoked which
> does not access bpf_redirect_info but will touch the individual per-CPU
> lists.
>
> The per-CPU variables are only used in the NAPI callback hence disabling
> bottom halves is the only protection mechanism. Users from preemptible
> context (like cpu_map_kthread_run()) explicitly disable bottom halves
> for protections reasons.
> Without locking in local_bh_disable() on PREEMPT_RT this data structure
> requires explicit locking.
>
> PREEMPT_RT has forced-threaded interrupts enabled and every
> NAPI-callback runs in a thread. If each thread has its own data
> structure then locking can be avoided.
>
> Create a struct bpf_net_context which contains struct bpf_redirect_info.
> Define the variable on stack, use bpf_net_ctx_set() to save a pointer to
> it, bpf_net_ctx_clear() removes it again.
> The bpf_net_ctx_set() may nest. For instance a function can be used from
> within NET_RX_SOFTIRQ/ net_rx_action which uses bpf_net_ctx_set() and
> NET_TX_SOFTIRQ which does not. Therefore only the first invocations
> updates the pointer.
> Use bpf_net_ctx_get_ri() as a wrapper to retrieve the current struct
> bpf_redirect_info. The returned data structure is zero initialized to
> ensure nothing is leaked from stack. This is done on first usage of the
> struct. bpf_net_ctx_set() sets bpf_redirect_info::kern_flags to 0 to
> note that initialisation is required. First invocation of
> bpf_net_ctx_get_ri() will memset() the data structure and update
> bpf_redirect_info::kern_flags.
> bpf_redirect_info::nh is excluded from memset because it is only used
> once BPF_F_NEIGH is set which also sets the nh member. The kern_flags is
> moved past nh to exclude it from memset.
>
> The pointer to bpf_net_context is saved task's task_struct. Using
> always the bpf_net_context approach has the advantage that there is
> almost zero differences between PREEMPT_RT and non-PREEMPT_RT builds.
>
> Cc: Alexei Starovoitov<ast@kernel.org>
> Cc: Andrii Nakryiko<andrii@kernel.org>
> Cc: Eduard Zingerman<eddyz87@gmail.com>
> Cc: Hao Luo<haoluo@google.com>
> Cc: Jesper Dangaard Brouer<hawk@kernel.org>
> Cc: Jiri Olsa<jolsa@kernel.org>
> Cc: John Fastabend<john.fastabend@gmail.com>
> Cc: KP Singh<kpsingh@kernel.org>
> Cc: Martin KaFai Lau<martin.lau@linux.dev>
> Cc: Song Liu<song@kernel.org>
> Cc: Stanislav Fomichev<sdf@google.com>
> Cc: Toke Høiland-Jørgensen<toke@redhat.com>
> Cc: Yonghong Song<yonghong.song@linux.dev>
> Cc:bpf@vger.kernel.org
> Acked-by: Alexei Starovoitov<ast@kernel.org>
> Reviewed-by: Toke Høiland-Jørgensen<toke@redhat.com>
> Signed-off-by: Sebastian Andrzej Siewior<bigeasy@linutronix.de>
> ---
> include/linux/filter.h | 56 ++++++++++++++++++++++++++++++++++--------
> include/linux/sched.h | 3 +++
> kernel/bpf/cpumap.c | 3 +++
> kernel/bpf/devmap.c | 9 ++++++-
> kernel/fork.c | 1 +
> net/bpf/test_run.c | 11 ++++++++-
> net/core/dev.c | 26 +++++++++++++++++++-
> net/core/filter.c | 44 +++++++++------------------------
> net/core/lwt_bpf.c | 3 +++
> 9 files changed, 111 insertions(+), 45 deletions(-)
>
I like it :-)
Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
> diff --git a/include/linux/filter.h b/include/linux/filter.h
> index b02aea291b7e8..0a7f6e4a00b60 100644
> --- a/include/linux/filter.h
> +++ b/include/linux/filter.h
> @@ -733,21 +733,59 @@ struct bpf_nh_params {
> };
> };
>
> +/* flags for bpf_redirect_info kern_flags */
> +#define BPF_RI_F_RF_NO_DIRECT BIT(0) /* no napi_direct on return_frame */
> +#define BPF_RI_F_RI_INIT BIT(1)
> +
> struct bpf_redirect_info {
> u64 tgt_index;
> void *tgt_value;
> struct bpf_map *map;
> u32 flags;
> - u32 kern_flags;
> u32 map_id;
> enum bpf_map_type map_type;
> struct bpf_nh_params nh;
> + u32 kern_flags;
> };
>
> -DECLARE_PER_CPU(struct bpf_redirect_info, bpf_redirect_info);
> +struct bpf_net_context {
> + struct bpf_redirect_info ri;
> +};
>
> -/* flags for bpf_redirect_info kern_flags */
> -#define BPF_RI_F_RF_NO_DIRECT BIT(0) /* no napi_direct on return_frame */
> +static inline struct bpf_net_context *bpf_net_ctx_set(struct bpf_net_context *bpf_net_ctx)
> +{
> + struct task_struct *tsk = current;
> +
> + if (tsk->bpf_net_context != NULL)
> + return NULL;
> + bpf_net_ctx->ri.kern_flags = 0;
> +
> + tsk->bpf_net_context = bpf_net_ctx;
> + return bpf_net_ctx;
> +}
> +
> +static inline void bpf_net_ctx_clear(struct bpf_net_context *bpf_net_ctx)
> +{
> + if (bpf_net_ctx)
> + current->bpf_net_context = NULL;
> +}
> +
> +static inline struct bpf_net_context *bpf_net_ctx_get(void)
> +{
> + return current->bpf_net_context;
> +}
> +
> +static inline struct bpf_redirect_info *bpf_net_ctx_get_ri(void)
> +{
> + struct bpf_net_context *bpf_net_ctx = bpf_net_ctx_get();
> +
> + if (!(bpf_net_ctx->ri.kern_flags & BPF_RI_F_RI_INIT)) {
> + memset(&bpf_net_ctx->ri, 0, offsetof(struct bpf_net_context, ri.nh));
> + bpf_net_ctx->ri.kern_flags |= BPF_RI_F_RI_INIT;
> + }
> +
> + return &bpf_net_ctx->ri;
> +}
>
> /* Compute the linear packet data range [data, data_end) which
> * will be accessed by various program types (cls_bpf, act_bpf,
> @@ -1018,25 +1056,23 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
> const struct bpf_insn *patch, u32 len);
> int bpf_remove_insns(struct bpf_prog *prog, u32 off, u32 cnt);
>
> -void bpf_clear_redirect_map(struct bpf_map *map);
> -
> static inline bool xdp_return_frame_no_direct(void)
> {
> - struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
> + struct bpf_redirect_info *ri = bpf_net_ctx_get_ri();
>
> return ri->kern_flags & BPF_RI_F_RF_NO_DIRECT;
> }
>
> static inline void xdp_set_return_frame_no_direct(void)
> {
> - struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
> + struct bpf_redirect_info *ri = bpf_net_ctx_get_ri();
>
> ri->kern_flags |= BPF_RI_F_RF_NO_DIRECT;
> }
>
> static inline void xdp_clear_return_frame_no_direct(void)
> {
> - struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
> + struct bpf_redirect_info *ri = bpf_net_ctx_get_ri();
>
> ri->kern_flags &= ~BPF_RI_F_RF_NO_DIRECT;
> }
> @@ -1592,7 +1628,7 @@ static __always_inline long __bpf_xdp_redirect_map(struct bpf_map *map, u64 inde
> u64 flags, const u64 flag_mask,
> void *lookup_elem(struct bpf_map *map, u32 key))
> {
> - struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
> + struct bpf_redirect_info *ri = bpf_net_ctx_get_ri();
> const u64 action_mask = XDP_ABORTED | XDP_DROP | XDP_PASS | XDP_TX;
next prev parent reply other threads:[~2024-06-13 9:32 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-12 16:44 [PATCH v6 net-next 00/15] locking: Introduce nested-BH locking Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 01/15] locking/local_lock: Introduce guard definition for local_lock Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 02/15] locking/local_lock: Add local nested BH locking infrastructure Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 03/15] net: Use __napi_alloc_frag_align() instead of open coding it Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 04/15] net: Use nested-BH locking for napi_alloc_cache Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 05/15] net/tcp_sigpool: Use nested-BH locking for sigpool_scratch Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 06/15] net/ipv4: Use nested-BH locking for ipv4_tcp_sk Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 07/15] netfilter: br_netfilter: Use nested-BH locking for brnf_frag_data_storage Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 08/15] net: softnet_data: Make xmit.recursion per task Sebastian Andrzej Siewior
2024-06-12 17:18 ` Steven Rostedt
2024-06-14 8:27 ` Sebastian Andrzej Siewior
2024-06-14 8:38 ` Eric Dumazet
2024-06-14 9:48 ` Sebastian Andrzej Siewior
2024-06-14 14:08 ` Paolo Abeni
2024-06-14 16:04 ` Steven Rostedt
2024-06-14 16:04 ` Sebastian Andrzej Siewior
2024-06-14 16:01 ` [PATCH v6.5 08/15] net: softnet_data: Make xmit " Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 09/15] dev: Remove PREEMPT_RT ifdefs from backlog_lock.*() Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 10/15] dev: Use nested-BH locking for softnet_data.process_queue Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 11/15] lwt: Don't disable migration prio invoking BPF Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 12/15] seg6: Use nested-BH locking for seg6_bpf_srh_states Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 13/15] net: Use nested-BH locking for bpf_scratchpad Sebastian Andrzej Siewior
2024-06-12 16:44 ` [PATCH v6 net-next 14/15] net: Reference bpf_redirect_info via task_struct on PREEMPT_RT Sebastian Andrzej Siewior
2024-06-13 9:32 ` Jesper Dangaard Brouer [this message]
2024-06-12 16:44 ` [PATCH v6 net-next 15/15] net: Move per-CPU flush-lists to bpf_net_context " Sebastian Andrzej Siewior
2024-06-13 9:33 ` Jesper Dangaard Brouer
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=74985816-3a3a-490e-b8f0-49f795ab2f07@kernel.org \
--to=hawk@kernel.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bigeasy@linutronix.de \
--cc=boqun.feng@gmail.com \
--cc=bpf@vger.kernel.org \
--cc=bristot@kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=eddyz87@gmail.com \
--cc=edumazet@google.com \
--cc=frederic@kernel.org \
--cc=haoluo@google.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kpsingh@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=longman@redhat.com \
--cc=martin.lau@linux.dev \
--cc=mingo@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=peterz@infradead.org \
--cc=sdf@google.com \
--cc=song@kernel.org \
--cc=tglx@linutronix.de \
--cc=toke@redhat.com \
--cc=will@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.