* [PATCH bpf-next v2 0/2] bpf: Introduce bpf_in_interrupt kfunc @ 2025-08-25 13:14 Leon Hwang 2025-08-25 13:15 ` [PATCH bpf-next v2 1/2] " Leon Hwang 2025-08-25 13:15 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add case to test " Leon Hwang 0 siblings, 2 replies; 12+ messages in thread From: Leon Hwang @ 2025-08-25 13:14 UTC (permalink / raw) To: bpf Cc: ast, andrii, daniel, martin.lau, eddyz87, song, yonghong.song, leon.hwang, kernel-patches-bot Filtering pid_tgid is meaningless when the current task is preempted by an interrupt. To address this, introduce the bpf_in_interrupt kfunc, which allows BPF programs to determine whether they are executing in interrupt context. Internally, bpf_in_interrupt() is a thin wrapper around in_interrupt(). It is marked as fastcall function. On x86_64, it is inlined for efficiency. Changes: v1 -> v2: * Fix a build error reported by test bot. Leon Hwang (2): bpf: Introduce bpf_in_interrupt kfunc selftests/bpf: Add case to test bpf_in_interrupt kfunc kernel/bpf/helpers.c | 9 +++++++++ kernel/bpf/verifier.c | 11 +++++++++++ tools/testing/selftests/bpf/progs/irq.c | 7 +++++++ 3 files changed, 27 insertions(+) -- 2.50.1 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH bpf-next v2 1/2] bpf: Introduce bpf_in_interrupt kfunc 2025-08-25 13:14 [PATCH bpf-next v2 0/2] bpf: Introduce bpf_in_interrupt kfunc Leon Hwang @ 2025-08-25 13:15 ` Leon Hwang 2025-08-25 15:17 ` Alexei Starovoitov 2025-08-25 13:15 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add case to test " Leon Hwang 1 sibling, 1 reply; 12+ messages in thread From: Leon Hwang @ 2025-08-25 13:15 UTC (permalink / raw) To: bpf Cc: ast, andrii, daniel, martin.lau, eddyz87, song, yonghong.song, leon.hwang, kernel-patches-bot Filtering pid_tgid is meaningless when the current task is preempted by an interrupt. To address this, introduce the bpf_in_interrupt kfunc, which allows BPF programs to determine whether they are executing in interrupt context. This enables programs to avoid applying pid_tgid filtering when running in such contexts. Signed-off-by: Leon Hwang <leon.hwang@linux.dev> --- kernel/bpf/helpers.c | 9 +++++++++ kernel/bpf/verifier.c | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 401b4932cc49f..38991b7b4a9e9 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -3711,6 +3711,14 @@ __bpf_kfunc int bpf_strstr(const char *s1__ign, const char *s2__ign) return bpf_strnstr(s1__ign, s2__ign, XATTR_SIZE_MAX); } +/** + * bpf_in_interrupt - Check whether it's in interrupt context + */ +__bpf_kfunc int bpf_in_interrupt(void) +{ + return in_interrupt(); +} + __bpf_kfunc_end_defs(); BTF_KFUNCS_START(generic_btf_ids) @@ -3751,6 +3759,7 @@ BTF_ID_FLAGS(func, bpf_throw) #ifdef CONFIG_BPF_EVENTS BTF_ID_FLAGS(func, bpf_send_signal_task, KF_TRUSTED_ARGS) #endif +BTF_ID_FLAGS(func, bpf_in_interrupt, KF_FASTCALL) BTF_KFUNCS_END(generic_btf_ids) static const struct btf_kfunc_id_set generic_kfunc_set = { diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 5c9dd16b2c56b..e30ecbfc29dad 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -12259,6 +12259,7 @@ enum special_kfunc_type { KF_bpf_res_spin_lock_irqsave, KF_bpf_res_spin_unlock_irqrestore, KF___bpf_trap, + KF_bpf_in_interrupt, }; BTF_ID_LIST(special_kfunc_list) @@ -12327,6 +12328,7 @@ BTF_ID(func, bpf_res_spin_unlock) BTF_ID(func, bpf_res_spin_lock_irqsave) BTF_ID(func, bpf_res_spin_unlock_irqrestore) BTF_ID(func, __bpf_trap) +BTF_ID(func, bpf_in_interrupt) static bool is_kfunc_ret_null(struct bpf_kfunc_call_arg_meta *meta) { @@ -21977,6 +21979,15 @@ static int fixup_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn, desc->func_id == special_kfunc_list[KF_bpf_rdonly_cast]) { insn_buf[0] = BPF_MOV64_REG(BPF_REG_0, BPF_REG_1); *cnt = 1; + } else if (desc->func_id == special_kfunc_list[KF_bpf_in_interrupt]) { +#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, (u32)(unsigned long)&__preempt_count); + insn_buf[1] = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0); + insn_buf[2] = BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0); + insn_buf[3] = BPF_ALU32_IMM(BPF_AND, BPF_REG_0, NMI_MASK | HARDIRQ_MASK | + (IS_ENABLED(CONFIG_PREEMPT_RT) ? 0 : SOFTIRQ_MASK)); + *cnt = 4; +#endif } if (env->insn_aux_data[insn_idx].arg_prog) { -- 2.50.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Introduce bpf_in_interrupt kfunc 2025-08-25 13:15 ` [PATCH bpf-next v2 1/2] " Leon Hwang @ 2025-08-25 15:17 ` Alexei Starovoitov 2025-08-26 3:00 ` Leon Hwang 0 siblings, 1 reply; 12+ messages in thread From: Alexei Starovoitov @ 2025-08-25 15:17 UTC (permalink / raw) To: Leon Hwang Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Martin KaFai Lau, Eduard, Song Liu, Yonghong Song, kernel-patches-bot On Mon, Aug 25, 2025 at 6:15 AM Leon Hwang <leon.hwang@linux.dev> wrote: > > Filtering pid_tgid is meaningless when the current task is preempted by > an interrupt. > > To address this, introduce the bpf_in_interrupt kfunc, which allows BPF > programs to determine whether they are executing in interrupt context. > > This enables programs to avoid applying pid_tgid filtering when running > in such contexts. > > Signed-off-by: Leon Hwang <leon.hwang@linux.dev> > --- > kernel/bpf/helpers.c | 9 +++++++++ > kernel/bpf/verifier.c | 11 +++++++++++ > 2 files changed, 20 insertions(+) > > diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c > index 401b4932cc49f..38991b7b4a9e9 100644 > --- a/kernel/bpf/helpers.c > +++ b/kernel/bpf/helpers.c > @@ -3711,6 +3711,14 @@ __bpf_kfunc int bpf_strstr(const char *s1__ign, const char *s2__ign) > return bpf_strnstr(s1__ign, s2__ign, XATTR_SIZE_MAX); > } > > +/** > + * bpf_in_interrupt - Check whether it's in interrupt context > + */ > +__bpf_kfunc int bpf_in_interrupt(void) > +{ > + return in_interrupt(); > +} It doesn't scale. Next thing people will ask for hard vs soft irq. > + > __bpf_kfunc_end_defs(); > > BTF_KFUNCS_START(generic_btf_ids) > @@ -3751,6 +3759,7 @@ BTF_ID_FLAGS(func, bpf_throw) > #ifdef CONFIG_BPF_EVENTS > BTF_ID_FLAGS(func, bpf_send_signal_task, KF_TRUSTED_ARGS) > #endif > +BTF_ID_FLAGS(func, bpf_in_interrupt, KF_FASTCALL) > BTF_KFUNCS_END(generic_btf_ids) > > static const struct btf_kfunc_id_set generic_kfunc_set = { > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index 5c9dd16b2c56b..e30ecbfc29dad 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -12259,6 +12259,7 @@ enum special_kfunc_type { > KF_bpf_res_spin_lock_irqsave, > KF_bpf_res_spin_unlock_irqrestore, > KF___bpf_trap, > + KF_bpf_in_interrupt, > }; > > BTF_ID_LIST(special_kfunc_list) > @@ -12327,6 +12328,7 @@ BTF_ID(func, bpf_res_spin_unlock) > BTF_ID(func, bpf_res_spin_lock_irqsave) > BTF_ID(func, bpf_res_spin_unlock_irqrestore) > BTF_ID(func, __bpf_trap) > +BTF_ID(func, bpf_in_interrupt) > > static bool is_kfunc_ret_null(struct bpf_kfunc_call_arg_meta *meta) > { > @@ -21977,6 +21979,15 @@ static int fixup_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn, > desc->func_id == special_kfunc_list[KF_bpf_rdonly_cast]) { > insn_buf[0] = BPF_MOV64_REG(BPF_REG_0, BPF_REG_1); > *cnt = 1; > + } else if (desc->func_id == special_kfunc_list[KF_bpf_in_interrupt]) { > +#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) > + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, (u32)(unsigned long)&__preempt_count); I think bpf_per_cpu_ptr() should already be able to read that per cpu var. > + insn_buf[1] = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0); > + insn_buf[2] = BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0); > + insn_buf[3] = BPF_ALU32_IMM(BPF_AND, BPF_REG_0, NMI_MASK | HARDIRQ_MASK | > + (IS_ENABLED(CONFIG_PREEMPT_RT) ? 0 : SOFTIRQ_MASK)); This is still wrong in PREEMPT_RT. pw-bot: cr ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Introduce bpf_in_interrupt kfunc 2025-08-25 15:17 ` Alexei Starovoitov @ 2025-08-26 3:00 ` Leon Hwang 2025-08-26 22:18 ` Alexei Starovoitov 0 siblings, 1 reply; 12+ messages in thread From: Leon Hwang @ 2025-08-26 3:00 UTC (permalink / raw) To: Alexei Starovoitov Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Martin KaFai Lau, Eduard, Song Liu, Yonghong Song, kernel-patches-bot On 25/8/25 23:17, Alexei Starovoitov wrote: > On Mon, Aug 25, 2025 at 6:15 AM Leon Hwang <leon.hwang@linux.dev> wrote: >> >> Filtering pid_tgid is meaningless when the current task is preempted by >> an interrupt. >> >> To address this, introduce the bpf_in_interrupt kfunc, which allows BPF >> programs to determine whether they are executing in interrupt context. >> >> This enables programs to avoid applying pid_tgid filtering when running >> in such contexts. >> >> Signed-off-by: Leon Hwang <leon.hwang@linux.dev> >> --- >> kernel/bpf/helpers.c | 9 +++++++++ >> kernel/bpf/verifier.c | 11 +++++++++++ >> 2 files changed, 20 insertions(+) >> >> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c >> index 401b4932cc49f..38991b7b4a9e9 100644 >> --- a/kernel/bpf/helpers.c >> +++ b/kernel/bpf/helpers.c >> @@ -3711,6 +3711,14 @@ __bpf_kfunc int bpf_strstr(const char *s1__ign, const char *s2__ign) >> return bpf_strnstr(s1__ign, s2__ign, XATTR_SIZE_MAX); >> } >> >> +/** >> + * bpf_in_interrupt - Check whether it's in interrupt context >> + */ >> +__bpf_kfunc int bpf_in_interrupt(void) >> +{ >> + return in_interrupt(); >> +} > > It doesn't scale. Next thing people will ask for hard vs soft irq. > How about adding a 'flags'? Here are the values for 'flags': * 0: return in_interrupt(); * 1(NMI): return in_nmi(); * 2(HARDIRQ): return in_hardirq(); * 3(SOFTIRQ): return in_softirq(); >> + >> __bpf_kfunc_end_defs(); >> >> BTF_KFUNCS_START(generic_btf_ids) >> @@ -3751,6 +3759,7 @@ BTF_ID_FLAGS(func, bpf_throw) >> #ifdef CONFIG_BPF_EVENTS >> BTF_ID_FLAGS(func, bpf_send_signal_task, KF_TRUSTED_ARGS) >> #endif >> +BTF_ID_FLAGS(func, bpf_in_interrupt, KF_FASTCALL) >> BTF_KFUNCS_END(generic_btf_ids) >> >> static const struct btf_kfunc_id_set generic_kfunc_set = { >> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c >> index 5c9dd16b2c56b..e30ecbfc29dad 100644 >> --- a/kernel/bpf/verifier.c >> +++ b/kernel/bpf/verifier.c >> @@ -12259,6 +12259,7 @@ enum special_kfunc_type { >> KF_bpf_res_spin_lock_irqsave, >> KF_bpf_res_spin_unlock_irqrestore, >> KF___bpf_trap, >> + KF_bpf_in_interrupt, >> }; >> >> BTF_ID_LIST(special_kfunc_list) >> @@ -12327,6 +12328,7 @@ BTF_ID(func, bpf_res_spin_unlock) >> BTF_ID(func, bpf_res_spin_lock_irqsave) >> BTF_ID(func, bpf_res_spin_unlock_irqrestore) >> BTF_ID(func, __bpf_trap) >> +BTF_ID(func, bpf_in_interrupt) >> >> static bool is_kfunc_ret_null(struct bpf_kfunc_call_arg_meta *meta) >> { >> @@ -21977,6 +21979,15 @@ static int fixup_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn, >> desc->func_id == special_kfunc_list[KF_bpf_rdonly_cast]) { >> insn_buf[0] = BPF_MOV64_REG(BPF_REG_0, BPF_REG_1); >> *cnt = 1; >> + } else if (desc->func_id == special_kfunc_list[KF_bpf_in_interrupt]) { >> +#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) >> + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, (u32)(unsigned long)&__preempt_count); > > I think bpf_per_cpu_ptr() should already be able to read that per cpu var. > Correct. bpf_per_cpu_ptr() and bpf_this_cpu_ptr() are helpful to read it. So, this patch seems useless. >> + insn_buf[1] = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0); >> + insn_buf[2] = BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0); >> + insn_buf[3] = BPF_ALU32_IMM(BPF_AND, BPF_REG_0, NMI_MASK | HARDIRQ_MASK | >> + (IS_ENABLED(CONFIG_PREEMPT_RT) ? 0 : SOFTIRQ_MASK)); > > This is still wrong in PREEMPT_RT. > You are right. Double-check the following macros: #ifdef CONFIG_PREEMPT_RT # define softirq_count() (current->softirq_disable_cnt & SOFTIRQ_MASK) # define irq_count() ((preempt_count() & (NMI_MASK | HARDIRQ_MASK)) | softirq_count()) #else # define softirq_count() (preempt_count() & SOFTIRQ_MASK) # define irq_count() (preempt_count() & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_MASK)) #endif #define in_interrupt() (irq_count()) If PREEMPT_RT, 'softirq_count()' is missing here. Thanks, Leon ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Introduce bpf_in_interrupt kfunc 2025-08-26 3:00 ` Leon Hwang @ 2025-08-26 22:18 ` Alexei Starovoitov 2025-09-01 15:12 ` Leon Hwang 0 siblings, 1 reply; 12+ messages in thread From: Alexei Starovoitov @ 2025-08-26 22:18 UTC (permalink / raw) To: Leon Hwang Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Martin KaFai Lau, Eduard, Song Liu, Yonghong Song, kernel-patches-bot On Mon, Aug 25, 2025 at 8:00 PM Leon Hwang <leon.hwang@linux.dev> wrote: > > > > On 25/8/25 23:17, Alexei Starovoitov wrote: > > On Mon, Aug 25, 2025 at 6:15 AM Leon Hwang <leon.hwang@linux.dev> wrote: > >> > >> Filtering pid_tgid is meaningless when the current task is preempted by > >> an interrupt. > >> > >> To address this, introduce the bpf_in_interrupt kfunc, which allows BPF > >> programs to determine whether they are executing in interrupt context. > >> > >> This enables programs to avoid applying pid_tgid filtering when running > >> in such contexts. > >> > >> Signed-off-by: Leon Hwang <leon.hwang@linux.dev> > >> --- > >> kernel/bpf/helpers.c | 9 +++++++++ > >> kernel/bpf/verifier.c | 11 +++++++++++ > >> 2 files changed, 20 insertions(+) > >> > >> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c > >> index 401b4932cc49f..38991b7b4a9e9 100644 > >> --- a/kernel/bpf/helpers.c > >> +++ b/kernel/bpf/helpers.c > >> @@ -3711,6 +3711,14 @@ __bpf_kfunc int bpf_strstr(const char *s1__ign, const char *s2__ign) > >> return bpf_strnstr(s1__ign, s2__ign, XATTR_SIZE_MAX); > >> } > >> > >> +/** > >> + * bpf_in_interrupt - Check whether it's in interrupt context > >> + */ > >> +__bpf_kfunc int bpf_in_interrupt(void) > >> +{ > >> + return in_interrupt(); > >> +} > > > > It doesn't scale. Next thing people will ask for hard vs soft irq. > > > > How about adding a 'flags'? > > Here are the values for 'flags': > > * 0: return in_interrupt(); > * 1(NMI): return in_nmi(); > * 2(HARDIRQ): return in_hardirq(); > * 3(SOFTIRQ): return in_softirq(); That's an option, but before we argue whether to do as one kfunc with enum vs N kfuncs let's explore bpf only option that doesn't involve changing the kernel. > >> +#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) > >> + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, (u32)(unsigned long)&__preempt_count); > > > > I think bpf_per_cpu_ptr() should already be able to read that per cpu var. > > > > Correct. bpf_per_cpu_ptr() and bpf_this_cpu_ptr() are helpful to read it. Can you add them as static inline functions to bpf_experimental.h and a selftest to make sure it's all working? At least for x86 and !PREEMPT_RT. Like: bool bpf_in_interrupt() { bpf_this_cpu_ptr(...preempt_count..) & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_MASK); } Of course, there is a danger that kernel implementation might diverge from bpf-only bit, but it's a risk we're taking all the time. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Introduce bpf_in_interrupt kfunc 2025-08-26 22:18 ` Alexei Starovoitov @ 2025-09-01 15:12 ` Leon Hwang 2025-09-02 2:29 ` Alexei Starovoitov 0 siblings, 1 reply; 12+ messages in thread From: Leon Hwang @ 2025-09-01 15:12 UTC (permalink / raw) To: Alexei Starovoitov Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Martin KaFai Lau, Eduard, Song Liu, Yonghong Song, kernel-patches-bot On Wed Aug 27, 2025 at 6:18 AM +08, Alexei Starovoitov wrote: > On Mon, Aug 25, 2025 at 8:00 PM Leon Hwang <leon.hwang@linux.dev> wrote: >> >> >> >> On 25/8/25 23:17, Alexei Starovoitov wrote: >> > On Mon, Aug 25, 2025 at 6:15 AM Leon Hwang <leon.hwang@linux.dev> wrote: [...] >> > >> > It doesn't scale. Next thing people will ask for hard vs soft irq. >> > >> >> How about adding a 'flags'? >> >> Here are the values for 'flags': >> >> * 0: return in_interrupt(); >> * 1(NMI): return in_nmi(); >> * 2(HARDIRQ): return in_hardirq(); >> * 3(SOFTIRQ): return in_softirq(); > > That's an option, but before we argue whether to do as one kfunc with enum > vs N kfuncs let's explore bpf only option that doesn't involve changing > the kernel. > >> >> +#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) >> >> + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, (u32)(unsigned long)&__preempt_count); >> > >> > I think bpf_per_cpu_ptr() should already be able to read that per cpu var. >> > >> >> Correct. bpf_per_cpu_ptr() and bpf_this_cpu_ptr() are helpful to read it. > > Can you add them as static inline functions to bpf_experimental.h > and a selftest to make sure it's all working? > At least for x86 and !PREEMPT_RT. > Like: > bool bpf_in_interrupt() > { > bpf_this_cpu_ptr(...preempt_count..) & (NMI_MASK | HARDIRQ_MASK | > SOFTIRQ_MASK); > } > > Of course, there is a danger that kernel implementation might > diverge from bpf-only bit, but it's a risk we're taking all the time. I do a PoC of adding bpf_in_interrupt() to bpf_experimental.h. It works: extern bool CONFIG_PREEMPT_RT __kconfig __weak; #ifdef bpf_target_x86 extern const int __preempt_count __ksym; #endif struct task_struct__preempt_rt { int softirq_disable_cnt; } __attribute__((preserve_access_index)); /* Description * Report whether it is in interrupt context. Only works on x86. */ static inline int bpf_in_interrupt(void) { #ifdef bpf_target_x86 int pcnt; pcnt = *(int *) bpf_this_cpu_ptr(&__preempt_count); if (!CONFIG_PREEMPT_RT) { return pcnt & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_MASK); } else { struct task_struct__preempt_rt *tsk; tsk = (void *) bpf_get_current_task_btf(); return (pcnt & (NMI_MASK | HARDIRQ_MASK)) | (tsk->softirq_disable_cnt | SOFTIRQ_MASK); } #else return 0; #endif } However, I only test it for !PREEMPT_RT on x86. I'd like to respin the patchset by moving bpf_in_interrupt() to bpf_experimental.h. Thanks, Leon ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Introduce bpf_in_interrupt kfunc 2025-09-01 15:12 ` Leon Hwang @ 2025-09-02 2:29 ` Alexei Starovoitov 2025-09-03 5:22 ` Leon Hwang 0 siblings, 1 reply; 12+ messages in thread From: Alexei Starovoitov @ 2025-09-02 2:29 UTC (permalink / raw) To: Leon Hwang Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Martin KaFai Lau, Eduard, Song Liu, Yonghong Song, kernel-patches-bot On Mon, Sep 1, 2025 at 8:12 AM Leon Hwang <leon.hwang@linux.dev> wrote: > > > I do a PoC of adding bpf_in_interrupt() to bpf_experimental.h. lgtm > It works: > > extern bool CONFIG_PREEMPT_RT __kconfig __weak; > #ifdef bpf_target_x86 what is bpf_target_x86 ? > extern const int __preempt_count __ksym; > #endif > > struct task_struct__preempt_rt { > int softirq_disable_cnt; > } __attribute__((preserve_access_index)); > > /* Description > * Report whether it is in interrupt context. Only works on x86. arm64 shouldn't be hard to support either. > */ > static inline int bpf_in_interrupt(void) > { > #ifdef bpf_target_x86 > int pcnt; > > pcnt = *(int *) bpf_this_cpu_ptr(&__preempt_count); > if (!CONFIG_PREEMPT_RT) { > return pcnt & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_MASK); > } else { > struct task_struct__preempt_rt *tsk; > > tsk = (void *) bpf_get_current_task_btf(); > return (pcnt & (NMI_MASK | HARDIRQ_MASK)) | > (tsk->softirq_disable_cnt | SOFTIRQ_MASK); > } > #else > return 0; > #endif > } > > However, I only test it for !PREEMPT_RT on x86. > > I'd like to respin the patchset by moving bpf_in_interrupt() to > bpf_experimental.h. I think the approach should work for PREEMPT_RT too. Test it and send it. imo this is better than a new kfunc. Users can start using it right away without waiting for a new kernel. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Introduce bpf_in_interrupt kfunc 2025-09-02 2:29 ` Alexei Starovoitov @ 2025-09-03 5:22 ` Leon Hwang 0 siblings, 0 replies; 12+ messages in thread From: Leon Hwang @ 2025-09-03 5:22 UTC (permalink / raw) To: Alexei Starovoitov Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann, Martin KaFai Lau, Eduard, Song Liu, Yonghong Song, kernel-patches-bot On 2/9/25 10:29, Alexei Starovoitov wrote: > On Mon, Sep 1, 2025 at 8:12 AM Leon Hwang <leon.hwang@linux.dev> wrote: >> >> >> I do a PoC of adding bpf_in_interrupt() to bpf_experimental.h. > > lgtm > >> It works: >> >> extern bool CONFIG_PREEMPT_RT __kconfig __weak; >> #ifdef bpf_target_x86 > > what is bpf_target_x86 ? > bpf_target_x86 is a macro defined in bpf_tracing.h: #if defined(__TARGET_ARCH_x86) #define bpf_target_x86 ... #if defined(__x86_64__) #define bpf_target_x86 ... >> extern const int __preempt_count __ksym; >> #endif >> >> struct task_struct__preempt_rt { >> int softirq_disable_cnt; >> } __attribute__((preserve_access_index)); >> >> /* Description >> * Report whether it is in interrupt context. Only works on x86. > > arm64 shouldn't be hard to support either. > No problem. I'll add support for arm64. >> */ >> static inline int bpf_in_interrupt(void) >> { >> #ifdef bpf_target_x86 >> int pcnt; >> >> pcnt = *(int *) bpf_this_cpu_ptr(&__preempt_count); >> if (!CONFIG_PREEMPT_RT) { >> return pcnt & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_MASK); >> } else { >> struct task_struct__preempt_rt *tsk; >> >> tsk = (void *) bpf_get_current_task_btf(); >> return (pcnt & (NMI_MASK | HARDIRQ_MASK)) | >> (tsk->softirq_disable_cnt | SOFTIRQ_MASK); >> } >> #else >> return 0; >> #endif >> } >> >> However, I only test it for !PREEMPT_RT on x86. >> >> I'd like to respin the patchset by moving bpf_in_interrupt() to >> bpf_experimental.h. > > I think the approach should work for PREEMPT_RT too. > Test it and send it. Yes, it works for PREEMPT_RT too. It is able to get retval of bpf_in_interrupt() by running a simple demo. However, it's really difficult to add selftest case for PREEMPT_RT, as I'm not familiar with PREEMPT_RT. Thanks, Leon [...] ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH bpf-next v2 2/2] selftests/bpf: Add case to test bpf_in_interrupt kfunc 2025-08-25 13:14 [PATCH bpf-next v2 0/2] bpf: Introduce bpf_in_interrupt kfunc Leon Hwang 2025-08-25 13:15 ` [PATCH bpf-next v2 1/2] " Leon Hwang @ 2025-08-25 13:15 ` Leon Hwang 2025-08-25 17:26 ` Eduard Zingerman 1 sibling, 1 reply; 12+ messages in thread From: Leon Hwang @ 2025-08-25 13:15 UTC (permalink / raw) To: bpf Cc: ast, andrii, daniel, martin.lau, eddyz87, song, yonghong.song, leon.hwang, kernel-patches-bot cd tools/testing/selftests/bpf ./test_progs -t irq #143/29 irq/in_interrupt:OK #143 irq:OK Summary: 1/34 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Leon Hwang <leon.hwang@linux.dev> --- tools/testing/selftests/bpf/progs/irq.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/irq.c b/tools/testing/selftests/bpf/progs/irq.c index 74d912b22de90..65a796fd1d615 100644 --- a/tools/testing/selftests/bpf/progs/irq.c +++ b/tools/testing/selftests/bpf/progs/irq.c @@ -563,4 +563,11 @@ int irq_wrong_kfunc_class_2(struct __sk_buff *ctx) return 0; } +SEC("?tc") +__success +int in_interrupt(struct __sk_buff *ctx) +{ + return bpf_in_interrupt(); +} + char _license[] SEC("license") = "GPL"; -- 2.50.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH bpf-next v2 2/2] selftests/bpf: Add case to test bpf_in_interrupt kfunc 2025-08-25 13:15 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add case to test " Leon Hwang @ 2025-08-25 17:26 ` Eduard Zingerman 2025-08-26 3:05 ` Leon Hwang 0 siblings, 1 reply; 12+ messages in thread From: Eduard Zingerman @ 2025-08-25 17:26 UTC (permalink / raw) To: Leon Hwang, bpf Cc: ast, andrii, daniel, martin.lau, song, yonghong.song, kernel-patches-bot On Mon, 2025-08-25 at 21:15 +0800, Leon Hwang wrote: > cd tools/testing/selftests/bpf > ./test_progs -t irq > #143/29 irq/in_interrupt:OK > #143 irq:OK > Summary: 1/34 PASSED, 0 SKIPPED, 0 FAILED > > Signed-off-by: Leon Hwang <leon.hwang@linux.dev> > --- > tools/testing/selftests/bpf/progs/irq.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/tools/testing/selftests/bpf/progs/irq.c b/tools/testing/selftests/bpf/progs/irq.c > index 74d912b22de90..65a796fd1d615 100644 > --- a/tools/testing/selftests/bpf/progs/irq.c > +++ b/tools/testing/selftests/bpf/progs/irq.c > @@ -563,4 +563,11 @@ int irq_wrong_kfunc_class_2(struct __sk_buff *ctx) > return 0; > } > > +SEC("?tc") > +__success Could you please extend this test to verify generated x86 assembly code? (see __arch_x86_64 and __jited macro usage in verifier_tailcall_jit.c). Also, is it necessary to extend this test to actually verify returned value? > +int in_interrupt(struct __sk_buff *ctx) > +{ > + return bpf_in_interrupt(); > +} > + > char _license[] SEC("license") = "GPL"; ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH bpf-next v2 2/2] selftests/bpf: Add case to test bpf_in_interrupt kfunc 2025-08-25 17:26 ` Eduard Zingerman @ 2025-08-26 3:05 ` Leon Hwang 2025-08-26 22:31 ` Eduard Zingerman 0 siblings, 1 reply; 12+ messages in thread From: Leon Hwang @ 2025-08-26 3:05 UTC (permalink / raw) To: Eduard Zingerman, bpf Cc: ast, andrii, daniel, martin.lau, song, yonghong.song, kernel-patches-bot On 26/8/25 01:26, Eduard Zingerman wrote: > On Mon, 2025-08-25 at 21:15 +0800, Leon Hwang wrote: >> cd tools/testing/selftests/bpf >> ./test_progs -t irq >> #143/29 irq/in_interrupt:OK >> #143 irq:OK >> Summary: 1/34 PASSED, 0 SKIPPED, 0 FAILED >> >> Signed-off-by: Leon Hwang <leon.hwang@linux.dev> >> --- >> tools/testing/selftests/bpf/progs/irq.c | 7 +++++++ >> 1 file changed, 7 insertions(+) >> >> diff --git a/tools/testing/selftests/bpf/progs/irq.c b/tools/testing/selftests/bpf/progs/irq.c >> index 74d912b22de90..65a796fd1d615 100644 >> --- a/tools/testing/selftests/bpf/progs/irq.c >> +++ b/tools/testing/selftests/bpf/progs/irq.c >> @@ -563,4 +563,11 @@ int irq_wrong_kfunc_class_2(struct __sk_buff *ctx) >> return 0; >> } >> >> +SEC("?tc") >> +__success > > Could you please extend this test to verify generated x86 assembly > code? (see __arch_x86_64 and __jited macro usage in verifier_tailcall_jit.c). I’ll try to extend it, depending on the specific x86 implementation. > Also, is it necessary to extend this test to actually verify returned > value? Not necessary — let’s just return 0 here. Thanks, Leon > >> +int in_interrupt(struct __sk_buff *ctx) >> +{ >> + return bpf_in_interrupt(); >> +} >> + >> char _license[] SEC("license") = "GPL"; ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH bpf-next v2 2/2] selftests/bpf: Add case to test bpf_in_interrupt kfunc 2025-08-26 3:05 ` Leon Hwang @ 2025-08-26 22:31 ` Eduard Zingerman 0 siblings, 0 replies; 12+ messages in thread From: Eduard Zingerman @ 2025-08-26 22:31 UTC (permalink / raw) To: Leon Hwang, bpf Cc: ast, andrii, daniel, martin.lau, song, yonghong.song, kernel-patches-bot On Tue, 2025-08-26 at 11:05 +0800, Leon Hwang wrote: [...] > > > diff --git a/tools/testing/selftests/bpf/progs/irq.c b/tools/testing/selftests/bpf/progs/irq.c > > > index 74d912b22de90..65a796fd1d615 100644 > > > --- a/tools/testing/selftests/bpf/progs/irq.c > > > +++ b/tools/testing/selftests/bpf/progs/irq.c > > > @@ -563,4 +563,11 @@ int irq_wrong_kfunc_class_2(struct __sk_buff *ctx) > > > return 0; > > > } > > > > > > +SEC("?tc") > > > +__success > > > > Could you please extend this test to verify generated x86 assembly > > code? (see __arch_x86_64 and __jited macro usage in verifier_tailcall_jit.c). > > I’ll try to extend it, depending on the specific x86 implementation. > > > Also, is it necessary to extend this test to actually verify returned > > value? > > Not necessary — let’s just return 0 here. I mean a bit more broadly, make the bpf program run in an interrupt and outside of the interrupt context and check the return value. If it is a small wrapper around existing kernel function probably not worth it, but you are adding custom logic with inlining. Basically same thing Alexei asked in the sibling thread. ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-09-03 5:22 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-08-25 13:14 [PATCH bpf-next v2 0/2] bpf: Introduce bpf_in_interrupt kfunc Leon Hwang 2025-08-25 13:15 ` [PATCH bpf-next v2 1/2] " Leon Hwang 2025-08-25 15:17 ` Alexei Starovoitov 2025-08-26 3:00 ` Leon Hwang 2025-08-26 22:18 ` Alexei Starovoitov 2025-09-01 15:12 ` Leon Hwang 2025-09-02 2:29 ` Alexei Starovoitov 2025-09-03 5:22 ` Leon Hwang 2025-08-25 13:15 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add case to test " Leon Hwang 2025-08-25 17:26 ` Eduard Zingerman 2025-08-26 3:05 ` Leon Hwang 2025-08-26 22:31 ` Eduard Zingerman
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).