* [RFC PATCH bpf-next 0/5] bpf: Extend bpf syscall with common attributes support
@ 2025-07-28 14:23 Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 1/5] " Leon Hwang
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Leon Hwang @ 2025-07-28 14:23 UTC (permalink / raw)
To: bpf; +Cc: ast, andrii, daniel, menglong8.dong, Leon Hwang
This proposal builds upon the discussion in
"[PATCH bpf-next v4 0/4] bpf: Improve error reporting for freplace attachment failure"[1],
and is also relevant to ongoing efforts such as tracing multi-link attach
failures[2].
This patch set introduces support for *common attributes* in the 'bpf()'
syscall, providing a unified mechanism for passing shared metadata across
all BPF commands.
The initial set of common attributes includes:
1. 'log_buf': User-provided buffer for storing log output.
2. 'log_size': Size of the provided log buffer.
3. 'log_level': Verbosity level for logging.
With this extension, the 'bpf()' syscall will be able to return meaningful
error messages (e.g., when a 'freplace' program fails to attach),
improving debuggability and user experience.
Links:
[1] https://lore.kernel.org/bpf/20250224153352.64689-1-leon.hwang@linux.dev/
[2] https://lore.kernel.org/bpf/20250703121521.1874196-1-dongml2@chinatelecom.cn/
Leon Hwang (5):
bpf: Extend bpf syscall with common attributes support
libbpf: Add support for extended bpf syscall
bpf: Report freplace attach failure reason via extended syscall
libbpf: Capture error message on freplace attach failure
selftests/bpf: Add case to test freplace attach failure log
include/uapi/linux/bpf.h | 7 +++
kernel/bpf/syscall.c | 58 +++++++++++++++----
tools/include/uapi/linux/bpf.h | 7 +++
tools/lib/bpf/bpf.c | 58 ++++++++++++++++++-
tools/lib/bpf/bpf.h | 3 +
tools/lib/bpf/features.c | 8 +++
tools/lib/bpf/libbpf.c | 18 ++++--
tools/lib/bpf/libbpf.h | 4 ++
tools/lib/bpf/libbpf.map | 3 +
tools/lib/bpf/libbpf_internal.h | 2 +
.../bpf/prog_tests/tracing_failure.c | 43 ++++++++++++++
11 files changed, 193 insertions(+), 18 deletions(-)
--
2.50.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC PATCH bpf-next 1/5] bpf: Extend bpf syscall with common attributes support
2025-07-28 14:23 [RFC PATCH bpf-next 0/5] bpf: Extend bpf syscall with common attributes support Leon Hwang
@ 2025-07-28 14:23 ` Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 2/5] libbpf: Add support for extended bpf syscall Leon Hwang
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Leon Hwang @ 2025-07-28 14:23 UTC (permalink / raw)
To: bpf; +Cc: ast, andrii, daniel, menglong8.dong, Leon Hwang
This patch extends the 'bpf()' syscall to support a set of common
attributes shared across all BPF commands:
1. 'log_buf': User-provided buffer for storing logs
2. 'log_size': Size of the log buffer
3. 'log_level': Log verbosity level
These common attributes are passed as the 4th argument to the 'bpf()'
syscall, with the 5th argument specifying the size of this structure.
To indicate the use of these common attributes from userspace, a new flag
'BPF_COMMON_ATTRS' ('1 << 16') is introduced. This flag is OR-ed into the
'cmd' field of the syscall.
When 'cmd & BPF_COMMON_ATTRS' is set, the kernel will copy the common
attributes from userspace into kernel space for use.
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
include/uapi/linux/bpf.h | 7 +++++++
kernel/bpf/syscall.c | 19 +++++++++++++++----
tools/include/uapi/linux/bpf.h | 7 +++++++
3 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 233de8677382..5014baccf065 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1474,6 +1474,13 @@ struct bpf_stack_build_id {
};
};
+struct bpf_common_attr {
+ __u64 log_buf;
+ __u32 log_size;
+ __u32 log_level;
+};
+
+#define BPF_COMMON_ATTRS (1 << 16)
#define BPF_OBJ_NAME_LEN 16U
enum {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index e63039817af3..ca7ce8474812 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -5980,8 +5980,10 @@ static int prog_stream_read(union bpf_attr *attr)
return ret;
}
-static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size)
+static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
+ bpfptr_t uattr_common, unsigned int size_common)
{
+ struct bpf_common_attr common_attrs;
union bpf_attr attr;
int err;
@@ -5995,6 +5997,14 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size)
if (copy_from_bpfptr(&attr, uattr, size) != 0)
return -EFAULT;
+ memset(&common_attrs, 0, sizeof(common_attrs));
+ if (cmd & BPF_COMMON_ATTRS) {
+ cmd &= ~BPF_COMMON_ATTRS;
+ size_common = min_t(u32, size_common, sizeof(common_attrs));
+ if (uattr_common.user && copy_from_bpfptr(&common_attrs, uattr_common, size_common))
+ return -EFAULT;
+ }
+
err = security_bpf(cmd, &attr, size, uattr.is_kernel);
if (err < 0)
return err;
@@ -6127,9 +6137,10 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size)
return err;
}
-SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
+SYSCALL_DEFINE5(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size,
+ struct bpf_common_attr __user *, uattr_common, unsigned int, size_common)
{
- return __sys_bpf(cmd, USER_BPFPTR(uattr), size);
+ return __sys_bpf(cmd, USER_BPFPTR(uattr), size, USER_BPFPTR(uattr_common), size_common);
}
static bool syscall_prog_is_valid_access(int off, int size,
@@ -6160,7 +6171,7 @@ BPF_CALL_3(bpf_sys_bpf, int, cmd, union bpf_attr *, attr, u32, attr_size)
default:
return -EINVAL;
}
- return __sys_bpf(cmd, KERNEL_BPFPTR(attr), attr_size);
+ return __sys_bpf(cmd, KERNEL_BPFPTR(attr), attr_size, KERNEL_BPFPTR(NULL), 0);
}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 233de8677382..5014baccf065 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -1474,6 +1474,13 @@ struct bpf_stack_build_id {
};
};
+struct bpf_common_attr {
+ __u64 log_buf;
+ __u32 log_size;
+ __u32 log_level;
+};
+
+#define BPF_COMMON_ATTRS (1 << 16)
#define BPF_OBJ_NAME_LEN 16U
enum {
--
2.50.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFC PATCH bpf-next 2/5] libbpf: Add support for extended bpf syscall
2025-07-28 14:23 [RFC PATCH bpf-next 0/5] bpf: Extend bpf syscall with common attributes support Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 1/5] " Leon Hwang
@ 2025-07-28 14:23 ` Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 3/5] bpf: Report freplace attach failure reason via extended syscall Leon Hwang
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Leon Hwang @ 2025-07-28 14:23 UTC (permalink / raw)
To: bpf; +Cc: ast, andrii, daniel, menglong8.dong, Leon Hwang
To support the extended 'bpf()' syscall introduced in the previous commit,
this patch adds the following APIs:
1. *Internal:*
* 'sys_bpf_extended()'
* 'sys_bpf_fd_extended()'
These wrap the raw 'syscall()' interface to support passing extended
attributes.
2. *Exported:*
* 'probe_sys_bpf_extended()'
This function checks whether the running kernel supports the extended
'bpf()' syscall with common attributes.
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
tools/lib/bpf/bpf.c | 44 +++++++++++++++++++++++++++++++++
tools/lib/bpf/bpf.h | 1 +
tools/lib/bpf/features.c | 8 ++++++
tools/lib/bpf/libbpf.map | 2 ++
tools/lib/bpf/libbpf_internal.h | 2 ++
5 files changed, 57 insertions(+)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index ab40dbf9f020..de0c5c6c8ae6 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -69,6 +69,50 @@ static inline __u64 ptr_to_u64(const void *ptr)
return (__u64) (unsigned long) ptr;
}
+static inline int sys_bpf_extended(enum bpf_cmd cmd, union bpf_attr *attr,
+ unsigned int size,
+ struct bpf_common_attr *common_attrs,
+ unsigned int size_common)
+{
+ cmd = common_attrs ? cmd | BPF_COMMON_ATTRS : cmd & ~BPF_COMMON_ATTRS;
+ return syscall(__NR_bpf, cmd, attr, size, common_attrs, size_common);
+}
+
+static inline int sys_bpf_fd_extended(enum bpf_cmd cmd, union bpf_attr *attr,
+ unsigned int size,
+ struct bpf_common_attr *common_attrs,
+ unsigned int size_common)
+{
+ int fd;
+
+ fd = sys_bpf_extended(cmd, attr, size, common_attrs, size_common);
+ return ensure_good_fd(fd);
+}
+
+int probe_sys_bpf_extended(int token_fd)
+{
+ const size_t attr_sz = offsetofend(union bpf_attr, prog_token_fd);
+ struct bpf_common_attr common_attrs;
+ struct bpf_insn insns[] = {
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ };
+ union bpf_attr attr;
+
+ memset(&attr, 0, attr_sz);
+ attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
+ attr.license = ptr_to_u64("GPL");
+ attr.insns = ptr_to_u64(insns);
+ attr.insn_cnt = (__u32)ARRAY_SIZE(insns);
+ attr.prog_token_fd = token_fd;
+ if (token_fd)
+ attr.prog_flags |= BPF_F_TOKEN_FD;
+ libbpf_strlcpy(attr.prog_name, "libbpf_sysbpftest", sizeof(attr.prog_name));
+ memset(&common_attrs, 0, sizeof(common_attrs));
+
+ return sys_bpf_fd_extended(BPF_PROG_LOAD, &attr, attr_sz, &common_attrs, sizeof(common_attrs));
+}
+
static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
unsigned int size)
{
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 7252150e7ad3..38819071ecbe 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -35,6 +35,7 @@
extern "C" {
#endif
+LIBBPF_API int probe_sys_bpf_extended(int token_fd);
LIBBPF_API int libbpf_set_memlock_rlim(size_t memlock_bytes);
struct bpf_map_create_opts {
diff --git a/tools/lib/bpf/features.c b/tools/lib/bpf/features.c
index 760657f5224c..a63172c6343d 100644
--- a/tools/lib/bpf/features.c
+++ b/tools/lib/bpf/features.c
@@ -507,6 +507,11 @@ static int probe_kern_arg_ctx_tag(int token_fd)
return probe_fd(prog_fd);
}
+static int probe_kern_extended_syscall(int token_fd)
+{
+ return probe_fd(probe_sys_bpf_extended(token_fd));
+}
+
typedef int (*feature_probe_fn)(int /* token_fd */);
static struct kern_feature_cache feature_cache;
@@ -582,6 +587,9 @@ static struct kern_feature_desc {
[FEAT_BTF_QMARK_DATASEC] = {
"BTF DATASEC names starting from '?'", probe_kern_btf_qmark_datasec,
},
+ [FEAT_EXTENDED_SYSCALL] = {
+ "Kernel supports extended syscall", probe_kern_extended_syscall,
+ },
};
bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id)
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index d7bd463e7017..83d3d1af5ed1 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -448,4 +448,6 @@ LIBBPF_1.6.0 {
} LIBBPF_1.5.0;
LIBBPF_1.7.0 {
+ global:
+ probe_sys_bpf_extended;
} LIBBPF_1.6.0;
diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
index 477a3b3389a0..497d845339a6 100644
--- a/tools/lib/bpf/libbpf_internal.h
+++ b/tools/lib/bpf/libbpf_internal.h
@@ -380,6 +380,8 @@ enum kern_feature_id {
FEAT_ARG_CTX_TAG,
/* Kernel supports '?' at the front of datasec names */
FEAT_BTF_QMARK_DATASEC,
+ /* Kernel supports extended syscall */
+ FEAT_EXTENDED_SYSCALL,
__FEAT_CNT,
};
--
2.50.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFC PATCH bpf-next 3/5] bpf: Report freplace attach failure reason via extended syscall
2025-07-28 14:23 [RFC PATCH bpf-next 0/5] bpf: Extend bpf syscall with common attributes support Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 1/5] " Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 2/5] libbpf: Add support for extended bpf syscall Leon Hwang
@ 2025-07-28 14:23 ` Leon Hwang
2025-07-31 16:32 ` Alexei Starovoitov
2025-07-28 14:23 ` [RFC PATCH bpf-next 4/5] libbpf: Capture error message on freplace attach failure Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 5/5] selftests/bpf: Add case to test freplace attach failure log Leon Hwang
4 siblings, 1 reply; 8+ messages in thread
From: Leon Hwang @ 2025-07-28 14:23 UTC (permalink / raw)
To: bpf; +Cc: ast, andrii, daniel, menglong8.dong, Leon Hwang
This patch enables detailed error reporting when a freplace program fails
to attach to its target.
By leveraging the extended 'bpf()' syscall with common attributes, users
can now retrieve the failure reason through the provided log buffer.
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
kernel/bpf/syscall.c | 39 +++++++++++++++++++++++++++++++--------
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index ca7ce8474812..4d1f58b14a0a 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -3446,7 +3446,8 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
int tgt_prog_fd,
u32 btf_id,
u64 bpf_cookie,
- enum bpf_attach_type attach_type)
+ enum bpf_attach_type attach_type,
+ struct bpf_verifier_log *log)
{
struct bpf_link_primer link_primer;
struct bpf_prog *tgt_prog = NULL;
@@ -3571,7 +3572,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
*/
struct bpf_attach_target_info tgt_info = {};
- err = bpf_check_attach_target(NULL, prog, tgt_prog, btf_id,
+ err = bpf_check_attach_target(log, prog, tgt_prog, btf_id,
&tgt_info);
if (err)
goto out_unlock;
@@ -4109,7 +4110,7 @@ static int bpf_raw_tp_link_attach(struct bpf_prog *prog,
tp_name = prog->aux->attach_func_name;
break;
}
- return bpf_tracing_prog_attach(prog, 0, 0, 0, attach_type);
+ return bpf_tracing_prog_attach(prog, 0, 0, 0, attach_type, NULL);
case BPF_PROG_TYPE_RAW_TRACEPOINT:
case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE:
if (strncpy_from_user(buf, user_tp_name, sizeof(buf) - 1) < 0)
@@ -5514,9 +5515,11 @@ static int bpf_map_do_batch(const union bpf_attr *attr,
}
#define BPF_LINK_CREATE_LAST_FIELD link_create.uprobe_multi.pid
-static int link_create(union bpf_attr *attr, bpfptr_t uattr)
+static int link_create(union bpf_attr *attr, bpfptr_t uattr, struct bpf_common_attr *common_attrs)
{
+ struct bpf_verifier_log *log = NULL;
struct bpf_prog *prog;
+ u32 log_true_size;
int ret;
if (CHECK_ATTR(BPF_LINK_CREATE))
@@ -5529,10 +5532,23 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
if (IS_ERR(prog))
return PTR_ERR(prog);
+ if (common_attrs->log_buf) {
+ log = kvzalloc(sizeof(*log), GFP_KERNEL);
+ if (!log) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ ret = bpf_vlog_init(log, BPF_LOG_FIXED,
+ (char __user *) (unsigned long) common_attrs->log_buf,
+ common_attrs->log_size);
+ if (ret)
+ goto out_free_log;
+ }
+
ret = bpf_prog_attach_check_attach_type(prog,
attr->link_create.attach_type);
if (ret)
- goto out;
+ goto out_free_log;
switch (prog->type) {
case BPF_PROG_TYPE_CGROUP_SKB:
@@ -5549,7 +5565,8 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
attr->link_create.target_fd,
attr->link_create.target_btf_id,
attr->link_create.tracing.cookie,
- attr->link_create.attach_type);
+ attr->link_create.attach_type,
+ log);
break;
case BPF_PROG_TYPE_LSM:
case BPF_PROG_TYPE_TRACING:
@@ -5569,7 +5586,8 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
attr->link_create.target_fd,
attr->link_create.target_btf_id,
attr->link_create.tracing.cookie,
- attr->link_create.attach_type);
+ attr->link_create.attach_type,
+ log);
break;
case BPF_PROG_TYPE_FLOW_DISSECTOR:
case BPF_PROG_TYPE_SK_LOOKUP:
@@ -5612,6 +5630,11 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
ret = -EINVAL;
}
+ if (ret < 0 && log)
+ (void) bpf_vlog_finalize(log, &log_true_size);
+out_free_log:
+ if (log)
+ kvfree(log);
out:
if (ret < 0)
bpf_prog_put(prog);
@@ -6099,7 +6122,7 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
err = bpf_map_do_batch(&attr, uattr.user, BPF_MAP_DELETE_BATCH);
break;
case BPF_LINK_CREATE:
- err = link_create(&attr, uattr);
+ err = link_create(&attr, uattr, &common_attrs);
break;
case BPF_LINK_UPDATE:
err = link_update(&attr);
--
2.50.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFC PATCH bpf-next 4/5] libbpf: Capture error message on freplace attach failure
2025-07-28 14:23 [RFC PATCH bpf-next 0/5] bpf: Extend bpf syscall with common attributes support Leon Hwang
` (2 preceding siblings ...)
2025-07-28 14:23 ` [RFC PATCH bpf-next 3/5] bpf: Report freplace attach failure reason via extended syscall Leon Hwang
@ 2025-07-28 14:23 ` Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 5/5] selftests/bpf: Add case to test freplace attach failure log Leon Hwang
4 siblings, 0 replies; 8+ messages in thread
From: Leon Hwang @ 2025-07-28 14:23 UTC (permalink / raw)
To: bpf; +Cc: ast, andrii, daniel, menglong8.dong, Leon Hwang
Extend 'bpf_link_create()' to support capturing log output from the kernel
when creating a freplace link.
Additionally, introduce a new API, 'bpf_program__attach_freplace_log()',
to allow users to retrieve detailed error message when a freplace program
fails to attach.
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
tools/lib/bpf/bpf.c | 14 ++++++++++++--
tools/lib/bpf/bpf.h | 2 ++
tools/lib/bpf/libbpf.c | 18 ++++++++++++++----
tools/lib/bpf/libbpf.h | 4 ++++
tools/lib/bpf/libbpf.map | 1 +
5 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index de0c5c6c8ae6..25e88219d140 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -772,6 +772,7 @@ int bpf_link_create(int prog_fd, int target_fd,
{
const size_t attr_sz = offsetofend(union bpf_attr, link_create);
__u32 target_btf_id, iter_info_len, relative_id;
+ struct bpf_common_attr common_attrs;
int fd, err, relative_fd;
union bpf_attr attr;
@@ -785,7 +786,9 @@ int bpf_link_create(int prog_fd, int target_fd,
if (iter_info_len || target_btf_id) {
if (iter_info_len && target_btf_id)
return libbpf_err(-EINVAL);
- if (!OPTS_ZEROED(opts, target_btf_id))
+ if (iter_info_len && !OPTS_ZEROED(opts, target_btf_id))
+ return libbpf_err(-EINVAL);
+ if (target_btf_id && !OPTS_ZEROED(opts, tracing.log_size))
return libbpf_err(-EINVAL);
}
@@ -795,7 +798,12 @@ int bpf_link_create(int prog_fd, int target_fd,
attr.link_create.attach_type = attach_type;
attr.link_create.flags = OPTS_GET(opts, flags, 0);
+ memset(&common_attrs, 0, sizeof(common_attrs));
if (target_btf_id) {
+ common_attrs.log_buf = (__u64) OPTS_GET(opts, tracing.log_buf, NULL);
+ common_attrs.log_size = OPTS_GET(opts, tracing.log_size, 0);
+ if (common_attrs.log_buf && !feat_supported(NULL, FEAT_EXTENDED_SYSCALL))
+ return libbpf_err(-EOPNOTSUPP);
attr.link_create.target_btf_id = target_btf_id;
goto proceed;
}
@@ -931,7 +939,9 @@ int bpf_link_create(int prog_fd, int target_fd,
break;
}
proceed:
- fd = sys_bpf_fd(BPF_LINK_CREATE, &attr, attr_sz);
+ fd = !common_attrs.log_buf ? sys_bpf_fd(BPF_LINK_CREATE, &attr, attr_sz)
+ : sys_bpf_fd_extended(BPF_LINK_CREATE, &attr, attr_sz,
+ &common_attrs, sizeof(common_attrs));
if (fd >= 0)
return fd;
/* we'll get EINVAL if LINK_CREATE doesn't support attaching fentry
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 38819071ecbe..5720d3e3df76 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -422,6 +422,8 @@ struct bpf_link_create_opts {
} uprobe_multi;
struct {
__u64 cookie;
+ const char *log_buf;
+ unsigned int log_size;
} tracing;
struct {
__u32 pf;
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index e067cb5776bd..9748466691f3 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -12949,9 +12949,11 @@ bpf_program__attach_netkit(const struct bpf_program *prog, int ifindex,
return bpf_program_attach_fd(prog, ifindex, "netkit", &link_create_opts);
}
-struct bpf_link *bpf_program__attach_freplace(const struct bpf_program *prog,
- int target_fd,
- const char *attach_func_name)
+struct bpf_link *bpf_program__attach_freplace_log(const struct bpf_program *prog,
+ int target_fd,
+ const char *attach_func_name,
+ const char *log_buf,
+ unsigned int log_size)
{
int btf_id;
@@ -12975,7 +12977,8 @@ struct bpf_link *bpf_program__attach_freplace(const struct bpf_program *prog,
return libbpf_err_ptr(btf_id);
target_opts.target_btf_id = btf_id;
-
+ target_opts.tracing.log_buf = log_buf;
+ target_opts.tracing.log_size = log_size;
return bpf_program_attach_fd(prog, target_fd, "freplace",
&target_opts);
} else {
@@ -12986,6 +12989,13 @@ struct bpf_link *bpf_program__attach_freplace(const struct bpf_program *prog,
}
}
+struct bpf_link *bpf_program__attach_freplace(const struct bpf_program *prog,
+ int target_fd,
+ const char *attach_func_name)
+{
+ return bpf_program__attach_freplace_log(prog, target_fd, attach_func_name, NULL, 0);
+}
+
struct bpf_link *
bpf_program__attach_iter(const struct bpf_program *prog,
const struct bpf_iter_attach_opts *opts)
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index d1cf813a057b..01a0bf76adf5 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -829,6 +829,10 @@ bpf_program__attach_sockmap(const struct bpf_program *prog, int map_fd);
LIBBPF_API struct bpf_link *
bpf_program__attach_xdp(const struct bpf_program *prog, int ifindex);
LIBBPF_API struct bpf_link *
+bpf_program__attach_freplace_log(const struct bpf_program *prog,
+ int target_fd, const char *attach_func_name,
+ const char *log_buf, unsigned int log_size);
+LIBBPF_API struct bpf_link *
bpf_program__attach_freplace(const struct bpf_program *prog,
int target_fd, const char *attach_func_name);
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 83d3d1af5ed1..25cd2d54b7d9 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -449,5 +449,6 @@ LIBBPF_1.6.0 {
LIBBPF_1.7.0 {
global:
+ bpf_program__attach_freplace_log;
probe_sys_bpf_extended;
} LIBBPF_1.6.0;
--
2.50.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFC PATCH bpf-next 5/5] selftests/bpf: Add case to test freplace attach failure log
2025-07-28 14:23 [RFC PATCH bpf-next 0/5] bpf: Extend bpf syscall with common attributes support Leon Hwang
` (3 preceding siblings ...)
2025-07-28 14:23 ` [RFC PATCH bpf-next 4/5] libbpf: Capture error message on freplace attach failure Leon Hwang
@ 2025-07-28 14:23 ` Leon Hwang
4 siblings, 0 replies; 8+ messages in thread
From: Leon Hwang @ 2025-07-28 14:23 UTC (permalink / raw)
To: bpf; +Cc: ast, andrii, daniel, menglong8.dong, Leon Hwang
Test the new libbpf API 'bpf_program__attach_freplace_log()':
cd tools/testing/selftests/bpf/
./test_progs -t tracing_failure/freplace_attach_log
#468/3 tracing_failure/freplace_attach_log:OK
#468 tracing_failure:OK
Summary: 1/1 PASSED, 0 SKIPPED, 0 FAILED
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
.../bpf/prog_tests/tracing_failure.c | 43 +++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_failure.c b/tools/testing/selftests/bpf/prog_tests/tracing_failure.c
index a222df765bc3..05c3a5a9db2a 100644
--- a/tools/testing/selftests/bpf/prog_tests/tracing_failure.c
+++ b/tools/testing/selftests/bpf/prog_tests/tracing_failure.c
@@ -2,6 +2,8 @@
/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
#include <test_progs.h>
#include "tracing_failure.skel.h"
+#include "tailcall_bpf2bpf1.skel.h"
+#include "freplace_global_func.skel.h"
static void test_bpf_spin_lock(bool is_spin_lock)
{
@@ -28,10 +30,51 @@ static void test_bpf_spin_lock(bool is_spin_lock)
tracing_failure__destroy(skel);
}
+static void test_freplace_attach_log(void)
+{
+ struct freplace_global_func *freplace_skel = NULL;
+ struct tailcall_bpf2bpf1 *tailcall_skel = NULL;
+ struct bpf_link *freplace_link = NULL;
+ struct bpf_program *prog;
+ char log_buf[64];
+ int err, prog_fd;
+
+ tailcall_skel = tailcall_bpf2bpf1__open_and_load();
+ if (!ASSERT_OK_PTR(tailcall_skel, "tailcall_bpf2bpf1__open_and_load"))
+ return;
+
+ freplace_skel = freplace_global_func__open();
+ if (!ASSERT_OK_PTR(freplace_skel, "freplace_global_func__open"))
+ goto out;
+
+ prog = freplace_skel->progs.new_test_pkt_access;
+ prog_fd = bpf_program__fd(tailcall_skel->progs.entry);
+ err = bpf_program__set_attach_target(prog, prog_fd, "entry");
+ if (!ASSERT_OK(err, "bpf_program__set_attach_target"))
+ goto out;
+
+ err = freplace_global_func__load(freplace_skel);
+ if (!ASSERT_OK(err, "freplace_global_func__load"))
+ goto out;
+
+ log_buf[0] = '\0';
+ freplace_link = bpf_program__attach_freplace_log(prog, prog_fd, "subprog_tail", log_buf,
+ sizeof(log_buf));
+ ASSERT_ERR_PTR(freplace_link, "bpf_program__attach_freplace_log");
+ ASSERT_STREQ(log_buf, "subprog_tail() is not a global function\n", "log_buf");
+
+out:
+ bpf_link__destroy(freplace_link);
+ freplace_global_func__destroy(freplace_skel);
+ tailcall_bpf2bpf1__destroy(tailcall_skel);
+}
+
void test_tracing_failure(void)
{
if (test__start_subtest("bpf_spin_lock"))
test_bpf_spin_lock(true);
if (test__start_subtest("bpf_spin_unlock"))
test_bpf_spin_lock(false);
+ if (test__start_subtest("freplace_attach_log"))
+ test_freplace_attach_log();
}
--
2.50.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [RFC PATCH bpf-next 3/5] bpf: Report freplace attach failure reason via extended syscall
2025-07-28 14:23 ` [RFC PATCH bpf-next 3/5] bpf: Report freplace attach failure reason via extended syscall Leon Hwang
@ 2025-07-31 16:32 ` Alexei Starovoitov
2025-08-01 13:45 ` Leon Hwang
0 siblings, 1 reply; 8+ messages in thread
From: Alexei Starovoitov @ 2025-07-31 16:32 UTC (permalink / raw)
To: Leon Hwang
Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Menglong Dong
On Mon, Jul 28, 2025 at 7:24 AM Leon Hwang <leon.hwang@linux.dev> wrote:
>
> This patch enables detailed error reporting when a freplace program fails
> to attach to its target.
>
> By leveraging the extended 'bpf()' syscall with common attributes, users
> can now retrieve the failure reason through the provided log buffer.
>
> Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
> ---
> kernel/bpf/syscall.c | 39 +++++++++++++++++++++++++++++++--------
> 1 file changed, 31 insertions(+), 8 deletions(-)
>
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index ca7ce8474812..4d1f58b14a0a 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -3446,7 +3446,8 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
> int tgt_prog_fd,
> u32 btf_id,
> u64 bpf_cookie,
> - enum bpf_attach_type attach_type)
> + enum bpf_attach_type attach_type,
> + struct bpf_verifier_log *log)
Same issue as before.
Nack on adding new uapi for the sole purpose of freplace.
Patches 1 and 2 are fine, but must follow with patch(es) that
make common_attrs usable for existing commands like prog_load and btf_load.
We need to decide what to do when prog_load's log_buf conflicts
with common_attrs.log_buf.
I think it's ok if they both specified and are exactly the same.
If one of them is specified and another is zero it's also ok.
When they conflict it's an EINVAL or, maybe, EUSERS to make it distinct.
After that map_create cmd should adopt log and disambiguate all EINVAL-s
into human readable messages.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH bpf-next 3/5] bpf: Report freplace attach failure reason via extended syscall
2025-07-31 16:32 ` Alexei Starovoitov
@ 2025-08-01 13:45 ` Leon Hwang
0 siblings, 0 replies; 8+ messages in thread
From: Leon Hwang @ 2025-08-01 13:45 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Menglong Dong
On 2025/8/1 00:32, Alexei Starovoitov wrote:
> On Mon, Jul 28, 2025 at 7:24 AM Leon Hwang <leon.hwang@linux.dev> wrote:
>>
>> This patch enables detailed error reporting when a freplace program fails
>> to attach to its target.
>>
>> By leveraging the extended 'bpf()' syscall with common attributes, users
>> can now retrieve the failure reason through the provided log buffer.
>>
>> Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
>> ---
>> kernel/bpf/syscall.c | 39 +++++++++++++++++++++++++++++++--------
>> 1 file changed, 31 insertions(+), 8 deletions(-)
>>
>> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
>> index ca7ce8474812..4d1f58b14a0a 100644
>> --- a/kernel/bpf/syscall.c
>> +++ b/kernel/bpf/syscall.c
>> @@ -3446,7 +3446,8 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
>> int tgt_prog_fd,
>> u32 btf_id,
>> u64 bpf_cookie,
>> - enum bpf_attach_type attach_type)
>> + enum bpf_attach_type attach_type,
>> + struct bpf_verifier_log *log)
>
> Same issue as before.
> Nack on adding new uapi for the sole purpose of freplace.
>
Got it.
> Patches 1 and 2 are fine, but must follow with patch(es) that
> make common_attrs usable for existing commands like prog_load and btf_load.
> We need to decide what to do when prog_load's log_buf conflicts
> with common_attrs.log_buf.
> I think it's ok if they both specified and are exactly the same.
> If one of them is specified and another is zero it's also ok.
> When they conflict it's an EINVAL or, maybe, EUSERS to make it distinct.
> After that map_create cmd should adopt log and disambiguate all EINVAL-s
> into human readable messages.
Let me have a try.
Thanks,
Leon
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-08-01 13:45 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-28 14:23 [RFC PATCH bpf-next 0/5] bpf: Extend bpf syscall with common attributes support Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 1/5] " Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 2/5] libbpf: Add support for extended bpf syscall Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 3/5] bpf: Report freplace attach failure reason via extended syscall Leon Hwang
2025-07-31 16:32 ` Alexei Starovoitov
2025-08-01 13:45 ` Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 4/5] libbpf: Capture error message on freplace attach failure Leon Hwang
2025-07-28 14:23 ` [RFC PATCH bpf-next 5/5] selftests/bpf: Add case to test freplace attach failure log Leon Hwang
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).