Skip to content

Commit 0ee52c0

Browse files
borkmannAlexei Starovoitov
authored andcommitted
bpf, bpftool: Allow probing for CONFIG_HZ from kernel config
In Cilium we've recently switched to make use of bpf_jiffies64() for parts of our tc and XDP datapath since bpf_ktime_get_ns() is more expensive and high-precision is not needed for our timeouts we have anyway. Our agent has a probe manager which picks up the json of bpftool's feature probe and we also use the macro output in our C programs e.g. to have workarounds when helpers are not available on older kernels. Extend the kernel config info dump to also include the kernel's CONFIG_HZ, and rework the probe_kernel_image_config() for allowing a macro dump such that CONFIG_HZ can be propagated to BPF C code as a simple define if available via config. Latter allows to have _compile- time_ resolution of jiffies <-> sec conversion in our code since all are propagated as known constants. Given we cannot generally assume availability of kconfig everywhere, we also have a kernel hz probe [0] as a fallback. Potentially, bpftool could have an integrated probe fallback as well, although to derive it, we might need to place it under 'bpftool feature probe full' or similar given it would slow down the probing process overall. Yet 'full' doesn't fit either for us since we don't want to pollute the kernel log with warning messages from bpf_probe_write_user() and bpf_trace_printk() on agent startup; I've left it out for the time being. [0] https://github.com/cilium/cilium/blob/master/bpf/cilium-probe-kernel-hz.c Signed-off-by: Daniel Borkmann <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Reviewed-by: Quentin Monnet <[email protected]> Cc: Martin KaFai Lau <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 5cc5924 commit 0ee52c0

File tree

1 file changed

+67
-53
lines changed

1 file changed

+67
-53
lines changed

tools/bpf/bpftool/feature.c

Lines changed: 67 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,12 @@ print_bool_feature(const char *feat_name, const char *plain_name,
8080
printf("%s is %savailable\n", plain_name, res ? "" : "NOT ");
8181
}
8282

