All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 bpf-next 0/6] bpf: add helpers to support BTF-based kernel data display
@ 2020-09-23 17:46 Alan Maguire
  2020-09-23 17:46 ` [PATCH v6 bpf-next 1/6] bpf: provide function to get vmlinux BTF information Alan Maguire
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: Alan Maguire @ 2020-09-23 17:46 UTC (permalink / raw)
  To: ast, daniel, andriin, yhs
  Cc: linux, andriy.shevchenko, pmladek, kafai, songliubraving,
	john.fastabend, kpsingh, shuah, rdna, scott.branden, quentin,
	cneirabustos, jakub, mingo, rostedt, bpf, netdev, linux-kernel,
	linux-kselftest, acme, Alan Maguire

This series attempts to provide a simple way for BPF programs (and in
future other consumers) to utilize BPF Type Format (BTF) information
to display kernel data structures in-kernel.  The use case this
functionality is applied to here is to support a snprintf()-like
helper to copy a BTF representation of kernel data to a string,
and a BPF seq file helper to display BTF data for an iterator.

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; rather than seq_printf()ing the show data, it is copied
to a supplied string using a snprintf()-like function.  Other future
consumers of the show functionality could include a bpf_printk_btf()
function which printk()ed the data instead.  Oops messaging in
particular would be an interesting application for such functionality.

The above potential use case hints 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.  Critically in BPF programs it greatly simplifies
debugging and tracing of such data to invoking a simple
helper.

One challenge raised in an earlier iteration of this work -
where the BTF printing was implemented as a printk() format
specifier - was that the amount of data printed per
printk() was large, and other format specifiers were far
simpler.  Here we sidestep that concern by printing
components of the BTF representation as we go for the
seq file case, and in the string case the snprintf()-like
operation is intended to be a basis for perf event or
ringbuf output.  The reasons for avoiding bpf_trace_printk
are that

1. bpf_trace_printk() strings are restricted in size and
cannot display anything beyond trivial data structures; and
2. bpf_trace_printk() is for debugging purposes only.

As Alexei suggested, a bpf_trace_puts() helper could solve
this in the future but it still would be limited by the
1000 byte limit for traced strings.

Default output for an sk_buff looks like this (zeroed fields
are omitted):

(struct sk_buff){
 .transport_header = (__u16)65535,
 .mac_header = (__u16)65535,
 .end = (sk_buff_data_t)192,
 .head = (unsigned char *)0x000000007524fd8b,
 .data = (unsigned char *)0x000000007524fd8b,
 .truesize = (unsigned int)768,
 .users = (refcount_t){
  .refs = (atomic_t){
   .counter = (int)1,
  },
 },
}

Flags can modify aspects of output format; see patch 3
for more details.

Changes since v5:

- Moved btf print prepare into patch 3, type show seq
  with flags into patch 2 (Alexei, patches 2,3)
- Fixed build bot warnings around static declarations
  and printf attributes
- Renamed functions to snprintf_btf/seq_printf_btf
  (Alexei, patches 3-6)

Changes since v4:

- Changed approach from a BPF trace event-centric design to one
  utilizing a snprintf()-like helper and an iter helper (Alexei,
  patches 3,5)
- Added tests to verify BTF output (patch 4)
- Added support to tests for verifying BTF type_id-based display
  as well as type name via __builtin_btf_type_id (Andrii, patch 4).
- Augmented task iter tests to cover the BTF-based seq helper.
  Because a task_struct's BTF-based representation would overflow
  the PAGE_SIZE limit on iterator data, the "struct fs_struct"
  (task->fs) is displayed for each task instead (Alexei, patch 6).

Changes since v3:

- Moved to RFC since the approach is different (and bpf-next is
  closed)
- Rather than using a printk() format specifier as the means
  of invoking BTF-enabled display, a dedicated BPF helper is
  used.  This solves the issue of printk() having to output
  large amounts of data using a complex mechanism such as
  BTF traversal, but still provides a way for the display of
  such data to be achieved via BPF programs.  Future work could
  include a bpf_printk_btf() function to invoke display via
  printk() where the elements of a data structure are printk()ed
 one at a time.  Thanks to Petr Mladek, Andy Shevchenko and
  Rasmus Villemoes who took time to look at the earlier printk()
  format-specifier-focused version of this and provided feedback
  clarifying the problems with that approach.
- Added trace id to the bpf_trace_printk events as a means of
  separating output from standard bpf_trace_printk() events,
  ensuring it can be easily parsed by the reader.
- Added bpf_trace_btf() helper tests which do simple verification
  of the various display options.

Changes since v2:

- Alexei and Yonghong suggested it would be good to use
  probe_kernel_read() on to-be-shown data to ensure safety
  during operation.  Safe copy via probe_kernel_read() to a
  buffer object in "struct btf_show" is used to support
  this.  A few different approaches were explored
  including dynamic allocation and per-cpu buffers. The
  downside of dynamic allocation is that it would be done
  during BPF program execution for bpf_trace_printk()s using
  %pT format specifiers. The problem with per-cpu buffers
  is we'd have to manage preemption and since the display
  of an object occurs over an extended period and in printk
  context where we'd rather not change preemption status,
  it seemed tricky to manage buffer safety while considering
  preemption.  The approach of utilizing stack buffer space
  via the "struct btf_show" seemed like the simplest approach.
  The stack size of the associated functions which have a
  "struct btf_show" on their stack to support show operation
  (btf_type_snprintf_show() and btf_type_seq_show()) stays
  under 500 bytes. The compromise here is the safe buffer we
  use is small - 256 bytes - and as a result multiple
  probe_kernel_read()s are needed for larger objects. Most
  objects of interest are smaller than this (e.g.
  "struct sk_buff" is 224 bytes), and while task_struct is a
  notable exception at ~8K, performance is not the priority for
  BTF-based display. (Alexei and Yonghong, patch 2).
- safe buffer use is the default behaviour (and is mandatory
  for BPF) but unsafe display - meaning no safe copy is done
  and we operate on the object itself - is supported via a
  'u' option.
- pointers are prefixed with 0x for clarity (Alexei, patch 2)
- added additional comments and explanations around BTF show
  code, especially around determining whether objects such
  zeroed. Also tried to comment safe object scheme used. (Yonghong,
  patch 2)
- added late_initcall() to initialize vmlinux BTF so that it would
  not have to be initialized during printk operation (Alexei,
  patch 5)
- removed CONFIG_BTF_PRINTF config option as it is not needed;
  CONFIG_DEBUG_INFO_BTF can be used to gate test behaviour and
  determining behaviour of type-based printk can be done via
  retrieval of BTF data; if it's not there BTF was unavailable
  or broken (Alexei, patches 4,6)
- fix bpf_trace_printk test to use vmlinux.h and globals via
  skeleton infrastructure, removing need for perf events
  (Andrii, patch 8)

Changes since v1:

- changed format to be more drgn-like, rendering indented type info
  along with type names by default (Alexei)
- zeroed values are omitted (Arnaldo) by default unless the '0'
  modifier is specified (Alexei)
- added an option to print pointer values without obfuscation.
  The reason to do this is the sysctls controlling pointer display
  are likely to be irrelevant in many if not most tracing contexts.
  Some questions on this in the outstanding questions section below...
- reworked printk format specifer so that we no longer rely on format
  %pT<type> but instead use a struct * which contains type information
  (Rasmus). This simplifies the printk parsing, makes use more dynamic
  and also allows specification by BTF id as well as name.
- removed incorrect patch which tried to fix dereferencing of resolved
  BTF info for vmlinux; instead we skip modifiers for the relevant
  case (array element type determination) (Alexei).
- fixed issues with negative snprintf format length (Rasmus)
- added test cases for various data structure formats; base types,
  typedefs, structs, etc.
- tests now iterate through all typedef, enum, struct and unions
  defined for vmlinux BTF and render a version of the target dummy
  value which is either all zeros or all 0xff values; the idea is this
  exercises the "skip if zero" and "print everything" cases.
- added support in BPF for using the %pT format specifier in
  bpf_trace_printk()
- added BPF tests which ensure %pT format specifier use works (Alexei).

Alan Maguire (6):
  bpf: provide function to get vmlinux BTF information
  bpf: move to generic BTF show support, apply it to seq files/strings
  bpf: add bpf_snprintf_btf helper
  selftests/bpf: add bpf_snprintf_btf helper tests
  bpf: add bpf_seq_printf_btf helper
  selftests/bpf: add test for bpf_seq_printf_btf helper

 include/linux/bpf.h                                |   3 +
 include/linux/btf.h                                |  39 +
 include/uapi/linux/bpf.h                           |  78 ++
 kernel/bpf/btf.c                                   | 980 ++++++++++++++++++---
 kernel/bpf/core.c                                  |   2 +
 kernel/bpf/helpers.c                               |   4 +
 kernel/bpf/verifier.c                              |  18 +-
 kernel/trace/bpf_trace.c                           | 134 +++
 scripts/bpf_helpers_doc.py                         |   2 +
 tools/include/uapi/linux/bpf.h                     |  78 ++
 tools/testing/selftests/bpf/prog_tests/bpf_iter.c  |  66 ++
 .../selftests/bpf/prog_tests/snprintf_btf.c        |  54 ++
 .../selftests/bpf/progs/bpf_iter_task_btf.c        |  49 ++
 .../selftests/bpf/progs/netif_receive_skb.c        | 260 ++++++
 14 files changed, 1659 insertions(+), 108 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/snprintf_btf.c
 create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task_btf.c
 create mode 100644 tools/testing/selftests/bpf/progs/netif_receive_skb.c

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 17+ messages in thread
* Re: [PATCH v6 bpf-next 2/6] bpf: move to generic BTF show support, apply it to seq files/strings
@ 2020-09-24 16:03 kernel test robot
  0 siblings, 0 replies; 17+ messages in thread
From: kernel test robot @ 2020-09-24 16:03 UTC (permalink / raw)
  To: kbuild

[-- Attachment #1: Type: text/plain, Size: 16807 bytes --]

CC: kbuild-all(a)lists.01.org
In-Reply-To: <1600883188-4831-3-git-send-email-alan.maguire@oracle.com>
References: <1600883188-4831-3-git-send-email-alan.maguire@oracle.com>
TO: Alan Maguire <alan.maguire@oracle.com>
TO: ast(a)kernel.org
TO: daniel(a)iogearbox.net
TO: andriin(a)fb.com
TO: yhs(a)fb.com
CC: linux(a)rasmusvillemoes.dk
CC: andriy.shevchenko(a)linux.intel.com
CC: pmladek(a)suse.com
CC: kafai(a)fb.com
CC: songliubraving(a)fb.com
CC: john.fastabend(a)gmail.com

Hi Alan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on bpf-next/master]

url:    https://github.com/0day-ci/linux/commits/Alan-Maguire/bpf-add-helpers-to-support-BTF-based-kernel-data-display/20200924-015115
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
:::::: branch date: 22 hours ago
:::::: commit date: 22 hours ago
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


cppcheck warnings: (new ones prefixed by >>)

   kernel/bpf/btf.c:4438:38: warning: Either the condition 't?btf_type_vlen(t):5' is redundant or there is pointer arithmetic with NULL pointer. [nullPointerArithmeticRedundantCheck]
    args = (const struct btf_param *)(t + 1);
                                        ^
   kernel/bpf/btf.c:4440:14: note: Assuming that condition 't?btf_type_vlen(t):5' is not redundant
    nr_args = t ? btf_type_vlen(t) : 5;
                ^
   kernel/bpf/btf.c:4438:38: note: Null pointer addition
    args = (const struct btf_param *)(t + 1);
                                        ^
>> kernel/bpf/btf.c:831:4: warning: Variable 't' is reassigned a value before the old one has been used. [redundantAssignment]
    t = btf_type_by_id(show->btf, id);
      ^
   kernel/bpf/btf.c:799:0: note: Variable 't' is reassigned a value before the old one has been used.
    const struct btf_type *t = show->state.type;
   ^
   kernel/bpf/btf.c:831:4: note: Variable 't' is reassigned a value before the old one has been used.
    t = btf_type_by_id(show->btf, id);
      ^
   kernel/bpf/btf.c:4296:9: warning: Local variable btf_id shadows outer function [shadowFunction]
    int i, btf_id;
           ^
   kernel/bpf/btf.c:5526:5: note: Shadowed declaration
   u32 btf_id(const struct btf *btf)
       ^
   kernel/bpf/btf.c:4296:9: note: Shadow variable
    int i, btf_id;
           ^
   kernel/bpf/btf.c:5084:6: warning: Local variable btf_id shadows outer function [shadowFunction]
    u32 btf_id = 0;
        ^
   kernel/bpf/btf.c:5526:5: note: Shadowed declaration
   u32 btf_id(const struct btf *btf)
       ^
   kernel/bpf/btf.c:5084:6: note: Shadow variable
    u32 btf_id = 0;
        ^
   kernel/bpf/btf.c:5117:16: warning: Local variable btf_id shadows outer function [shadowFunction]
    u32 i, nargs, btf_id;
                  ^
   kernel/bpf/btf.c:5526:5: note: Shadowed declaration
   u32 btf_id(const struct btf *btf)
       ^
   kernel/bpf/btf.c:5117:16: note: Shadow variable
    u32 i, nargs, btf_id;
                  ^
   kernel/bpf/btf.c:5215:16: warning: Local variable btf_id shadows outer function [shadowFunction]
    u32 i, nargs, btf_id;
                  ^
   kernel/bpf/btf.c:5526:5: note: Shadowed declaration
   u32 btf_id(const struct btf *btf)
       ^
   kernel/bpf/btf.c:5215:16: note: Shadow variable
    u32 i, nargs, btf_id;
                  ^
>> kernel/bpf/btf.c:4200:5: warning: union member 'Anonymous2::__t' is never used. [unusedStructMember]
    } *__t;
       ^

# https://github.com/0day-ci/linux/commit/f8bb50c0c9cdac7a730f35d0e579c25d0bc3947f
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Alan-Maguire/bpf-add-helpers-to-support-BTF-based-kernel-data-display/20200924-015115
git checkout f8bb50c0c9cdac7a730f35d0e579c25d0bc3947f
vim +/t +831 kernel/bpf/btf.c

f8bb50c0c9cdac7 Alan Maguire 2020-09-23  782  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  783  /*
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  784   * Populate show->state.name with type name information.
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  785   * Format of type name is
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  786   *
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  787   * [.member_name = ] (type_name)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  788   */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  789  static inline const char *btf_show_name(struct btf_show *show)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  790  {
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  791  	/* BTF_MAX_ITER array suffixes "[]" */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  792  	const char *array_suffixes = "[][][][][][][][][][]";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  793  	const char *array_suffix = &array_suffixes[strlen(array_suffixes)];
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  794  	/* BTF_MAX_ITER pointer suffixes "*" */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  795  	const char *ptr_suffixes = "**********";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  796  	const char *ptr_suffix = &ptr_suffixes[strlen(ptr_suffixes)];
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  797  	const char *name = NULL, *prefix = "", *parens = "";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  798  	const struct btf_member *m = show->state.member;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  799  	const struct btf_type *t = show->state.type;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  800  	const struct btf_array *array;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  801  	u32 id = show->state.type_id;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  802  	const char *member = NULL;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  803  	bool show_member = false;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  804  	u64 kinds = 0;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  805  	int i;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  806  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  807  	show->state.name[0] = '\0';
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  808  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  809  	/*
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  810  	 * Don't show type name if we're showing an array member;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  811  	 * in that case we show the array type so don't need to repeat
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  812  	 * ourselves for each member.
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  813  	 */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  814  	if (show->state.array_member)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  815  		return "";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  816  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  817  	/* Retrieve member name, if any. */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  818  	if (m) {
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  819  		member = btf_name_by_offset(show->btf, m->name_off);
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  820  		show_member = strlen(member) > 0;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  821  		id = m->type;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  822  	}
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  823  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  824  	/*
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  825  	 * Start with type_id, as we have resolved the struct btf_type *
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  826  	 * via btf_modifier_show() past the parent typedef to the child
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  827  	 * struct, int etc it is defined as.  In such cases, the type_id
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  828  	 * still represents the starting type while the struct btf_type *
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  829  	 * in our show->state points at the resolved type of the typedef.
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  830  	 */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23 @831  	t = btf_type_by_id(show->btf, id);
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  832  	if (!t)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  833  		return "";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  834  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  835  	/*
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  836  	 * The goal here is to build up the right number of pointer and
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  837  	 * array suffixes while ensuring the type name for a typedef
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  838  	 * is represented.  Along the way we accumulate a list of
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  839  	 * BTF kinds we have encountered, since these will inform later
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  840  	 * display; for example, pointer types will not require an
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  841  	 * opening "{" for struct, we will just display the pointer value.
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  842  	 *
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  843  	 * We also want to accumulate the right number of pointer or array
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  844  	 * indices in the format string while iterating until we get to
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  845  	 * the typedef/pointee/array member target type.
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  846  	 *
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  847  	 * We start by pointing at the end of pointer and array suffix
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  848  	 * strings; as we accumulate pointers and arrays we move the pointer
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  849  	 * or array string backwards so it will show the expected number of
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  850  	 * '*' or '[]' for the type.  BTF_SHOW_MAX_ITER of nesting of pointers
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  851  	 * and/or arrays and typedefs are supported as a precaution.
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  852  	 *
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  853  	 * We also want to get typedef name while proceeding to resolve
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  854  	 * type it points to so that we can add parentheses if it is a
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  855  	 * "typedef struct" etc.
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  856  	 */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  857  	for (i = 0; i < BTF_SHOW_MAX_ITER; i++) {
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  858  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  859  		switch (BTF_INFO_KIND(t->info)) {
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  860  		case BTF_KIND_TYPEDEF:
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  861  			if (!name)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  862  				name = btf_name_by_offset(show->btf,
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  863  							       t->name_off);
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  864  			kinds |= BTF_KIND_BIT(BTF_KIND_TYPEDEF);
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  865  			id = t->type;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  866  			break;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  867  		case BTF_KIND_ARRAY:
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  868  			kinds |= BTF_KIND_BIT(BTF_KIND_ARRAY);
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  869  			parens = "[";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  870  			if (!t)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  871  				return "";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  872  			array = btf_type_array(t);
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  873  			if (array_suffix > array_suffixes)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  874  				array_suffix -= 2;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  875  			id = array->type;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  876  			break;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  877  		case BTF_KIND_PTR:
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  878  			kinds |= BTF_KIND_BIT(BTF_KIND_PTR);
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  879  			if (ptr_suffix > ptr_suffixes)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  880  				ptr_suffix -= 1;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  881  			id = t->type;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  882  			break;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  883  		default:
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  884  			id = 0;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  885  			break;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  886  		}
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  887  		if (!id)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  888  			break;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  889  		t = btf_type_skip_qualifiers(show->btf, id);
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  890  	}
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  891  	/* We may not be able to represent this type; bail to be safe */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  892  	if (i == BTF_SHOW_MAX_ITER)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  893  		return "";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  894  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  895  	if (!name)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  896  		name = btf_name_by_offset(show->btf, t->name_off);
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  897  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  898  	switch (BTF_INFO_KIND(t->info)) {
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  899  	case BTF_KIND_STRUCT:
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  900  	case BTF_KIND_UNION:
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  901  		prefix = BTF_INFO_KIND(t->info) == BTF_KIND_STRUCT ?
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  902  			 "struct" : "union";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  903  		/* if it's an array of struct/union, parens is already set */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  904  		if (!(kinds & (BTF_KIND_BIT(BTF_KIND_ARRAY))))
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  905  			parens = "{";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  906  		break;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  907  	case BTF_KIND_ENUM:
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  908  		prefix = "enum";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  909  		break;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  910  	default:
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  911  		break;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  912  	}
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  913  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  914  	/* pointer does not require parens */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  915  	if (kinds & BTF_KIND_BIT(BTF_KIND_PTR))
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  916  		parens = "";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  917  	/* typedef does not require struct/union/enum prefix */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  918  	if (kinds & BTF_KIND_BIT(BTF_KIND_TYPEDEF))
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  919  		prefix = "";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  920  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  921  	if (!name)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  922  		name = "";
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  923  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  924  	/* Even if we don't want type name info, we want parentheses etc */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  925  	if (show->flags & BTF_SHOW_NONAME)
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  926  		snprintf(show->state.name, sizeof(show->state.name), "%s",
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  927  			 parens);
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  928  	else
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  929  		snprintf(show->state.name, sizeof(show->state.name),
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  930  			 "%s%s%s(%s%s%s%s%s%s)%s",
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  931  			 /* first 3 strings comprise ".member = " */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  932  			 show_member ? "." : "",
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  933  			 show_member ? member : "",
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  934  			 show_member ? " = " : "",
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  935  			 /* ...next is our prefix (struct, enum, etc) */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  936  			 prefix,
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  937  			 strlen(prefix) > 0 && strlen(name) > 0 ? " " : "",
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  938  			 /* ...this is the type name itself */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  939  			 name,
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  940  			 /* ...suffixed by the appropriate '*', '[]' suffixes */
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  941  			 strlen(ptr_suffix) > 0 ? " " : "", ptr_suffix,
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  942  			 array_suffix, parens);
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  943  
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  944  	return show->state.name;
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  945  }
f8bb50c0c9cdac7 Alan Maguire 2020-09-23  946  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

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

end of thread, other threads:[~2020-09-29  1:55 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-09-23 17:46 [PATCH v6 bpf-next 0/6] bpf: add helpers to support BTF-based kernel data display Alan Maguire
2020-09-23 17:46 ` [PATCH v6 bpf-next 1/6] bpf: provide function to get vmlinux BTF information Alan Maguire
2020-09-23 17:46 ` [PATCH v6 bpf-next 2/6] bpf: move to generic BTF show support, apply it to seq files/strings Alan Maguire
2020-09-23 19:38   ` kernel test robot
2020-09-25  0:33   ` Alexei Starovoitov
2020-09-23 17:46 ` [PATCH v6 bpf-next 3/6] bpf: add bpf_snprintf_btf helper Alan Maguire
2020-09-25  0:42   ` Alexei Starovoitov
2020-09-23 17:46 ` [PATCH v6 bpf-next 4/6] selftests/bpf: add bpf_snprintf_btf helper tests Alan Maguire
2020-09-25  0:50   ` Alexei Starovoitov
2020-09-25 17:36     ` Andrii Nakryiko
2020-09-23 17:46 ` [PATCH v6 bpf-next 5/6] bpf: add bpf_seq_printf_btf helper Alan Maguire
2020-09-23 17:46 ` [PATCH v6 bpf-next 6/6] selftests/bpf: add test for " Alan Maguire
2020-09-25  1:26   ` Alexei Starovoitov
2020-09-28 14:12     ` Alan Maguire
2020-09-28 17:51       ` Andrii Nakryiko
2020-09-29  1:54         ` Alexei Starovoitov
  -- strict thread matches above, loose matches on Subject: below --
2020-09-24 16:03 [PATCH v6 bpf-next 2/6] bpf: move to generic BTF show support, apply it to seq files/strings kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.