From: Dave Marchevsky <hidden> Date: 2021-08-21 02:58:51
This series introduces a new helper, bpf_trace_vprintk, which functions
like bpf_trace_printk but supports > 3 arguments via a pseudo-vararg u64
array. A libbpf convienience macro, bpf_vprintk, is added to support
true vararg calling style.
Helper functions and macros added during the implementation of
bpf_seq_printf and bpf_snprintf do most of the heavy lifting for
bpf_trace_vprintk. There's no novel format string wrangling here.
Usecase here is straightforward: Giving BPF program writers a more
powerful printk will ease development of BPF programs, particularly
during debugging and testing, where printk tends to be used.
Hypothetically libbpf's bpf_printk convenience macro could be modified
to use bpf_trace_vprintk under the hood. This patchset does not attempt
to do this, though, nor am I confident that it's desired.
This feature was proposed by Andrii in libbpf mirror's issue tracker
[1].
[1] https://github.com/libbpf/libbpf/issues/315
Dave Marchevsky (5):
bpf: merge printk and seq_printf VARARG max macros
bpf: add bpf_trace_vprintk helper
libbpf: Add bpf_vprintk convenience macro
bpftool: only probe trace_vprintk feature in 'full' mode
selftests/bpf: add trace_vprintk test prog
include/linux/bpf.h | 3 +
include/uapi/linux/bpf.h | 23 ++++++
kernel/bpf/core.c | 5 ++
kernel/bpf/helpers.c | 6 +-
kernel/trace/bpf_trace.c | 54 ++++++++++++-
tools/bpf/bpftool/feature.c | 1 +
tools/include/uapi/linux/bpf.h | 23 ++++++
tools/lib/bpf/bpf_helpers.h | 18 +++++
tools/testing/selftests/bpf/Makefile | 3 +-
.../selftests/bpf/prog_tests/trace_vprintk.c | 75 +++++++++++++++++++
.../selftests/bpf/progs/trace_vprintk.c | 25 +++++++
tools/testing/selftests/bpf/test_bpftool.py | 22 +++---
12 files changed, 238 insertions(+), 20 deletions(-)
create mode 100644 tools/testing/selftests/bpf/prog_tests/trace_vprintk.c
create mode 100644 tools/testing/selftests/bpf/progs/trace_vprintk.c
--
2.30.2
From: Dave Marchevsky <hidden> Date: 2021-08-21 02:59:17
This helper is meant to be "bpf_trace_printk, but with proper vararg
support". Follow bpf_snprintf's example and take a u64 pseudo-vararg
array. Write to dmesg using the same mechanism as bpf_trace_printk.
Signed-off-by: Dave Marchevsky <redacted>
---
include/linux/bpf.h | 1 +
include/uapi/linux/bpf.h | 23 +++++++++++++++
kernel/bpf/core.c | 5 ++++
kernel/bpf/helpers.c | 2 ++
kernel/trace/bpf_trace.c | 52 +++++++++++++++++++++++++++++++++-
tools/include/uapi/linux/bpf.h | 23 +++++++++++++++
6 files changed, 105 insertions(+), 1 deletion(-)
@@ -4871,6 +4871,28 @@ union bpf_attr {*Return*ValuespecifiedbyuseratBPFlinkcreation/attachmenttime*or0,ifitwasnotspecified.+*+*u64bpf_trace_vprintk(constchar*fmt,u32fmt_size,constvoid*data,u32data_len)+*Description+*Behaveslike**bpf_trace_printk**\()helper,buttakesanarrayofu64+*toformat.Supportsupto12argumentstoprintinthisway.+*The*fmt*and*fmt_size*arefortheformatstringitself.The*data*and+**data_len*areformatstringarguments.+*+*Eachformatspecifierin**fmt**correspondstooneu64element+*inthe**data**array.Forstringsandpointerswherepointees+*areaccessed,onlythepointervaluesarestoredinthe*data*+*array.The*data_len*isthesizeof*data*inbytes.+*Formats**%s**,**%p{i,I}{4,6}**requirestoreadkernelmemory.+*Readingkernelmemorymayfailduetoeitherinvalidaddressor+*validaddressbutrequiringamajormemoryfault.Ifreadingkernelmemory+*fails,thestringfor**%s**willbeanemptystring,andtheip+*addressfor**%p{i,I}{4,6}**willbe0.Notreturningerrorto+*bpfprogramisconsistentwithwhat**bpf_trace_printk**\()doesfornow.+*+*Return+*Thenumberofbyteswrittentothebuffer,oranegativeerror+*incaseoffailure.*/#define __BPF_FUNC_MAPPER(FN) \FN(unspec),\
@@ -5048,6 +5070,7 @@ union bpf_attr {FN(timer_cancel),\FN(get_func_ip),\FN(get_attach_cookie),\+FN(trace_vprintk),\/* *//* integer value in 'imm' field of BPF_CALL instruction selects which helper
@@ -4871,6 +4871,28 @@ union bpf_attr {*Return*ValuespecifiedbyuseratBPFlinkcreation/attachmenttime*or0,ifitwasnotspecified.+*+*u64bpf_trace_vprintk(constchar*fmt,u32fmt_size,constvoid*data,u32data_len)+*Description+*Behaveslike**bpf_trace_printk**\()helper,buttakesanarrayofu64+*toformat.Supportsupto12argumentstoprintinthisway.+*The*fmt*and*fmt_size*arefortheformatstringitself.The*data*and+**data_len*areformatstringarguments.+*+*Eachformatspecifierin**fmt**correspondstooneu64element+*inthe**data**array.Forstringsandpointerswherepointees+*areaccessed,onlythepointervaluesarestoredinthe*data*+*array.The*data_len*isthesizeof*data*inbytes.+*Formats**%s**,**%p{i,I}{4,6}**requirestoreadkernelmemory.+*Readingkernelmemorymayfailduetoeitherinvalidaddressor+*validaddressbutrequiringamajormemoryfault.Ifreadingkernelmemory+*fails,thestringfor**%s**willbeanemptystring,andtheip+*addressfor**%p{i,I}{4,6}**willbe0.Notreturningerrorto+*bpfprogramisconsistentwithwhat**bpf_trace_printk**\()doesfornow.+*+*Return+*Thenumberofbyteswrittentothebuffer,oranegativeerror+*incaseoffailure.*/#define __BPF_FUNC_MAPPER(FN) \FN(unspec),\
@@ -5048,6 +5070,7 @@ union bpf_attr {FN(timer_cancel),\FN(get_func_ip),\FN(get_attach_cookie),\+FN(trace_vprintk),\/* *//* integer value in 'imm' field of BPF_CALL instruction selects which helper
From: Dave Marchevsky <hidden> Date: 2021-08-21 02:59:17
Since commit 368cb0e7cdb5e ("bpftool: Make probes which emit dmesg
warnings optional"), some helpers aren't probed by bpftool unless
`full` arg is added to `bpftool feature probe`.
bpf_trace_vprintk can emit dmesg warnings when probed, so include it.
Signed-off-by: Dave Marchevsky <redacted>
---
tools/bpf/bpftool/feature.c | 1 +
tools/testing/selftests/bpf/test_bpftool.py | 22 +++++++++------------
2 files changed, 10 insertions(+), 13 deletions(-)
@@ -67,10 +72,7 @@ class TestBpftool(unittest.TestCase):@default_ifacedeftest_feature_dev_json(self,iface):-unexpected_helpers=[-"bpf_probe_write_user",-"bpf_trace_printk",-]+unexpected_helpers=DMESG_EMITTING_HELPERSexpected_keys=["syscall_config","program_types",
@@ -94,10 +96,7 @@ class TestBpftool(unittest.TestCase):bpftool_json(["feature","probe"]),bpftool_json(["feature"]),]-unexpected_helpers=[-"bpf_probe_write_user",-"bpf_trace_printk",-]+unexpected_helpers=DMESG_EMITTING_HELPERSexpected_keys=["syscall_config","system_config",
@@ -121,10 +120,7 @@ class TestBpftool(unittest.TestCase):bpftool_json(["feature","probe","kernel","full"]),bpftool_json(["feature","probe","full"]),]-expected_helpers=[-"bpf_probe_write_user",-"bpf_trace_printk",-]+expected_helpers=DMESG_EMITTING_HELPERSfortcintest_cases:# Check if expected helpers are included at least once in any
@@ -157,7 +153,7 @@ class TestBpftool(unittest.TestCase):not_full_set.add(helper)self.assertCountEqual(full_set-not_full_set,-{"bpf_probe_write_user","bpf_trace_printk"})+set(DMESG_EMITTING_HELPERS))self.assertCountEqual(not_full_set-full_set,set())deftest_feature_macros(self):
From: Dave Marchevsky <hidden> Date: 2021-08-21 02:59:17
bpf_vprintk functions similarly to BPF_SEQ_PRINTF and BPF_SNPRINTF
macros elsewhere in the file - it allows use of bpf_trace_vprintk
without manual conversion of varargs to u64 array.
Like the bpf_printk macro, bpf_vprintk is meant to be the main interface
to the bpf_trace_vprintk helper and thus is uncapitalized.
Signed-off-by: Dave Marchevsky <redacted>
---
tools/lib/bpf/bpf_helpers.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
From: Dave Marchevsky <hidden> Date: 2021-08-21 02:59:24
This commit adds a test prog for vprintk which confirms that:
* bpf_trace_vprintk is writing to dmesg
* bpf_vprintk convenience macro works as expected
* >3 args are printed
Approach and code are borrowed from trace_printk test.
Signed-off-by: Dave Marchevsky <redacted>
---
tools/testing/selftests/bpf/Makefile | 3 +-
.../selftests/bpf/prog_tests/trace_vprintk.c | 75 +++++++++++++++++++
.../selftests/bpf/progs/trace_vprintk.c | 25 +++++++
3 files changed, 102 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/bpf/prog_tests/trace_vprintk.c
create mode 100644 tools/testing/selftests/bpf/progs/trace_vprintk.c
@@ -0,0 +1,75 @@+// SPDX-License-Identifier: GPL-2.0+/* Copyright (c) 2021 Facebook */++#include<test_progs.h>++#include"trace_vprintk.lskel.h"++#define TRACEBUF "/sys/kernel/debug/tracing/trace_pipe"+#define SEARCHMSG "1,2,3,4,5,6,7,8,9,10"++voidtest_trace_vprintk(void)+{+interr,iter=0,duration=0,found=0;+structtrace_vprintk__bss*bss;+structtrace_vprintk*skel;+char*buf=NULL;+FILE*fp=NULL;+size_tbuflen;++skel=trace_vprintk__open();+if(CHECK(!skel,"skel_open","failed to open skeleton\n"))+return;++err=trace_vprintk__load(skel);+if(CHECK(err,"skel_load","failed to load skeleton: %d\n",err))+gotocleanup;++bss=skel->bss;++err=trace_vprintk__attach(skel);+if(CHECK(err,"skel_attach","skeleton attach failed: %d\n",err))+gotocleanup;++fp=fopen(TRACEBUF,"r");+if(CHECK(fp==NULL,"could not open trace buffer",+"error %d opening %s",errno,TRACEBUF))+gotocleanup;++/* We do not want to wait forever if this test fails... */+fcntl(fileno(fp),F_SETFL,O_NONBLOCK);++/* wait for tracepoint to trigger */+usleep(1);+trace_vprintk__detach(skel);++if(CHECK(bss->trace_vprintk_ran==0,+"bpf_trace_vprintk never ran",+"ran == %d",bss->trace_vprintk_ran))+gotocleanup;++if(CHECK(bss->trace_vprintk_ret<=0,+"bpf_trace_vprintk returned <= 0 value",+"got %d",bss->trace_vprintk_ret))+gotocleanup;++/* verify our search string is in the trace buffer */+while(getline(&buf,&buflen,fp)>=0||errno==EAGAIN){+if(strstr(buf,SEARCHMSG)!=NULL)+found++;+if(found==bss->trace_vprintk_ran)+break;+if(++iter>1000)+break;+}++if(CHECK(!found,"message from bpf_trace_vprintk not found",+"no instance of %s in %s",SEARCHMSG,TRACEBUF))+gotocleanup;++cleanup:+trace_vprintk__destroy(skel);+free(buf);+if(fp)+fclose(fp);+}
From: Dave Marchevsky <hidden> Date: 2021-08-21 02:59:30
MAX_SNPRINTF_VARARGS and MAX_SEQ_PRINTF_VARARGS are used by bpf helpers
bpf_snprintf and bpf_seq_printf to limit their varargs. Both call into
bpf_bprintf_prepare for print formatting logic and have convenience
macros in libbpf (BPF_SNPRINTF, BPF_SEQ_PRINTF) which use the same
helper macros to convert varargs to a byte array.
Changing shared functionality to support more varargs for either bpf
helper would affect the other as well, so let's combine the _VARARGS
macros to make this more obvious.
Signed-off-by: Dave Marchevsky <redacted>
---
include/linux/bpf.h | 2 ++
kernel/bpf/helpers.c | 4 +---
kernel/trace/bpf_trace.c | 4 +---
3 files changed, 4 insertions(+), 6 deletions(-)
On Fri, Aug 20, 2021 at 7:59 PM Dave Marchevsky [off-list ref] wrote:
MAX_SNPRINTF_VARARGS and MAX_SEQ_PRINTF_VARARGS are used by bpf helpers
bpf_snprintf and bpf_seq_printf to limit their varargs. Both call into
bpf_bprintf_prepare for print formatting logic and have convenience
macros in libbpf (BPF_SNPRINTF, BPF_SEQ_PRINTF) which use the same
helper macros to convert varargs to a byte array.
Changing shared functionality to support more varargs for either bpf
helper would affect the other as well, so let's combine the _VARARGS
macros to make this more obvious.
Signed-off-by: Dave Marchevsky <redacted>
---
On Fri, Aug 20, 2021 at 7:59 PM Dave Marchevsky [off-list ref] wrote:
This helper is meant to be "bpf_trace_printk, but with proper vararg
We have bpf_snprintf() and bpf_seq_printf() names for other BPF
helpers using the same approach. How about we call this one simply
`bpf_printf`? It will be in line with other naming, it is logical BPF
equivalent of user-space printf (which outputs to stderr, which in BPF
land is /sys/kernel/debug/tracing/trace_pipe). And it will be logical
to have a nice and short BPF_PRINTF() convenience macro provided by
libbpf.
support". Follow bpf_snprintf's example and take a u64 pseudo-vararg
array. Write to dmesg using the same mechanism as bpf_trace_printk.
Are you sure about the dmesg part?... bpf_trace_printk is outputting
into /sys/kernel/debug/tracing/trace_pipe.
@@ -4871,6 +4871,28 @@ union bpf_attr {*Return*ValuespecifiedbyuseratBPFlinkcreation/attachmenttime*or0,ifitwasnotspecified.+*+*u64bpf_trace_vprintk(constchar*fmt,u32fmt_size,constvoid*data,u32data_len)+*Description+*Behaveslike**bpf_trace_printk**\()helper,buttakesanarrayofu64+*toformat.Supportsupto12argumentstoprintinthisway.
we didn't specify 12 in the description of bpf_snprintf() or
bpf_seq_printf(), so why start doing that here? For data/args format,
let's just refer to bpf_snprintf() or bpf_seq_printf(), whichever does
a better job explaining this :)
+ * The *fmt* and *fmt_size* are for the format string itself. The *data* and
+ * *data_len* are format string arguments.
+ *
+ * Each format specifier in **fmt** corresponds to one u64 element
+ * in the **data** array. For strings and pointers where pointees
+ * are accessed, only the pointer values are stored in the *data*
+ * array. The *data_len* is the size of *data* in bytes.
+ * Formats **%s**, **%p{i,I}{4,6}** requires to read kernel memory.
+ * Reading kernel memory may fail due to either invalid address or
+ * valid address but requiring a major memory fault. If reading kernel memory
+ * fails, the string for **%s** will be an empty string, and the ip
+ * address for **%p{i,I}{4,6}** will be 0. Not returning error to
+ * bpf program is consistent with what **bpf_trace_printk**\ () does for now.
This is just a copy/paste from other helpers. Let's avoid duplication
and just point people to a description in other helpers.
quoted hunk
+ *
+ * Return
+ * The number of bytes written to the buffer, or a negative error
+ * in case of failure.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -5048,6 +5070,7 @@ union bpf_attr { FN(timer_cancel), \ FN(get_func_ip), \ FN(get_attach_cookie), \+ FN(trace_vprintk), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper
@@ -4871,6 +4871,28 @@ union bpf_attr {*Return*ValuespecifiedbyuseratBPFlinkcreation/attachmenttime*or0,ifitwasnotspecified.+*+*u64bpf_trace_vprintk(constchar*fmt,u32fmt_size,constvoid*data,u32data_len)+*Description+*Behaveslike**bpf_trace_printk**\()helper,buttakesanarrayofu64+*toformat.Supportsupto12argumentstoprintinthisway.+*The*fmt*and*fmt_size*arefortheformatstringitself.The*data*and+**data_len*areformatstringarguments.+*+*Eachformatspecifierin**fmt**correspondstooneu64element+*inthe**data**array.Forstringsandpointerswherepointees+*areaccessed,onlythepointervaluesarestoredinthe*data*+*array.The*data_len*isthesizeof*data*inbytes.+*Formats**%s**,**%p{i,I}{4,6}**requirestoreadkernelmemory.+*Readingkernelmemorymayfailduetoeitherinvalidaddressor+*validaddressbutrequiringamajormemoryfault.Ifreadingkernelmemory+*fails,thestringfor**%s**willbeanemptystring,andtheip+*addressfor**%p{i,I}{4,6}**willbe0.Notreturningerrorto+*bpfprogramisconsistentwithwhat**bpf_trace_printk**\()doesfornow.+*+*Return+*Thenumberofbyteswrittentothebuffer,oranegativeerror+*incaseoffailure.*/#define __BPF_FUNC_MAPPER(FN) \FN(unspec),\
@@ -5048,6 +5070,7 @@ union bpf_attr {FN(timer_cancel),\FN(get_func_ip),\FN(get_attach_cookie),\+FN(trace_vprintk),\/* *//* integer value in 'imm' field of BPF_CALL instruction selects which helper--
On Fri, Aug 20, 2021 at 7:59 PM Dave Marchevsky [off-list ref] wrote:
quoted hunk
bpf_vprintk functions similarly to BPF_SEQ_PRINTF and BPF_SNPRINTF
macros elsewhere in the file - it allows use of bpf_trace_vprintk
without manual conversion of varargs to u64 array.
Like the bpf_printk macro, bpf_vprintk is meant to be the main interface
to the bpf_trace_vprintk helper and thus is uncapitalized.
Signed-off-by: Dave Marchevsky <redacted>
---
tools/lib/bpf/bpf_helpers.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
Given BPF_SNPRINTF and BPF_SEQ_PRINTF, should we call this one in
all-caps as well?
+({ \
+ static const char ___fmt[] = fmt; \
+ unsigned long long ___param[___bpf_narg(args)]; \
I wonder how hard would it be to still use bpf_trace_printk() if the
number of input arguments is less than 3? That way you could use
BPF_PRINTF() everywhere, even on old kernels (you just need to
remember to use < 3 arguments). WDYT? It might be more challenging
than it seems, given it's hard to do conditionals inside #defines :(
On Fri, Aug 20, 2021 at 7:59 PM Dave Marchevsky [off-list ref] wrote:
quoted hunk
This commit adds a test prog for vprintk which confirms that:
* bpf_trace_vprintk is writing to dmesg
* bpf_vprintk convenience macro works as expected
* >3 args are printed
Approach and code are borrowed from trace_printk test.
Signed-off-by: Dave Marchevsky <redacted>
---
tools/testing/selftests/bpf/Makefile | 3 +-
.../selftests/bpf/prog_tests/trace_vprintk.c | 75 +++++++++++++++++++
.../selftests/bpf/progs/trace_vprintk.c | 25 +++++++
3 files changed, 102 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/bpf/prog_tests/trace_vprintk.c
create mode 100644 tools/testing/selftests/bpf/progs/trace_vprintk.c
On Mon, Aug 23, 2021 at 9:50 PM Andrii Nakryiko
[off-list ref] wrote:
On Fri, Aug 20, 2021 at 7:59 PM Dave Marchevsky [off-list ref] wrote:
quoted
This helper is meant to be "bpf_trace_printk, but with proper vararg
We have bpf_snprintf() and bpf_seq_printf() names for other BPF
helpers using the same approach. How about we call this one simply
`bpf_printf`? It will be in line with other naming, it is logical BPF
equivalent of user-space printf (which outputs to stderr, which in BPF
land is /sys/kernel/debug/tracing/trace_pipe). And it will be logical
to have a nice and short BPF_PRINTF() convenience macro provided by
libbpf.
quoted
support". Follow bpf_snprintf's example and take a u64 pseudo-vararg
array. Write to dmesg using the same mechanism as bpf_trace_printk.
Are you sure about the dmesg part?... bpf_trace_printk is outputting
into /sys/kernel/debug/tracing/trace_pipe.
Actually I like bpf_trace_vprintk() name, since it makes it obvious that
it's a flavor of bpf_trace_printk() and its quirks that users learned
to deal with.
I would reserve bpf_printf() for the future. We might have standalone
bpf programs in the future (without user space component) and a better
equivalent
of stdin/stdout. clang -target bpf hello_world.c -o a.out; ./a.out
should print to a terminal. Such future hello world in bpf would be
using bpf_printf()
or bpf_dprintf().
On Tue, Aug 24, 2021 at 10:57 AM Alexei Starovoitov
[off-list ref] wrote:
On Mon, Aug 23, 2021 at 9:50 PM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Fri, Aug 20, 2021 at 7:59 PM Dave Marchevsky [off-list ref] wrote:
quoted
This helper is meant to be "bpf_trace_printk, but with proper vararg
We have bpf_snprintf() and bpf_seq_printf() names for other BPF
helpers using the same approach. How about we call this one simply
`bpf_printf`? It will be in line with other naming, it is logical BPF
equivalent of user-space printf (which outputs to stderr, which in BPF
land is /sys/kernel/debug/tracing/trace_pipe). And it will be logical
to have a nice and short BPF_PRINTF() convenience macro provided by
libbpf.
quoted
support". Follow bpf_snprintf's example and take a u64 pseudo-vararg
array. Write to dmesg using the same mechanism as bpf_trace_printk.
Are you sure about the dmesg part?... bpf_trace_printk is outputting
into /sys/kernel/debug/tracing/trace_pipe.
Actually I like bpf_trace_vprintk() name, since it makes it obvious that
It's the inconsistency with bpf_snprintf() and bpf_seq_printf() that's
mildly annoying (it's f at the end, and no v- prefix). Maybe
bpf_trace_printf() then? Or is it too close to bpf_trace_printk()? But
either way you would be using BPF_PRINTF() macro for this. And we can
make that macro use bpf_trace_printk() transparently for <3 args, so
that new macro works on old kernels.
it's a flavor of bpf_trace_printk() and its quirks that users learned
to deal with.
I would reserve bpf_printf() for the future. We might have standalone
bpf programs in the future (without user space component) and a better
equivalent
of stdin/stdout. clang -target bpf hello_world.c -o a.out; ./a.out
should print to a terminal. Such future hello world in bpf would be
using bpf_printf()
or bpf_dprintf().
On Tue, Aug 24, 2021 at 11:02 AM Andrii Nakryiko
[off-list ref] wrote:
On Tue, Aug 24, 2021 at 10:57 AM Alexei Starovoitov
[off-list ref] wrote:
quoted
On Mon, Aug 23, 2021 at 9:50 PM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Fri, Aug 20, 2021 at 7:59 PM Dave Marchevsky [off-list ref] wrote:
quoted
This helper is meant to be "bpf_trace_printk, but with proper vararg
We have bpf_snprintf() and bpf_seq_printf() names for other BPF
helpers using the same approach. How about we call this one simply
`bpf_printf`? It will be in line with other naming, it is logical BPF
equivalent of user-space printf (which outputs to stderr, which in BPF
land is /sys/kernel/debug/tracing/trace_pipe). And it will be logical
to have a nice and short BPF_PRINTF() convenience macro provided by
libbpf.
quoted
support". Follow bpf_snprintf's example and take a u64 pseudo-vararg
array. Write to dmesg using the same mechanism as bpf_trace_printk.
Are you sure about the dmesg part?... bpf_trace_printk is outputting
into /sys/kernel/debug/tracing/trace_pipe.
Actually I like bpf_trace_vprintk() name, since it makes it obvious that
It's the inconsistency with bpf_snprintf() and bpf_seq_printf() that's
mildly annoying (it's f at the end, and no v- prefix). Maybe
bpf_trace_printf() then? Or is it too close to bpf_trace_printk()?
bpf_trace_printf could be ok, but see below.
But
either way you would be using BPF_PRINTF() macro for this. And we can
make that macro use bpf_trace_printk() transparently for <3 args, so
that new macro works on old kernels.
Cannot we change the existing bpf_printk() macro to work on old and new kernels?
So bpf_printk() would use bpf_trace_printf() on new and
bpf_trace_printk() on old?
I think bpf_trace_vprintk() looks cleaner in this context if we reuse
bpf_printk() macro.
On Tue, Aug 24, 2021 at 11:17 AM Alexei Starovoitov
[off-list ref] wrote:
On Tue, Aug 24, 2021 at 11:02 AM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Tue, Aug 24, 2021 at 10:57 AM Alexei Starovoitov
[off-list ref] wrote:
quoted
On Mon, Aug 23, 2021 at 9:50 PM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Fri, Aug 20, 2021 at 7:59 PM Dave Marchevsky [off-list ref] wrote:
quoted
This helper is meant to be "bpf_trace_printk, but with proper vararg
We have bpf_snprintf() and bpf_seq_printf() names for other BPF
helpers using the same approach. How about we call this one simply
`bpf_printf`? It will be in line with other naming, it is logical BPF
equivalent of user-space printf (which outputs to stderr, which in BPF
land is /sys/kernel/debug/tracing/trace_pipe). And it will be logical
to have a nice and short BPF_PRINTF() convenience macro provided by
libbpf.
quoted
support". Follow bpf_snprintf's example and take a u64 pseudo-vararg
array. Write to dmesg using the same mechanism as bpf_trace_printk.
Are you sure about the dmesg part?... bpf_trace_printk is outputting
into /sys/kernel/debug/tracing/trace_pipe.
Actually I like bpf_trace_vprintk() name, since it makes it obvious that
It's the inconsistency with bpf_snprintf() and bpf_seq_printf() that's
mildly annoying (it's f at the end, and no v- prefix). Maybe
bpf_trace_printf() then? Or is it too close to bpf_trace_printk()?
bpf_trace_printf could be ok, but see below.
quoted
But
either way you would be using BPF_PRINTF() macro for this. And we can
make that macro use bpf_trace_printk() transparently for <3 args, so
that new macro works on old kernels.
Cannot we change the existing bpf_printk() macro to work on old and new kernels?
Only if we break backwards compatibility. And I only know how to
detect the presence of new helper with CO-RE, which automatically
makes any BPF program using this macro CO-RE-dependent, which might
not be what users want (vmlinux BTF is still not universally
available). If I could do something like that without breaking change
and without CO-RE, I'd update bpf_printk() to use `const char *fmt`
for format string a long time ago. But adding CO-RE dependency for
bpf_printk() seems like a no-go.
So bpf_printk() would use bpf_trace_printf() on new and
bpf_trace_printk() on old?
I think bpf_trace_vprintk() looks cleaner in this context if we reuse
bpf_printk() macro.
On Tue, Aug 24, 2021 at 11:24 AM Andrii Nakryiko
[off-list ref] wrote:
On Tue, Aug 24, 2021 at 11:17 AM Alexei Starovoitov
[off-list ref] wrote:
quoted
On Tue, Aug 24, 2021 at 11:02 AM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Tue, Aug 24, 2021 at 10:57 AM Alexei Starovoitov
[off-list ref] wrote:
quoted
On Mon, Aug 23, 2021 at 9:50 PM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Fri, Aug 20, 2021 at 7:59 PM Dave Marchevsky [off-list ref] wrote:
quoted
This helper is meant to be "bpf_trace_printk, but with proper vararg
We have bpf_snprintf() and bpf_seq_printf() names for other BPF
helpers using the same approach. How about we call this one simply
`bpf_printf`? It will be in line with other naming, it is logical BPF
equivalent of user-space printf (which outputs to stderr, which in BPF
land is /sys/kernel/debug/tracing/trace_pipe). And it will be logical
to have a nice and short BPF_PRINTF() convenience macro provided by
libbpf.
quoted
support". Follow bpf_snprintf's example and take a u64 pseudo-vararg
array. Write to dmesg using the same mechanism as bpf_trace_printk.
Are you sure about the dmesg part?... bpf_trace_printk is outputting
into /sys/kernel/debug/tracing/trace_pipe.
Actually I like bpf_trace_vprintk() name, since it makes it obvious that
It's the inconsistency with bpf_snprintf() and bpf_seq_printf() that's
mildly annoying (it's f at the end, and no v- prefix). Maybe
bpf_trace_printf() then? Or is it too close to bpf_trace_printk()?
bpf_trace_printf could be ok, but see below.
quoted
But
either way you would be using BPF_PRINTF() macro for this. And we can
make that macro use bpf_trace_printk() transparently for <3 args, so
that new macro works on old kernels.
Cannot we change the existing bpf_printk() macro to work on old and new kernels?
Only if we break backwards compatibility. And I only know how to
detect the presence of new helper with CO-RE, which automatically
makes any BPF program using this macro CO-RE-dependent, which might
not be what users want (vmlinux BTF is still not universally
available). If I could do something like that without breaking change
and without CO-RE, I'd update bpf_printk() to use `const char *fmt`
for format string a long time ago. But adding CO-RE dependency for
bpf_printk() seems like a no-go.
I see. Naming is the hardest.
I think Dave's current choice of lower case bpf_vprintk() macro and
bpf_trace_vprintk()
helper fits the existing bpf_printk/bpf_trace_printk the best.
Yes, it's inconsistent with BPF_SEQ_PRINTF/BPF_SNPRINTF,
but consistent with trace_printk. Whichever way we go it will be inconsistent.
Stylistically I like the lower case macro, since it doesn't scream at me.
On Tue, Aug 24, 2021 at 2:00 PM Alexei Starovoitov
[off-list ref] wrote:
On Tue, Aug 24, 2021 at 11:24 AM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Tue, Aug 24, 2021 at 11:17 AM Alexei Starovoitov
[off-list ref] wrote:
quoted
On Tue, Aug 24, 2021 at 11:02 AM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Tue, Aug 24, 2021 at 10:57 AM Alexei Starovoitov
[off-list ref] wrote:
quoted
On Mon, Aug 23, 2021 at 9:50 PM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Fri, Aug 20, 2021 at 7:59 PM Dave Marchevsky [off-list ref] wrote:
quoted
This helper is meant to be "bpf_trace_printk, but with proper vararg
We have bpf_snprintf() and bpf_seq_printf() names for other BPF
helpers using the same approach. How about we call this one simply
`bpf_printf`? It will be in line with other naming, it is logical BPF
equivalent of user-space printf (which outputs to stderr, which in BPF
land is /sys/kernel/debug/tracing/trace_pipe). And it will be logical
to have a nice and short BPF_PRINTF() convenience macro provided by
libbpf.
quoted
support". Follow bpf_snprintf's example and take a u64 pseudo-vararg
array. Write to dmesg using the same mechanism as bpf_trace_printk.
Are you sure about the dmesg part?... bpf_trace_printk is outputting
into /sys/kernel/debug/tracing/trace_pipe.
Actually I like bpf_trace_vprintk() name, since it makes it obvious that
It's the inconsistency with bpf_snprintf() and bpf_seq_printf() that's
mildly annoying (it's f at the end, and no v- prefix). Maybe
bpf_trace_printf() then? Or is it too close to bpf_trace_printk()?
bpf_trace_printf could be ok, but see below.
quoted
But
either way you would be using BPF_PRINTF() macro for this. And we can
make that macro use bpf_trace_printk() transparently for <3 args, so
that new macro works on old kernels.
Cannot we change the existing bpf_printk() macro to work on old and new kernels?
Only if we break backwards compatibility. And I only know how to
detect the presence of new helper with CO-RE, which automatically
makes any BPF program using this macro CO-RE-dependent, which might
not be what users want (vmlinux BTF is still not universally
available). If I could do something like that without breaking change
and without CO-RE, I'd update bpf_printk() to use `const char *fmt`
for format string a long time ago. But adding CO-RE dependency for
bpf_printk() seems like a no-go.
I see. Naming is the hardest.
I think Dave's current choice of lower case bpf_vprintk() macro and
bpf_trace_vprintk()
helper fits the existing bpf_printk/bpf_trace_printk the best.
Yes, it's inconsistent with BPF_SEQ_PRINTF/BPF_SNPRINTF,
but consistent with trace_printk. Whichever way we go it will be inconsistent.
Stylistically I like the lower case macro, since it doesn't scream at me.
Ok, it's fine. Even more so because we don't need a new macro, we can
just extend the existing bpf_printk() macro to automatically pick
bpf_trace_printk() if more than 3 arguments is provided.
Dave, you'll have to solve a bit of a puzzle macro-wise, but it's
possible to use either bpf_trace_printk() or bpf_trace_vprintk()
transparently for the user.
The only downside is that for <3 args, for backwards compatibility,
we'd have to stick to
char ___fmt[] = fmt;
vs more efficient
static const char ___fmt[] = fmt;
But I'm thinking it might be time to finally make this improvement. We
can also allow users to fallback to less efficient ways for really old
kernels with some extra flag, like so
#ifdef BPF_NO_GLOBAL_DATA
char ___fmt[] = fmt;
#else
static const char ___fmt[] = fmt;
#end
Thoughts?
On Tue, Aug 24, 2021 at 2:24 PM Andrii Nakryiko
[off-list ref] wrote:
On Tue, Aug 24, 2021 at 2:00 PM Alexei Starovoitov
[off-list ref] wrote:
quoted
On Tue, Aug 24, 2021 at 11:24 AM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Tue, Aug 24, 2021 at 11:17 AM Alexei Starovoitov
[off-list ref] wrote:
quoted
On Tue, Aug 24, 2021 at 11:02 AM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Tue, Aug 24, 2021 at 10:57 AM Alexei Starovoitov
[off-list ref] wrote:
quoted
On Mon, Aug 23, 2021 at 9:50 PM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Fri, Aug 20, 2021 at 7:59 PM Dave Marchevsky [off-list ref] wrote:
quoted
This helper is meant to be "bpf_trace_printk, but with proper vararg
We have bpf_snprintf() and bpf_seq_printf() names for other BPF
helpers using the same approach. How about we call this one simply
`bpf_printf`? It will be in line with other naming, it is logical BPF
equivalent of user-space printf (which outputs to stderr, which in BPF
land is /sys/kernel/debug/tracing/trace_pipe). And it will be logical
to have a nice and short BPF_PRINTF() convenience macro provided by
libbpf.
quoted
support". Follow bpf_snprintf's example and take a u64 pseudo-vararg
array. Write to dmesg using the same mechanism as bpf_trace_printk.
Are you sure about the dmesg part?... bpf_trace_printk is outputting
into /sys/kernel/debug/tracing/trace_pipe.
Actually I like bpf_trace_vprintk() name, since it makes it obvious that
It's the inconsistency with bpf_snprintf() and bpf_seq_printf() that's
mildly annoying (it's f at the end, and no v- prefix). Maybe
bpf_trace_printf() then? Or is it too close to bpf_trace_printk()?
bpf_trace_printf could be ok, but see below.
quoted
But
either way you would be using BPF_PRINTF() macro for this. And we can
make that macro use bpf_trace_printk() transparently for <3 args, so
that new macro works on old kernels.
Cannot we change the existing bpf_printk() macro to work on old and new kernels?
Only if we break backwards compatibility. And I only know how to
detect the presence of new helper with CO-RE, which automatically
makes any BPF program using this macro CO-RE-dependent, which might
not be what users want (vmlinux BTF is still not universally
available). If I could do something like that without breaking change
and without CO-RE, I'd update bpf_printk() to use `const char *fmt`
for format string a long time ago. But adding CO-RE dependency for
bpf_printk() seems like a no-go.
I see. Naming is the hardest.
I think Dave's current choice of lower case bpf_vprintk() macro and
bpf_trace_vprintk()
helper fits the existing bpf_printk/bpf_trace_printk the best.
Yes, it's inconsistent with BPF_SEQ_PRINTF/BPF_SNPRINTF,
but consistent with trace_printk. Whichever way we go it will be inconsistent.
Stylistically I like the lower case macro, since it doesn't scream at me.
Ok, it's fine. Even more so because we don't need a new macro, we can
just extend the existing bpf_printk() macro to automatically pick
bpf_trace_printk() if more than 3 arguments is provided.
Dave, you'll have to solve a bit of a puzzle macro-wise, but it's
possible to use either bpf_trace_printk() or bpf_trace_vprintk()
transparently for the user.
The only downside is that for <3 args, for backwards compatibility,
we'd have to stick to
char ___fmt[] = fmt;
vs more efficient
static const char ___fmt[] = fmt;
But I'm thinking it might be time to finally make this improvement. We
can also allow users to fallback to less efficient ways for really old
kernels with some extra flag, like so
#ifdef BPF_NO_GLOBAL_DATA
char ___fmt[] = fmt;
#else
static const char ___fmt[] = fmt;
#end
Thoughts?
+1 from me for the latter assuming macro magic is possible.