83-
static void print_kernel_option(const char *name, const char *value)
83+
static void print_kernel_option(const char *name, const char *value,
84+
const char *define_prefix)
8485
{
8586
char *endptr;
8687
int res;
8788

88-
/* No support for C-style ouptut */
89-
9089
if (json_output) {
9190
if (!value) {
9291
jsonw_null_field(json_wtr, name);
@@ -98,6 +97,12 @@ static void print_kernel_option(const char *name, const char *value)
9897
jsonw_int_field(json_wtr, name, res);
9998
else
10099
jsonw_string_field(json_wtr, name, value);
100+
} else if (define_prefix) {
101+
if (value)
102+
printf("#define %s%s %s\n", define_prefix,
103+
name, value);
104+
else
105+
printf("/* %s%s is not set */\n", define_prefix, name);
101106
} else {
102107
if (value)
103108
printf("%s is set to %s\n", name, value);
@@ -315,77 +320,84 @@ static bool read_next_kernel_config_option(gzFile file, char *buf, size_t n,
315320
return false;
316321
}
317322

318-
static void probe_kernel_image_config(void)
323+
static void probe_kernel_image_config(const char *define_prefix)
319324
{
320-
static const char * const options[] = {
325+
static const struct {
326+
const char * const name;
327+
bool macro_dump;
328+
} options[] = {
321329
/* Enable BPF */
322-
"CONFIG_BPF",
330+
{ "CONFIG_BPF", },
323331
/* Enable bpf() syscall */
324-
"CONFIG_BPF_SYSCALL",
332+
{ "CONFIG_BPF_SYSCALL", },
325333
/* Does selected architecture support eBPF JIT compiler */
326-
"CONFIG_HAVE_EBPF_JIT",
334+
{ "CONFIG_HAVE_EBPF_JIT", },
327335
/* Compile eBPF JIT compiler */
328-
"CONFIG_BPF_JIT",
336+
{ "CONFIG_BPF_JIT", },
329337
/* Avoid compiling eBPF interpreter (use JIT only) */
330-
"CONFIG_BPF_JIT_ALWAYS_ON",
338+
{ "CONFIG_BPF_JIT_ALWAYS_ON", },
331339

332340
/* cgroups */
333-
"CONFIG_CGROUPS",
341+
{ "CONFIG_CGROUPS", },
334342
/* BPF programs attached to cgroups */
335-
"CONFIG_CGROUP_BPF",
343+
{ "CONFIG_CGROUP_BPF", },
336344
/* bpf_get_cgroup_classid() helper */
337-
"CONFIG_CGROUP_NET_CLASSID",
345+
{ "CONFIG_CGROUP_NET_CLASSID", },
338346
/* bpf_skb_{,ancestor_}cgroup_id() helpers */
339-
"CONFIG_SOCK_CGROUP_DATA",
347+
{ "CONFIG_SOCK_CGROUP_DATA", },
340348

341349
/* Tracing: attach BPF to kprobes, tracepoints, etc. */
342-
"CONFIG_BPF_EVENTS",
350+
{ "CONFIG_BPF_EVENTS", },
343351
/* Kprobes */
344-
"CONFIG_KPROBE_EVENTS",
352+
{ "CONFIG_KPROBE_EVENTS", },
345353
/* Uprobes */
346-
"CONFIG_UPROBE_EVENTS",
354+
{ "CONFIG_UPROBE_EVENTS", },
347355
/* Tracepoints */
348-
"CONFIG_TRACING",
356+
{ "CONFIG_TRACING", },
349357
/* Syscall tracepoints */
350-
"CONFIG_FTRACE_SYSCALLS",
358+
{ "CONFIG_FTRACE_SYSCALLS", },
351359
/* bpf_override_return() helper support for selected arch */
352-
"CONFIG_FUNCTION_ERROR_INJECTION",
360+
{ "CONFIG_FUNCTION_ERROR_INJECTION", },
353361
/* bpf_override_return() helper */
354-
"CONFIG_BPF_KPROBE_OVERRIDE",
362+
{ "CONFIG_BPF_KPROBE_OVERRIDE", },
355363

356364
/* Network */
357-
"CONFIG_NET",
365+
{ "CONFIG_NET", },
358366
/* AF_XDP sockets */
359-
"CONFIG_XDP_SOCKETS",
367+
{ "CONFIG_XDP_SOCKETS", },
360368
/* BPF_PROG_TYPE_LWT_* and related helpers */
361-
"CONFIG_LWTUNNEL_BPF",
369+
{ "CONFIG_LWTUNNEL_BPF", },
362370
/* BPF_PROG_TYPE_SCHED_ACT, TC (traffic control) actions */
363-
"CONFIG_NET_ACT_BPF",
371+
{ "CONFIG_NET_ACT_BPF", },
364372
/* BPF_PROG_TYPE_SCHED_CLS, TC filters */
365-
"CONFIG_NET_CLS_BPF",
373+
{ "CONFIG_NET_CLS_BPF", },
366374
/* TC clsact qdisc */
367-
"CONFIG_NET_CLS_ACT",
375+
{ "CONFIG_NET_CLS_ACT", },
368376
/* Ingress filtering with TC */
369-
"CONFIG_NET_SCH_INGRESS",
377+
{ "CONFIG_NET_SCH_INGRESS", },
370378
/* bpf_skb_get_xfrm_state() helper */
371-
"CONFIG_XFRM",
379+
{ "CONFIG_XFRM", },
372380
/* bpf_get_route_realm() helper */
373-
"CONFIG_IP_ROUTE_CLASSID",
381+
{ "CONFIG_IP_ROUTE_CLASSID", },
374382
/* BPF_PROG_TYPE_LWT_SEG6_LOCAL and related helpers */
375-
"CONFIG_IPV6_SEG6_BPF",
383+
{ "CONFIG_IPV6_SEG6_BPF", },
376384
/* BPF_PROG_TYPE_LIRC_MODE2 and related helpers */
377-
"CONFIG_BPF_LIRC_MODE2",
385+
{ "CONFIG_BPF_LIRC_MODE2", },
378386
/* BPF stream parser and BPF socket maps */
379-
"CONFIG_BPF_STREAM_PARSER",
387+
{ "CONFIG_BPF_STREAM_PARSER", },
380388
/* xt_bpf module for passing BPF programs to netfilter */
381-
"CONFIG_NETFILTER_XT_MATCH_BPF",
389+
{ "CONFIG_NETFILTER_XT_MATCH_BPF", },
382390
/* bpfilter back-end for iptables */
383-
"CONFIG_BPFILTER",
391+
{ "CONFIG_BPFILTER", },
384392
/* bpftilter module with "user mode helper" */
385-
"CONFIG_BPFILTER_UMH",
393+
{ "CONFIG_BPFILTER_UMH", },
386394

387395
/* test_bpf module for BPF tests */
388-
"CONFIG_TEST_BPF",
396+
{ "CONFIG_TEST_BPF", },
397+
398+
/* Misc configs useful in BPF C programs */
399+
/* jiffies <-> sec conversion for bpf_jiffies64() helper */
400+
{ "CONFIG_HZ", true, }
389401
};
390402
char *values[ARRAY_SIZE(options)] = { };
391403
struct utsname utsn;
@@ -427,7 +439,8 @@ static void probe_kernel_image_config(void)
427439

428440
while (read_next_kernel_config_option(file, buf, sizeof(buf), &value)) {
429441
for (i = 0; i < ARRAY_SIZE(options); i++) {
430-
if (values[i] || strcmp(buf, options[i]))
442+
if ((define_prefix && !options[i].macro_dump) ||
443+
values[i] || strcmp(buf, options[i].name))
431444
continue;
432445

433446
values[i] = strdup(value);
@@ -439,7 +452,9 @@ static void probe_kernel_image_config(void)
439452
gzclose(file);
440453

441454
for (i = 0; i < ARRAY_SIZE(options); i++) {
442-
print_kernel_option(options[i], values[i]);
455+
if (define_prefix && !options[i].macro_dump)
456+
continue;
457+
print_kernel_option(options[i].name, values[i], define_prefix);
443458
free(values[i]);
444459
}
445460
}
@@ -632,23 +647,22 @@ section_system_config(enum probe_component target, const char *define_prefix)
632647
switch (target) {
633648
case COMPONENT_KERNEL:
634649
case COMPONENT_UNSPEC:
635-
if (define_prefix)
636-
break;
637-
638650
print_start_section("system_config",
639651
"Scanning system configuration...",
640-
NULL, /* define_comment never used here */
641-
NULL); /* define_prefix always NULL here */
642-
if (check_procfs()) {
643-
probe_unprivileged_disabled();
644-
probe_jit_enable();
645-
probe_jit_harden();
646-
probe_jit_kallsyms();
647-
probe_jit_limit();
648-
} else {
649-
p_info("/* procfs not mounted, skipping related probes */");
652+
"/*** Misc kernel config items ***/",
653+
define_prefix);
654+
if (!define_prefix) {
655+
if (check_procfs()) {
656+
probe_unprivileged_disabled();
657+
probe_jit_enable();
658+
probe_jit_harden();
659+
probe_jit_kallsyms();
660+
probe_jit_limit();
661+
} else {
662+
p_info("/* procfs not mounted, skipping related probes */");
663+
}
650664
}
651-
probe_kernel_image_config();
665+
probe_kernel_image_config(define_prefix);
652666
print_end_section();
653667
break;
654668
default:

0 commit comments

Comments
 (0)