linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH bpf-next 0/6] bpf, printk: add BTF-based type printing
@ 2020-04-17 10:42 Alan Maguire
  2020-04-17 10:42 ` [RFC PATCH bpf-next 1/6] bpf: provide function to get vmlinux BTF information Alan Maguire
                   ` (7 more replies)
  0 siblings, 8 replies; 18+ messages in thread
From: Alan Maguire @ 2020-04-17 10:42 UTC (permalink / raw)
  To: ast, daniel, yhs
  Cc: kafai, songliubraving, andriin, john.fastabend, kpsingh,
	linux-kernel, netdev, bpf, Alan Maguire

The printk family of functions support printing specific pointer types
using %p format specifiers (MAC addresses, IP addresses, etc).  For
full details see Documentation/core-api/printk-formats.rst.

This RFC patchset proposes introducing a "print typed pointer" format
specifier "%pT<type>"; the type specified is then looked up in the BPF
Type Format (BTF) information provided for vmlinux to support display.

There is already support in kernel/bpf/btf.c for "show" functionality;
the changes here generalize that support from seq-file specific
verifier display to the more generic case and add another specific
use case; snprintf()-style rendering of type information to a
provided buffer.  This support is then used to support printk
rendering of types, but the intent is to provide a function
that might be useful in other in-kernel scenarios; for example:

- ftrace could possibly utilize the function to support typed
  display of function arguments by cross-referencing BTF function
  information to derive the types of arguments
- oops/panic messaging could extend the information displayed to
  dig into data structures associated with failing functions

The above potential use cases hint at a potential reply to
a reasonable objection that such typed display should be
solved by tracing programs, where the in kernel tracing records
data and the userspace program prints it out.  While this
is certainly the recommended approach for most cases, I
believe having an in-kernel mechanism would be valuable
also.

The function the printk() family of functions rely on
could potentially be used directly for other use cases
like ftrace where we might have the BTF ids of the
pointers we wish to display; its signature is as follows:

int btf_type_snprintf_show(const struct btf *btf, u32 type_id, void *obj,
                           char *buf, int len, u64 flags);

So if ftrace say had the BTF ids of the types of arguments,
we see that the above would allow us to convert the
pointer data into displayable form.

To give a flavour for what the printed-out data looks like,
here we use pr_info() to display a struct sk_buff *.  Note
we specify the 'N' modifier to show type field names:

  struct sk_buff *skb = alloc_skb(64, GFP_KERNEL);

  pr_info("%pTN<struct sk_buff>", skb);

...gives us:

