From 4d641d5523d8143b7ba3006ad573ddf106de8f6d Mon Sep 17 00:00:00 2001 From: Kavya Shekar Date: Mon, 12 May 2025 21:09:09 +0000 Subject: [PATCH 1/5] feat: new prog type `BPF_PROG_TYPE_KTHREAD` and new attach type `BPF_KTHREAD` --- include/linux/bpf_types.h | 2 ++ include/uapi/linux/bpf.h | 2 ++ kernel/bpf/syscall.c | 17 ++++++++++++++--- kernel/trace/bpf_trace.c | 7 +++++++ tools/bpf/bpftool/prog.c | 11 ++++++----- tools/include/uapi/linux/bpf.h | 1 + tools/lib/bpf/libbpf.c | 4 ++++ 7 files changed, 36 insertions(+), 8 deletions(-) diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h index fa78f49d4a9a64..6d851da9cb7202 100644 --- a/include/linux/bpf_types.h +++ b/include/linux/bpf_types.h @@ -83,6 +83,8 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_SYSCALL, bpf_syscall, BPF_PROG_TYPE(BPF_PROG_TYPE_NETFILTER, netfilter, struct bpf_nf_ctx, struct bpf_nf_ctx) #endif +BPF_PROG_TYPE(BPF_PROG_TYPE_KTHREAD, kthread, + void *, void *) BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_ARRAY, percpu_array_map_ops) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 4a939c90dc2e4b..78c6220fe40dbc 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -1055,6 +1055,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_SK_LOOKUP, BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ BPF_PROG_TYPE_NETFILTER, + BPF_PROG_TYPE_KTHREAD, __MAX_BPF_PROG_TYPE }; @@ -1116,6 +1117,7 @@ enum bpf_attach_type { BPF_NETKIT_PRIMARY, BPF_NETKIT_PEER, BPF_TRACE_KPROBE_SESSION, + BPF_KTHREAD, __MAX_BPF_ATTACH_TYPE }; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index c5aa127ed4cc01..b57e80a540e401 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -2843,9 +2843,10 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size) goto free_prog_sec; /* run eBPF verifier */ - err = bpf_check(&prog, attr, uattr, uattr_size); - if (err < 0) - goto free_used_maps; + // err = bpf_check(&prog, attr, uattr, uattr_size); + // if (err < 0) + // goto free_used_maps; + pr_info("[bpf/syscall.c] Skipping BPF verification\n"); prog = bpf_prog_select_runtime(prog, &err); if (err < 0) @@ -3951,6 +3952,8 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type) case BPF_NETKIT_PRIMARY: case BPF_NETKIT_PEER: return BPF_PROG_TYPE_SCHED_CLS; + case BPF_TRACE_KPROBE_SESSION+1: + return BPF_PROG_TYPE_KTHREAD; default: return BPF_PROG_TYPE_UNSPEC; } @@ -4070,6 +4073,10 @@ static int bpf_prog_attach(const union bpf_attr *attr) } switch (ptype) { + case BPF_PROG_TYPE_KTHREAD: + pr_info("TODO: init and start the workqueue\n"); + ret = 0; + break; case BPF_PROG_TYPE_SK_SKB: case BPF_PROG_TYPE_SK_MSG: ret = sock_map_get_from_fd(attr, prog); @@ -4139,6 +4146,10 @@ static int bpf_prog_detach(const union bpf_attr *attr) } switch (ptype) { + case BPF_PROG_TYPE_KTHREAD: + pr_info("TODO: stop and free the workqueue\n"); + ret = 0; + break; case BPF_PROG_TYPE_SK_MSG: case BPF_PROG_TYPE_SK_SKB: ret = sock_map_prog_detach(attr, ptype); diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 630b763e52402f..49ede154837470 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -2051,6 +2051,13 @@ const struct bpf_prog_ops tracing_prog_ops = { .test_run = bpf_prog_test_run_tracing, }; +const struct bpf_verifier_ops kthread_verifier_ops = { +}; + +const struct bpf_prog_ops kthread_prog_ops = { + .test_run = bpf_prog_test_run_tracing, +}; + static bool raw_tp_writable_prog_is_valid_access(int off, int size, enum bpf_access_type type, const struct bpf_prog *prog, diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 2ff949ea82fa66..b7a935c5e471c3 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -49,7 +49,8 @@ static const bool attach_types[] = { [BPF_SK_SKB_VERDICT] = true, [BPF_SK_MSG_VERDICT] = true, [BPF_FLOW_DISSECTOR] = true, - [__MAX_BPF_ATTACH_TYPE] = false, + [BPF_TRACE_KPROBE_SESSION+1] = true, + [__MAX_BPF_ATTACH_TYPE+1] = false, }; /* Textual representations traditionally used by the program and kept around @@ -60,7 +61,7 @@ static const char * const attach_type_strings[] = { [BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict", [BPF_SK_SKB_VERDICT] = "skb_verdict", [BPF_SK_MSG_VERDICT] = "msg_verdict", - [__MAX_BPF_ATTACH_TYPE] = NULL, + [__MAX_BPF_ATTACH_TYPE+1] = NULL, }; static struct hashmap *prog_table; @@ -69,7 +70,7 @@ static enum bpf_attach_type parse_attach_type(const char *str) { enum bpf_attach_type type; - for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) { + for (type = 0; type < __MAX_BPF_ATTACH_TYPE+1; type++) { if (attach_types[type]) { const char *attach_type_str; @@ -1041,12 +1042,12 @@ static int parse_attach_detach_args(int argc, char **argv, int *progfd, return *progfd; *attach_type = parse_attach_type(*argv); - if (*attach_type == __MAX_BPF_ATTACH_TYPE) { + if (*attach_type == __MAX_BPF_ATTACH_TYPE+1) { p_err("invalid attach/detach type"); return -EINVAL; } - if (*attach_type == BPF_FLOW_DISSECTOR) { + if (*attach_type == BPF_FLOW_DISSECTOR || *attach_type == BPF_TRACE_KPROBE_SESSION+1) { *mapfd = 0; return 0; } diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 4a939c90dc2e4b..f699a5cdba96cb 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -1055,6 +1055,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_SK_LOOKUP, BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ BPF_PROG_TYPE_NETFILTER, + BPF_PROG_TYPE_KTHREAD, __MAX_BPF_PROG_TYPE }; diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 219facd0e66e8b..5dd7f3620d0da6 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -133,6 +133,7 @@ static const char * const attach_type_name[] = { [BPF_NETKIT_PRIMARY] = "netkit_primary", [BPF_NETKIT_PEER] = "netkit_peer", [BPF_TRACE_KPROBE_SESSION] = "trace_kprobe_session", + [BPF_TRACE_KPROBE_SESSION + 1] = "kthread", }; static const char * const link_type_name[] = { @@ -224,6 +225,7 @@ static const char * const prog_type_name[] = { [BPF_PROG_TYPE_SK_LOOKUP] = "sk_lookup", [BPF_PROG_TYPE_SYSCALL] = "syscall", [BPF_PROG_TYPE_NETFILTER] = "netfilter", + [BPF_PROG_TYPE_KTHREAD] = "kthread", }; static int __base_pr(enum libbpf_print_level level, const char *format, @@ -7518,6 +7520,7 @@ static int bpf_object_load_prog(struct bpf_object *obj, struct bpf_program *prog load_attr.log_level = log_level; ret = bpf_prog_load(prog->type, prog_name, license, insns, insns_cnt, &load_attr); + if (ret >= 0) { if (log_level && own_log_buf) { pr_debug("prog '%s': -- BEGIN PROG LOAD LOG --\n%s-- END PROG LOAD LOG --\n", @@ -9457,6 +9460,7 @@ static const struct bpf_sec_def section_defs[] = { SEC_DEF("struct_ops.s+", STRUCT_OPS, 0, SEC_SLEEPABLE), SEC_DEF("sk_lookup", SK_LOOKUP, BPF_SK_LOOKUP, SEC_ATTACHABLE), SEC_DEF("netfilter", NETFILTER, BPF_NETFILTER, SEC_NONE), + SEC_DEF("kthread", KTHREAD, 0, SEC_SLEEPABLE), }; int libbpf_register_prog_handler(const char *sec, From 41dbb012720a279137efac54d913065f917eb4fe Mon Sep 17 00:00:00 2001 From: Kavya Shekar Date: Tue, 13 May 2025 02:28:53 +0000 Subject: [PATCH 2/5] feat: support for scheduling of BPF programs using work-queues --- include/linux/bpf.h | 7 ++++ kernel/bpf/Makefile | 1 + kernel/bpf/bpf_kthread.c | 79 ++++++++++++++++++++++++++++++++++++++++ kernel/bpf/bpf_kthread.h | 16 ++++++++ kernel/bpf/syscall.c | 17 ++++++--- kernel/trace/bpf_trace.c | 2 +- 6 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 kernel/bpf/bpf_kthread.c create mode 100644 kernel/bpf/bpf_kthread.h diff --git a/include/linux/bpf.h b/include/linux/bpf.h index bdadb0bb6cecd1..c6f653a5e00510 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1585,6 +1585,13 @@ struct bpf_prog { const struct bpf_insn *insn); struct bpf_prog_aux *aux; /* Auxiliary fields */ struct sock_fprog_kern *orig_prog; /* Original BPF program */ + + /* Additions to support BPF_PROG_TYPE_KTHREAD */ + + struct work_struct sched_work; + ktime_t sched_period; + struct hrtimer sched_timer; + /* Instructions for interpreter */ union { DECLARE_FLEX_ARRAY(struct sock_filter, insns); diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile index 9b9c151b5c826b..29f7de68dc518d 100644 --- a/kernel/bpf/Makefile +++ b/kernel/bpf/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_BPF_SYSCALL) += cpumap.o obj-$(CONFIG_BPF_SYSCALL) += offload.o obj-$(CONFIG_BPF_SYSCALL) += net_namespace.o obj-$(CONFIG_BPF_SYSCALL) += tcx.o +obj-$(CONFIG_BPF_SYSCALL) += bpf_kthread.o endif ifeq ($(CONFIG_PERF_EVENTS),y) obj-$(CONFIG_BPF_SYSCALL) += stackmap.o diff --git a/kernel/bpf/bpf_kthread.c b/kernel/bpf/bpf_kthread.c new file mode 100644 index 00000000000000..a3671fb82b93f2 --- /dev/null +++ b/kernel/bpf/bpf_kthread.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2016 Facebook + */ +#include +#include +#include +#include +#include +#include + +#include "bpf_kthread.h" + +static struct workqueue_struct *bpf_kthread_wq; + +/* Work function for schedulable BPF programs */ +void bpf_kthread_program_run(struct work_struct *work) +{ + pr_info("workqueue item callback\n"); + struct bpf_prog *prog = container_of(work, struct bpf_prog, sched_work); + unsigned long dummy_ctx = 0; + pr_info("bpf_prog_run()\n"); + int ret = bpf_prog_run(prog, &dummy_ctx); + + /* Handle the return value if necessary */ + if (ret != 0) { + pr_warn("BPF program %d failed, returned non-zero value %d\n", + prog->aux->id, ret); + } + + pr_info("restarting hrtimer\n"); + /* Reschedule the timer*/ + hrtimer_start(&prog->sched_timer, ktime_set(1, 0), HRTIMER_MODE_REL); +} + +enum hrtimer_restart bpf_kthread_timer_callback(struct hrtimer *timer) +{ + pr_info("hrtimer callback...queuing workqueue item\n"); + struct bpf_prog *prog = container_of(timer, struct bpf_prog, sched_timer); + queue_work(bpf_kthread_wq, &prog->sched_work); + + /* The timer is restarted in the work function for periodic jobs */ + return HRTIMER_NORESTART; +} + +int bpf_kthread_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog) +{ + pr_info("Attaching BPF program\n"); + if(!bpf_kthread_wq) { + pr_info("Init workqueue\n"); + bpf_kthread_wq = alloc_workqueue("bpf_sched_wq", 0, 0); + if (!bpf_kthread_wq) { + pr_err("Failed to create bpf_sched_wq\n"); + return -ENOMEM; + } + } + + pr_info("Init hrtimer\n"); + hrtimer_init(&prog->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + prog->sched_timer.function = bpf_kthread_timer_callback; + hrtimer_start(&prog->sched_timer, ktime_set(1, 0), HRTIMER_MODE_REL); + + INIT_WORK(&prog->sched_work, bpf_kthread_program_run); + + return 0; +} + +int bpf_kthread_prog_detach(const union bpf_attr *attr, struct bpf_prog *prog) +{ + /* Stop timer to stop periodic schedule */ + hrtimer_cancel(&prog->sched_timer); + + /* Not stopping an running work ... for now */ + // cancel_work_sync(&prog->sched_work); + + /* Not bothering to clean up ... for now */ + // bpf_prog_put(prog); + + return 0; +} diff --git a/kernel/bpf/bpf_kthread.h b/kernel/bpf/bpf_kthread.h new file mode 100644 index 00000000000000..cdd8e087096cf5 --- /dev/null +++ b/kernel/bpf/bpf_kthread.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2023 Isovalent */ +#ifndef __BPF_KTHREAD_H +#define __BPF_KTHREAD_H + +#include +#include +#include + +int bpf_kthread_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog); +int bpf_kthread_prog_detach(const union bpf_attr *attr, struct bpf_prog *prog); + +void bpf_kthread_program_run(struct work_struct *work); +enum hrtimer_restart bpf_kthread_timer_callback(struct hrtimer *timer); + +#endif /* __BPF_KTHREAD_H */ diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index b57e80a540e401..6ae79ba03092f0 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -39,6 +39,7 @@ #include #include #include +#include "bpf_kthread.h" #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \ (map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \ @@ -4074,8 +4075,7 @@ static int bpf_prog_attach(const union bpf_attr *attr) switch (ptype) { case BPF_PROG_TYPE_KTHREAD: - pr_info("TODO: init and start the workqueue\n"); - ret = 0; + ret = bpf_kthread_prog_attach(attr, prog); break; case BPF_PROG_TYPE_SK_SKB: case BPF_PROG_TYPE_SK_MSG: @@ -4145,10 +4145,13 @@ static int bpf_prog_detach(const union bpf_attr *attr) return -EINVAL; } + prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype); + if (IS_ERR(prog)) + return PTR_ERR(prog); + switch (ptype) { case BPF_PROG_TYPE_KTHREAD: - pr_info("TODO: stop and free the workqueue\n"); - ret = 0; + ret = bpf_kthread_prog_detach(attr, prog); break; case BPF_PROG_TYPE_SK_MSG: case BPF_PROG_TYPE_SK_SKB: @@ -4255,6 +4258,7 @@ static int bpf_prog_query(const union bpf_attr *attr, static int bpf_prog_test_run(const union bpf_attr *attr, union bpf_attr __user *uattr) { + pr_info("Test run begins...\n"); struct bpf_prog *prog; int ret = -ENOTSUPP; @@ -5634,8 +5638,10 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size) /* copy attributes from user space, may be less than sizeof(bpf_attr) */ memset(&attr, 0, sizeof(attr)); - if (copy_from_bpfptr(&attr, uattr, size) != 0) + if (copy_from_bpfptr(&attr, uattr, size) != 0){ + pr_err("[bpf/syscall.c] L-5641: Unable to copy bpf attributes from user space\n"); return -EFAULT; + } err = security_bpf(cmd, &attr, size); if (err < 0) @@ -5679,6 +5685,7 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size) err = bpf_prog_query(&attr, uattr.user); break; case BPF_PROG_TEST_RUN: + pr_info("Test run triggered...\n"); err = bpf_prog_test_run(&attr, uattr.user); break; case BPF_PROG_GET_NEXT_ID: diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 49ede154837470..8bf13d7a776b93 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -2055,7 +2055,7 @@ const struct bpf_verifier_ops kthread_verifier_ops = { }; const struct bpf_prog_ops kthread_prog_ops = { - .test_run = bpf_prog_test_run_tracing, + .test_run = bpf_prog_test_run_xdp, }; static bool raw_tp_writable_prog_is_valid_access(int off, int size, From 9888b70cb65d84fc48ecdae433bd6a15bd672dea Mon Sep 17 00:00:00 2001 From: Kavya Shekar Date: Tue, 13 May 2025 03:31:56 +0000 Subject: [PATCH 3/5] fix: verifier_ops for `BPF_PROG_TYPE_KTHREAD` --- kernel/bpf/syscall.c | 7 +++---- kernel/trace/bpf_trace.c | 10 ++++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 6ae79ba03092f0..86e52561231781 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -2844,10 +2844,9 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size) goto free_prog_sec; /* run eBPF verifier */ - // err = bpf_check(&prog, attr, uattr, uattr_size); - // if (err < 0) - // goto free_used_maps; - pr_info("[bpf/syscall.c] Skipping BPF verification\n"); + err = bpf_check(&prog, attr, uattr, uattr_size); + if (err < 0) + goto free_used_maps; prog = bpf_prog_select_runtime(prog, &err); if (err < 0) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 8bf13d7a776b93..a5f92d3f099eba 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -2051,7 +2051,17 @@ const struct bpf_prog_ops tracing_prog_ops = { .test_run = bpf_prog_test_run_tracing, }; +static bool kthread_prog_is_valid_access(int off, int size, + enum bpf_access_type type, + const struct bpf_prog *prog, + struct bpf_insn_access_aux *info) +{ + return true; +} + const struct bpf_verifier_ops kthread_verifier_ops = { + .get_func_proto = bpf_base_func_proto, + .is_valid_access = kthread_prog_is_valid_access, }; const struct bpf_prog_ops kthread_prog_ops = { From 1ea7ff20ae7d082b7d58c3d47496ab2d69050a37 Mon Sep 17 00:00:00 2001 From: Kavya Shekar Date: Tue, 13 May 2025 15:36:34 +0000 Subject: [PATCH 4/5] fix: do not queue pending work_struct + remove debug lines --- kernel/bpf/bpf_kthread.c | 25 ++++++++++++------------- kernel/bpf/syscall.c | 2 -- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/kernel/bpf/bpf_kthread.c b/kernel/bpf/bpf_kthread.c index a3671fb82b93f2..352fd2b132ba21 100644 --- a/kernel/bpf/bpf_kthread.c +++ b/kernel/bpf/bpf_kthread.c @@ -15,10 +15,8 @@ static struct workqueue_struct *bpf_kthread_wq; /* Work function for schedulable BPF programs */ void bpf_kthread_program_run(struct work_struct *work) { - pr_info("workqueue item callback\n"); struct bpf_prog *prog = container_of(work, struct bpf_prog, sched_work); unsigned long dummy_ctx = 0; - pr_info("bpf_prog_run()\n"); int ret = bpf_prog_run(prog, &dummy_ctx); /* Handle the return value if necessary */ @@ -27,15 +25,18 @@ void bpf_kthread_program_run(struct work_struct *work) prog->aux->id, ret); } - pr_info("restarting hrtimer\n"); /* Reschedule the timer*/ - hrtimer_start(&prog->sched_timer, ktime_set(1, 0), HRTIMER_MODE_REL); + hrtimer_start(&prog->sched_timer, ktime_set(0, 100000000), HRTIMER_MODE_REL); } enum hrtimer_restart bpf_kthread_timer_callback(struct hrtimer *timer) { - pr_info("hrtimer callback...queuing workqueue item\n"); struct bpf_prog *prog = container_of(timer, struct bpf_prog, sched_timer); + + // Work is already pending, do not queue it again. + if (work_pending(&prog->sched_work)) + return HRTIMER_NORESTART; + queue_work(bpf_kthread_wq, &prog->sched_work); /* The timer is restarted in the work function for periodic jobs */ @@ -44,9 +45,8 @@ enum hrtimer_restart bpf_kthread_timer_callback(struct hrtimer *timer) int bpf_kthread_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog) { - pr_info("Attaching BPF program\n"); if(!bpf_kthread_wq) { - pr_info("Init workqueue\n"); + pr_info("Init BPF workqueue\n"); bpf_kthread_wq = alloc_workqueue("bpf_sched_wq", 0, 0); if (!bpf_kthread_wq) { pr_err("Failed to create bpf_sched_wq\n"); @@ -54,10 +54,9 @@ int bpf_kthread_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog) } } - pr_info("Init hrtimer\n"); hrtimer_init(&prog->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); prog->sched_timer.function = bpf_kthread_timer_callback; - hrtimer_start(&prog->sched_timer, ktime_set(1, 0), HRTIMER_MODE_REL); + hrtimer_start(&prog->sched_timer, ktime_set(0, 100000000), HRTIMER_MODE_REL); INIT_WORK(&prog->sched_work, bpf_kthread_program_run); @@ -69,11 +68,11 @@ int bpf_kthread_prog_detach(const union bpf_attr *attr, struct bpf_prog *prog) /* Stop timer to stop periodic schedule */ hrtimer_cancel(&prog->sched_timer); - /* Not stopping an running work ... for now */ - // cancel_work_sync(&prog->sched_work); + /* Stop any running work_struct */ + cancel_work_sync(&prog->sched_work); - /* Not bothering to clean up ... for now */ - // bpf_prog_put(prog); + /* Clean up program reference */ + bpf_prog_put(prog); return 0; } diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 86e52561231781..c42da379ac6f4c 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -4257,7 +4257,6 @@ static int bpf_prog_query(const union bpf_attr *attr, static int bpf_prog_test_run(const union bpf_attr *attr, union bpf_attr __user *uattr) { - pr_info("Test run begins...\n"); struct bpf_prog *prog; int ret = -ENOTSUPP; @@ -5684,7 +5683,6 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size) err = bpf_prog_query(&attr, uattr.user); break; case BPF_PROG_TEST_RUN: - pr_info("Test run triggered...\n"); err = bpf_prog_test_run(&attr, uattr.user); break; case BPF_PROG_GET_NEXT_ID: From 65da302a7adfa40ac1c69035f0542b1151d458d4 Mon Sep 17 00:00:00 2001 From: Kavya Shekar Date: Wed, 14 May 2025 07:18:56 +0000 Subject: [PATCH 5/5] fix: `BPF_KTHREAD` included in libbpf --- kernel/bpf/syscall.c | 2 +- tools/bpf/bpftool/prog.c | 12 ++++++------ tools/include/uapi/linux/bpf.h | 1 + tools/lib/bpf/libbpf.c | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index c42da379ac6f4c..d8e76f560b4b2a 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -3952,7 +3952,7 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type) case BPF_NETKIT_PRIMARY: case BPF_NETKIT_PEER: return BPF_PROG_TYPE_SCHED_CLS; - case BPF_TRACE_KPROBE_SESSION+1: + case BPF_KTHREAD: return BPF_PROG_TYPE_KTHREAD; default: return BPF_PROG_TYPE_UNSPEC; diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index b7a935c5e471c3..a5bab75b139755 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -49,8 +49,8 @@ static const bool attach_types[] = { [BPF_SK_SKB_VERDICT] = true, [BPF_SK_MSG_VERDICT] = true, [BPF_FLOW_DISSECTOR] = true, - [BPF_TRACE_KPROBE_SESSION+1] = true, - [__MAX_BPF_ATTACH_TYPE+1] = false, + [BPF_KTHREAD] = true, + [__MAX_BPF_ATTACH_TYPE] = false, }; /* Textual representations traditionally used by the program and kept around @@ -61,7 +61,7 @@ static const char * const attach_type_strings[] = { [BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict", [BPF_SK_SKB_VERDICT] = "skb_verdict", [BPF_SK_MSG_VERDICT] = "msg_verdict", - [__MAX_BPF_ATTACH_TYPE+1] = NULL, + [__MAX_BPF_ATTACH_TYPE] = NULL, }; static struct hashmap *prog_table; @@ -70,7 +70,7 @@ static enum bpf_attach_type parse_attach_type(const char *str) { enum bpf_attach_type type; - for (type = 0; type < __MAX_BPF_ATTACH_TYPE+1; type++) { + for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) { if (attach_types[type]) { const char *attach_type_str; @@ -1042,12 +1042,12 @@ static int parse_attach_detach_args(int argc, char **argv, int *progfd, return *progfd; *attach_type = parse_attach_type(*argv); - if (*attach_type == __MAX_BPF_ATTACH_TYPE+1) { + if (*attach_type == __MAX_BPF_ATTACH_TYPE) { p_err("invalid attach/detach type"); return -EINVAL; } - if (*attach_type == BPF_FLOW_DISSECTOR || *attach_type == BPF_TRACE_KPROBE_SESSION+1) { + if (*attach_type == BPF_FLOW_DISSECTOR || *attach_type == BPF_KTHREAD) { *mapfd = 0; return 0; } diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index f699a5cdba96cb..78c6220fe40dbc 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -1117,6 +1117,7 @@ enum bpf_attach_type { BPF_NETKIT_PRIMARY, BPF_NETKIT_PEER, BPF_TRACE_KPROBE_SESSION, + BPF_KTHREAD, __MAX_BPF_ATTACH_TYPE }; diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 5dd7f3620d0da6..9a21664296bf63 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -133,7 +133,7 @@ static const char * const attach_type_name[] = { [BPF_NETKIT_PRIMARY] = "netkit_primary", [BPF_NETKIT_PEER] = "netkit_peer", [BPF_TRACE_KPROBE_SESSION] = "trace_kprobe_session", - [BPF_TRACE_KPROBE_SESSION + 1] = "kthread", + [BPF_KTHREAD] = "kthread", }; static const char * const link_type_name[] = {