{{{.next=00000000c7916e9c,.prev=00000000c7916e9c,{.dev=00000000c7916e9c|.dev_scratch=0}}|.rbnode={.__rb_parent_color=0,.rb_right=00000000c7916e9c,.rb_left=00000000c7916e9c}|.list={.next=00000000c7916e9c,.prev=00000000c7916e9c}},{.sk=00000000c7916e9c|.ip_defrag_offset=0},{.tstamp=0|.skb_mstamp_ns=0},.cb=['\0'],{{._skb_refdst=0,.destructor=00000000c7916e9c}|.tcp_tsorted_anchor={.next=00000000c7916e9c,.prev=00000000c7916e9c}},._nfct=0,.len=0,.data_len=0,.mac_len=0,.hdr_len=0,.queue_mapping=0,.__cloned_offset=[],.cloned=0x0,.nohdr=0x0,.fclone=0x0,.peeked=0x0,.head_frag=0x0,.pfmemalloc=0x0,.active_extensions=0,.headers_start=[],.__pkt_type_offset=[],.pkt_type=0x0,.ignore_df=0x0,.nf_trace=0x0,.ip_summed=0x0,.ooo_okay=0x0,.l4_hash=0x0,.sw_hash=0x0,.wifi_acked_valid=0x0,.wifi_acked=0x0,.no_fcs=0x0,.encapsulation=0x0,.encap_hdr_csum=0x0,.csum_valid=0x0,.__pkt_vlan_present_offset=[],.vlan_present=0x0,.csum_complete_sw=0x0,.csum_level=0x0,.csum_not_inet=0x0,.dst_pending_co

printk output is truncated at 1024 bytes.  For such cases, the compact
display mode (minus the field info 'N') may be used at the expense of
readability. "|" differentiates between different union members, but
aside from that the format is intended to minic a valid C initiailizer
for the given type.

The hope is that this functionality will be useful for debugging,
and possibly help facilitate the cases mentioned above in the future.

The patches are marked RFC for several reasons

- There's already an RFC patchset in flight dealing with BTF dumping;

https://www.spinics.net/lists/netdev/msg644412.html

  The reason I'm posting this is the approach is a bit different 
  and there may be ways of synthesizing the approaches.
- The mechanism of vmlinux BTF initialization is not fit for purpose
  in a printk() setting as I understand it (it uses mutex locking
  to prevent multiple initializations of the BTF info).  A simple
  approach to support printk might be to simply initialize the
  BTF vmlinux case early in boot; it only needs to happen once.
  Any suggestions here would be great.
- BTF-based rendering is more complex than other printk() format
  specifier-driven methods; that said, because of its generality it
  does provide significant value I think
- More tests are needed.

Alan Maguire (6):
  bpf: provide function to get vmlinux BTF information
  bpf: btf->resolved_[ids,sizes] should not be used for vmlinux BTF
  bpf: move to generic BTF show support, apply it to seq files/strings
  checkpatch: add new BTF pointer format specifier
  printk: add type-printing %pT<type> format specifier which uses BTF
  printk: extend test_printf to test %pT BTF-based format specifier

 Documentation/core-api/printk-formats.rst |   8 +
 include/linux/bpf.h                       |   2 +
 include/linux/btf.h                       |  35 ++-
 kernel/bpf/btf.c                          | 466 ++++++++++++++++++++++++------
 kernel/bpf/verifier.c                     |  18 +-
 lib/Kconfig                               |  16 +
 lib/test_printf.c                         | 118 ++++++++
 lib/vsprintf.c                            | 145 +++++++++-
 scripts/checkpatch.pl                     |   2 +-
 9 files changed, 704 insertions(+), 106 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2020-05-02  0:25 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-17 10:42 [RFC PATCH bpf-next 0/6] bpf, printk: add BTF-based type printing Alan Maguire
2020-04-17 10:42 ` [RFC PATCH bpf-next 1/6] bpf: provide function to get vmlinux BTF information Alan Maguire
2020-04-17 10:42 ` [RFC PATCH bpf-next 2/6] bpf: btf->resolved_[ids,sizes] should not be used for vmlinux BTF Alan Maguire
2020-04-17 10:42 ` [RFC PATCH bpf-next 3/6] bpf: move to generic BTF show support, apply it to seq files/strings Alan Maguire
2020-04-17 10:42 ` [RFC PATCH bpf-next 4/6] checkpatch: add new BTF pointer format specifier Alan Maguire
2020-04-17 10:42 ` [RFC PATCH bpf-next 5/6] printk: add type-printing %pT<type> format specifier which uses BTF Alan Maguire
2020-04-29 12:09   ` Rasmus Villemoes
2020-04-17 10:42 ` [RFC PATCH bpf-next 6/6] printk: extend test_printf to test %pT BTF-based format specifier Alan Maguire
2020-04-17 16:47 ` [RFC PATCH bpf-next 0/6] bpf, printk: add BTF-based type printing Arnaldo Carvalho de Melo
2020-04-17 17:06   ` Alan Maguire
2020-04-18 16:05 ` Alexei Starovoitov
2020-04-18 20:31   ` Arnaldo Melo
2020-04-20 15:29   ` Alan Maguire
2020-04-20 16:32     ` Joe Perches
2020-04-29 12:15       ` Rasmus Villemoes
2020-04-30 10:03       ` Alan Maguire
2020-05-02  0:25         ` Joe Perches
2020-04-20 20:54   ` Arnaldo Carvalho de Melo

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).