diff options
Diffstat (limited to 'tools/bpf/bpftool')
28 files changed, 215 insertions, 85 deletions
| diff --git a/tools/bpf/bpftool/Documentation/bpftool-btf.rst b/tools/bpf/bpftool/Documentation/bpftool-btf.rst index ff4d327a582e..88b28aa7431f 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-btf.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-btf.rst @@ -12,7 +12,8 @@ SYNOPSIS  	**bpftool** [*OPTIONS*] **btf** *COMMAND* -	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] } +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | {**-d** | **--debug** } | +		{ **-B** | **--base-btf** } }  	*COMMANDS* := { **dump** | **help** } @@ -73,6 +74,20 @@ OPTIONS  =======  	.. include:: common_options.rst +	-B, --base-btf *FILE* +		  Pass a base BTF object. Base BTF objects are typically used +		  with BTF objects for kernel modules. To avoid duplicating +		  all kernel symbols required by modules, BTF objects for +		  modules are "split", they are built incrementally on top of +		  the kernel (vmlinux) BTF object. So the base BTF reference +		  should usually point to the kernel BTF. + +		  When the main BTF object to process (for example, the +		  module BTF to dump) is passed as a *FILE*, bpftool attempts +		  to autodetect the path for the base object, and passing +		  this option is optional. When the main BTF object is passed +		  through other handles, this option becomes necessary. +  EXAMPLES  ========  **# bpftool btf dump id 1226** @@ -217,3 +232,34 @@ All the standard ways to specify map or program are supported:  **# bpftool btf dump prog tag b88e0a09b1d9759d**  **# bpftool btf dump prog pinned /sys/fs/bpf/prog_name** + +| +| **# bpftool btf dump file /sys/kernel/btf/i2c_smbus** +| (or) +| **# I2C_SMBUS_ID=$(bpftool btf show -p | jq '.[] | select(.name=="i2c_smbus").id')** +| **# bpftool btf dump id ${I2C_SMBUS_ID} -B /sys/kernel/btf/vmlinux** + +:: + +  [104848] STRUCT 'i2c_smbus_alert' size=40 vlen=2 +          'alert' type_id=393 bits_offset=0 +          'ara' type_id=56050 bits_offset=256 +  [104849] STRUCT 'alert_data' size=12 vlen=3 +          'addr' type_id=16 bits_offset=0 +          'type' type_id=56053 bits_offset=32 +          'data' type_id=7 bits_offset=64 +  [104850] PTR '(anon)' type_id=104848 +  [104851] PTR '(anon)' type_id=104849 +  [104852] FUNC 'i2c_register_spd' type_id=84745 linkage=static +  [104853] FUNC 'smbalert_driver_init' type_id=1213 linkage=static +  [104854] FUNC_PROTO '(anon)' ret_type_id=18 vlen=1 +          'ara' type_id=56050 +  [104855] FUNC 'i2c_handle_smbus_alert' type_id=104854 linkage=static +  [104856] FUNC 'smbalert_remove' type_id=104854 linkage=static +  [104857] FUNC_PROTO '(anon)' ret_type_id=18 vlen=2 +          'ara' type_id=56050 +          'id' type_id=56056 +  [104858] FUNC 'smbalert_probe' type_id=104857 linkage=static +  [104859] FUNC 'smbalert_work' type_id=9695 linkage=static +  [104860] FUNC 'smbus_alert' type_id=71367 linkage=static +  [104861] FUNC 'smbus_do_alert' type_id=84827 linkage=static diff --git a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst index baee8591ac76..3e4395eede4f 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst @@ -12,7 +12,8 @@ SYNOPSIS  	**bpftool** [*OPTIONS*] **cgroup** *COMMAND* -	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } | +		{ **-f** | **--bpffs** } }  	*COMMANDS* :=  	{ **show** | **list** | **tree** | **attach** | **detach** | **help** } diff --git a/tools/bpf/bpftool/Documentation/bpftool-feature.rst b/tools/bpf/bpftool/Documentation/bpftool-feature.rst index dd3771bdbc57..ab9f57ee4c3a 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-feature.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-feature.rst @@ -12,7 +12,7 @@ SYNOPSIS  	**bpftool** [*OPTIONS*] **feature** *COMMAND* -	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] } +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } }  	*COMMANDS* := { **probe** | **help** } diff --git a/tools/bpf/bpftool/Documentation/bpftool-gen.rst b/tools/bpf/bpftool/Documentation/bpftool-gen.rst index 7cd6681137f3..2ef2f2df0279 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-gen.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-gen.rst @@ -12,7 +12,8 @@ SYNOPSIS  	**bpftool** [*OPTIONS*] **gen** *COMMAND* -	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] } +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } | +		{ **-L** | **--use-loader** } }  	*COMMAND* := { **object** | **skeleton** | **help** } @@ -152,6 +153,12 @@ OPTIONS  =======  	.. include:: common_options.rst +	-L, --use-loader +		  For skeletons, generate a "light" skeleton (also known as "loader" +		  skeleton). A light skeleton contains a loader eBPF program. It does +		  not use the majority of the libbpf infrastructure, and does not need +		  libelf. +  EXAMPLES  ========  **$ cat example1.bpf.c** diff --git a/tools/bpf/bpftool/Documentation/bpftool-iter.rst b/tools/bpf/bpftool/Documentation/bpftool-iter.rst index 51f49bead619..471f363a725a 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-iter.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-iter.rst @@ -12,6 +12,8 @@ SYNOPSIS  	**bpftool** [*OPTIONS*] **iter** *COMMAND* +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } } +  	*COMMANDS* := { **pin** | **help** }  ITER COMMANDS diff --git a/tools/bpf/bpftool/Documentation/bpftool-link.rst b/tools/bpf/bpftool/Documentation/bpftool-link.rst index 5f7db2a837cc..0de90f086238 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-link.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-link.rst @@ -12,7 +12,8 @@ SYNOPSIS  	**bpftool** [*OPTIONS*] **link** *COMMAND* -	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } | +		{ **-f** | **--bpffs** } | { **-n** | **--nomount** } }  	*COMMANDS* := { **show** | **list** | **pin** | **help** } diff --git a/tools/bpf/bpftool/Documentation/bpftool-map.rst b/tools/bpf/bpftool/Documentation/bpftool-map.rst index 3d52256ba75f..d0c4abe08aba 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-map.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-map.rst @@ -12,7 +12,8 @@ SYNOPSIS  	**bpftool** [*OPTIONS*] **map** *COMMAND* -	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } | +		{ **-f** | **--bpffs** } | { **-n** | **--nomount** } }  	*COMMANDS* :=  	{ **show** | **list** | **create** | **dump** | **update** | **lookup** | **getnext** diff --git a/tools/bpf/bpftool/Documentation/bpftool-net.rst b/tools/bpf/bpftool/Documentation/bpftool-net.rst index d8165d530937..1ae0375e8fea 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-net.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-net.rst @@ -12,7 +12,7 @@ SYNOPSIS  	**bpftool** [*OPTIONS*] **net** *COMMAND* -	*OPTIONS* := { [{ **-j** | **--json** }] [{ **-p** | **--pretty** }] } +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } }  	*COMMANDS* :=  	{ **show** | **list** | **attach** | **detach** | **help** } diff --git a/tools/bpf/bpftool/Documentation/bpftool-perf.rst b/tools/bpf/bpftool/Documentation/bpftool-perf.rst index e958ce91de72..ce52798a917d 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-perf.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-perf.rst @@ -12,7 +12,7 @@ SYNOPSIS  	**bpftool** [*OPTIONS*] **perf** *COMMAND* -	*OPTIONS* := { [{ **-j** | **--json** }] [{ **-p** | **--pretty** }] } +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } }  	*COMMANDS* :=  	{ **show** | **list** | **help** } diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index fe1b38e7e887..91608cb7e44a 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst @@ -12,7 +12,9 @@ SYNOPSIS  	**bpftool** [*OPTIONS*] **prog** *COMMAND* -	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } | +		{ **-f** | **--bpffs** } | { **-m** | **--mapcompat** } | { **-n** | **--nomount** } | +		{ **-L** | **--use-loader** } }  	*COMMANDS* :=  	{ **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load** @@ -48,10 +50,11 @@ PROG COMMANDS  |		**struct_ops** | **fentry** | **fexit** | **freplace** | **sk_lookup**  |	}  |       *ATTACH_TYPE* := { -|		**msg_verdict** | **stream_verdict** | **stream_parser** | **flow_dissector** +|		**msg_verdict** | **skb_verdict** | **stream_verdict** | **stream_parser** | **flow_dissector**  |	}  |	*METRICs* := { -|		**cycles** | **instructions** | **l1d_loads** | **llc_misses** +|		**cycles** | **instructions** | **l1d_loads** | **llc_misses** | +|		**itlb_misses** | **dtlb_misses**  |	} @@ -223,6 +226,20 @@ OPTIONS  		  Do not automatically attempt to mount any virtual file system  		  (such as tracefs or BPF virtual file system) when necessary. +	-L, --use-loader +		  Load program as a "loader" program. This is useful to debug +		  the generation of such programs. When this option is in +		  use, bpftool attempts to load the programs from the object +		  file into the kernel, but does not pin them (therefore, the +		  *PATH* must not be provided). + +		  When combined with the **-d**\ \|\ **--debug** option, +		  additional debug messages are generated, and the execution +		  of the loader program will use the **bpf_trace_printk**\ () +		  helper to log each step of loading BTF, creating the maps, +		  and loading the programs (see **bpftool prog tracelog** as +		  a way to dump those messages). +  EXAMPLES  ========  **# bpftool prog show** @@ -326,3 +343,16 @@ EXAMPLES        40176203 cycles                                                 (83.05%)        42518139 instructions    #   1.06 insns per cycle               (83.39%)             123 llc_misses      #   2.89 LLC misses per million insns  (83.15%) + +| +| Output below is for the trace logs. +| Run in separate terminals: +| **# bpftool prog tracelog** +| **# bpftool prog load -L -d file.o** + +:: + +    bpftool-620059  [004] d... 2634685.517903: bpf_trace_printk: btf_load size 665 r=5 +    bpftool-620059  [004] d... 2634685.517912: bpf_trace_printk: map_create sample_map idx 0 type 2 value_size 4 value_btf_id 0 r=6 +    bpftool-620059  [004] d... 2634685.517997: bpf_trace_printk: prog_load sample insn_cnt 13 r=7 +    bpftool-620059  [004] d... 2634685.517999: bpf_trace_printk: close(5) = 0 diff --git a/tools/bpf/bpftool/Documentation/bpftool-struct_ops.rst b/tools/bpf/bpftool/Documentation/bpftool-struct_ops.rst index 506e70ee78e9..02afc0fc14cb 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-struct_ops.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-struct_ops.rst @@ -12,7 +12,7 @@ SYNOPSIS  	**bpftool** [*OPTIONS*] **struct_ops** *COMMAND* -	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] } +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } }  	*COMMANDS* :=  	{ **show** | **list** | **dump** | **register** | **unregister** | **help** } diff --git a/tools/bpf/bpftool/Documentation/bpftool.rst b/tools/bpf/bpftool/Documentation/bpftool.rst index e7d949334961..bb23f55bb05a 100644 --- a/tools/bpf/bpftool/Documentation/bpftool.rst +++ b/tools/bpf/bpftool/Documentation/bpftool.rst @@ -18,15 +18,15 @@ SYNOPSIS  	*OBJECT* := { **map** | **program** | **cgroup** | **perf** | **net** | **feature** } -	*OPTIONS* := { { **-V** | **--version** } | { **-h** | **--help** } -	| { **-j** | **--json** } [{ **-p** | **--pretty** }] } +	*OPTIONS* := { { **-V** | **--version** } | +		{ **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } }  	*MAP-COMMANDS* := -	{ **show** | **list** | **create** | **dump** | **update** | **lookup** | **getnext** -	| **delete** | **pin** | **event_pipe** | **help** } +	{ **show** | **list** | **create** | **dump** | **update** | **lookup** | **getnext** | +		**delete** | **pin** | **event_pipe** | **help** } -	*PROG-COMMANDS* := { **show** | **list** | **dump jited** | **dump xlated** | **pin** -	| **load** | **attach** | **detach** | **help** } +	*PROG-COMMANDS* := { **show** | **list** | **dump jited** | **dump xlated** | **pin** | +		**load** | **attach** | **detach** | **help** }  	*CGROUP-COMMANDS* := { **show** | **list** | **attach** | **detach** | **help** } diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index cc33c5824a2f..88e2bcf16cca 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -260,7 +260,8 @@ _bpftool()      # Deal with options      if [[ ${words[cword]} == -* ]]; then -        local c='--version --json --pretty --bpffs --mapcompat --debug' +        local c='--version --json --pretty --bpffs --mapcompat --debug \ +	       --use-loader --base-btf'          COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )          return 0      fi @@ -278,7 +279,7 @@ _bpftool()              _sysfs_get_netdevs              return 0              ;; -        file|pinned) +        file|pinned|-B|--base-btf)              _filedir              return 0              ;; @@ -291,7 +292,8 @@ _bpftool()      # Remove all options so completions don't have to deal with them.      local i      for (( i=1; i < ${#words[@]}; )); do -        if [[ ${words[i]::1} == - ]]; then +        if [[ ${words[i]::1} == - ]] && +            [[ ${words[i]} != "-B" ]] && [[ ${words[i]} != "--base-btf" ]]; then              words=( "${words[@]:0:i}" "${words[@]:i+1}" )              [[ $i -le $cword ]] && cword=$(( cword - 1 ))          else @@ -343,7 +345,8 @@ _bpftool()              local PROG_TYPE='id pinned tag name'              local MAP_TYPE='id pinned name' -            local METRIC_TYPE='cycles instructions l1d_loads llc_misses' +            local METRIC_TYPE='cycles instructions l1d_loads llc_misses \ +                itlb_misses dtlb_misses'              case $command in                  show|list)                      [[ $prev != "$command" ]] && return 0 @@ -404,8 +407,10 @@ _bpftool()                              return 0                              ;;                          5) -                            COMPREPLY=( $( compgen -W 'msg_verdict stream_verdict \ -                                stream_parser flow_dissector' -- "$cur" ) ) +                            local BPFTOOL_PROG_ATTACH_TYPES='msg_verdict \ +                                skb_verdict stream_verdict stream_parser \ +                                flow_dissector' +                            COMPREPLY=( $( compgen -W "$BPFTOOL_PROG_ATTACH_TYPES" -- "$cur" ) )                              return 0                              ;;                          6) @@ -464,7 +469,7 @@ _bpftool()                      case $prev in                          type) -                            COMPREPLY=( $( compgen -W "socket kprobe \ +                            local BPFTOOL_PROG_LOAD_TYPES='socket kprobe \                                  kretprobe classifier flow_dissector \                                  action tracepoint raw_tracepoint \                                  xdp perf_event cgroup/skb cgroup/sock \ @@ -479,8 +484,8 @@ _bpftool()                                  cgroup/post_bind4 cgroup/post_bind6 \                                  cgroup/sysctl cgroup/getsockopt \                                  cgroup/setsockopt cgroup/sock_release struct_ops \ -                                fentry fexit freplace sk_lookup" -- \ -                                                   "$cur" ) ) +                                fentry fexit freplace sk_lookup' +                            COMPREPLY=( $( compgen -W "$BPFTOOL_PROG_LOAD_TYPES" -- "$cur" ) )                              return 0                              ;;                          id) @@ -698,15 +703,15 @@ _bpftool()                              return 0                              ;;                          type) -                            COMPREPLY=( $( compgen -W 'hash array prog_array \ -                                perf_event_array percpu_hash percpu_array \ -                                stack_trace cgroup_array lru_hash \ +                            local BPFTOOL_MAP_CREATE_TYPES='hash array \ +                                prog_array perf_event_array percpu_hash \ +                                percpu_array stack_trace cgroup_array lru_hash \                                  lru_percpu_hash lpm_trie array_of_maps \                                  hash_of_maps devmap devmap_hash sockmap cpumap \                                  xskmap sockhash cgroup_storage reuseport_sockarray \                                  percpu_cgroup_storage queue stack sk_storage \ -                                struct_ops inode_storage task_storage' -- \ -                                                   "$cur" ) ) +                                struct_ops inode_storage task_storage ringbuf' +                            COMPREPLY=( $( compgen -W "$BPFTOOL_MAP_CREATE_TYPES" -- "$cur" ) )                              return 0                              ;;                          key|value|flags|entries) @@ -1017,34 +1022,37 @@ _bpftool()                      return 0                      ;;                  attach|detach) -                    local ATTACH_TYPES='ingress egress sock_create sock_ops \ -                        device bind4 bind6 post_bind4 post_bind6 connect4 connect6 \ +                    local BPFTOOL_CGROUP_ATTACH_TYPES='ingress egress \ +                        sock_create sock_ops device \ +                        bind4 bind6 post_bind4 post_bind6 connect4 connect6 \                          getpeername4 getpeername6 getsockname4 getsockname6 \                          sendmsg4 sendmsg6 recvmsg4 recvmsg6 sysctl getsockopt \                          setsockopt sock_release'                      local ATTACH_FLAGS='multi override'                      local PROG_TYPE='id pinned tag name' -                    case $prev in -                        $command) -                            _filedir -                            return 0 -                            ;; -                        ingress|egress|sock_create|sock_ops|device|bind4|bind6|\ -                        post_bind4|post_bind6|connect4|connect6|getpeername4|\ -                        getpeername6|getsockname4|getsockname6|sendmsg4|sendmsg6|\ -                        recvmsg4|recvmsg6|sysctl|getsockopt|setsockopt|sock_release) +                    # Check for $prev = $command first +                    if [ $prev = $command ]; then +                        _filedir +                        return 0 +                    # Then check for attach type. This is done outside of the +                    # "case $prev in" to avoid writing the whole list of attach +                    # types again as pattern to match (where we cannot reuse +                    # our variable). +                    elif [[ $BPFTOOL_CGROUP_ATTACH_TYPES =~ $prev ]]; then                              COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \                                  "$cur" ) )                              return 0 -                            ;; +                    fi +                    # case/esac for the other cases +                    case $prev in                          id)                              _bpftool_get_prog_ids                              return 0                              ;;                          *) -                            if ! _bpftool_search_list "$ATTACH_TYPES"; then -                                COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- \ -                                    "$cur" ) ) +                            if ! _bpftool_search_list "$BPFTOOL_CGROUP_ATTACH_TYPES"; then +                                COMPREPLY=( $( compgen -W \ +                                    "$BPFTOOL_CGROUP_ATTACH_TYPES" -- "$cur" ) )                              elif [[ "$command" == "attach" ]]; then                                  # We have an attach type on the command line,                                  # but it is not the previous word, or diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c index 385d5c955cf3..f7e5ff3586c9 100644 --- a/tools/bpf/bpftool/btf.c +++ b/tools/bpf/bpftool/btf.c @@ -580,16 +580,12 @@ static int do_dump(int argc, char **argv)  	}  	if (!btf) { -		err = btf__get_from_id(btf_id, &btf); +		btf = btf__load_from_kernel_by_id_split(btf_id, base_btf); +		err = libbpf_get_error(btf);  		if (err) {  			p_err("get btf by id (%u): %s", btf_id, strerror(err));  			goto done;  		} -		if (!btf) { -			err = -ENOENT; -			p_err("can't find btf with ID (%u)", btf_id); -			goto done; -		}  	}  	if (dump_c) { @@ -985,7 +981,8 @@ static int do_help(int argc, char **argv)  		"       FORMAT  := { raw | c }\n"  		"       " HELP_SPEC_MAP "\n"  		"       " HELP_SPEC_PROGRAM "\n" -		"       " HELP_SPEC_OPTIONS "\n" +		"       " HELP_SPEC_OPTIONS " |\n" +		"                    {-B|--base-btf} }\n"  		"",  		bin_name, "btf"); diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c index 7ca54d046362..9c25286a5c73 100644 --- a/tools/bpf/bpftool/btf_dumper.c +++ b/tools/bpf/bpftool/btf_dumper.c @@ -64,8 +64,10 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d,  	}  	info = &prog_info->info; -	if (!info->btf_id || !info->nr_func_info || -	    btf__get_from_id(info->btf_id, &prog_btf)) +	if (!info->btf_id || !info->nr_func_info) +		goto print; +	prog_btf = btf__load_from_kernel_by_id(info->btf_id); +	if (libbpf_get_error(prog_btf))  		goto print;  	finfo = u64_to_ptr(info->func_info);  	func_type = btf__type_by_id(prog_btf, finfo->type_id); diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c index 6e53b1d393f4..3571a281c43f 100644 --- a/tools/bpf/bpftool/cgroup.c +++ b/tools/bpf/bpftool/cgroup.c @@ -501,7 +501,8 @@ static int do_help(int argc, char **argv)  		HELP_SPEC_ATTACH_TYPES "\n"  		"       " HELP_SPEC_ATTACH_FLAGS "\n"  		"       " HELP_SPEC_PROGRAM "\n" -		"       " HELP_SPEC_OPTIONS "\n" +		"       " HELP_SPEC_OPTIONS " |\n" +		"                    {-f|--bpffs} }\n"  		"",  		bin_name, argv[-2]); diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 1828bba19020..d42d930a3ec4 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c @@ -67,6 +67,12 @@ const char * const attach_type_name[__MAX_BPF_ATTACH_TYPE] = {  	[BPF_MODIFY_RETURN]		= "mod_ret",  	[BPF_LSM_MAC]			= "lsm_mac",  	[BPF_SK_LOOKUP]			= "sk_lookup", +	[BPF_TRACE_ITER]		= "trace_iter", +	[BPF_XDP_DEVMAP]		= "xdp_devmap", +	[BPF_XDP_CPUMAP]		= "xdp_cpumap", +	[BPF_XDP]			= "xdp", +	[BPF_SK_REUSEPORT_SELECT]	= "sk_skb_reuseport_select", +	[BPF_SK_REUSEPORT_SELECT_OR_MIGRATE]	= "sk_skb_reuseport_select_or_migrate",  };  void p_err(const char *fmt, ...) @@ -222,6 +228,11 @@ int mount_bpffs_for_pin(const char *name)  	int err = 0;  	file = malloc(strlen(name) + 1); +	if (!file) { +		p_err("mem alloc failed"); +		return -1; +	} +  	strcpy(file, name);  	dir = dirname(file); diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c index 40a88df275f9..7f36385aa9e2 100644 --- a/tools/bpf/bpftool/feature.c +++ b/tools/bpf/bpftool/feature.c @@ -1005,6 +1005,7 @@ static int do_help(int argc, char **argv)  		"       %1$s %2$s help\n"  		"\n"  		"       COMPONENT := { kernel | dev NAME }\n" +		"       " HELP_SPEC_OPTIONS " }\n"  		"",  		bin_name, argv[-2]); diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c index 1d71ff8c52fa..d40d92bbf0e4 100644 --- a/tools/bpf/bpftool/gen.c +++ b/tools/bpf/bpftool/gen.c @@ -1026,7 +1026,8 @@ static int do_help(int argc, char **argv)  		"       %1$s %2$s skeleton FILE [name OBJECT_NAME]\n"  		"       %1$s %2$s help\n"  		"\n" -		"       " HELP_SPEC_OPTIONS "\n" +		"       " HELP_SPEC_OPTIONS " |\n" +		"                    {-L|--use-loader} }\n"  		"",  		bin_name, "gen"); diff --git a/tools/bpf/bpftool/iter.c b/tools/bpf/bpftool/iter.c index 3b1aad7535dd..84a9b01d956d 100644 --- a/tools/bpf/bpftool/iter.c +++ b/tools/bpf/bpftool/iter.c @@ -97,7 +97,9 @@ static int do_help(int argc, char **argv)  	fprintf(stderr,  		"Usage: %1$s %2$s pin OBJ PATH [map MAP]\n"  		"       %1$s %2$s help\n" +		"\n"  		"       " HELP_SPEC_MAP "\n" +		"       " HELP_SPEC_OPTIONS " }\n"  		"",  		bin_name, "iter"); diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c index e77e1525d20a..8cc3e36f8cc6 100644 --- a/tools/bpf/bpftool/link.c +++ b/tools/bpf/bpftool/link.c @@ -401,7 +401,8 @@ static int do_help(int argc, char **argv)  		"       %1$s %2$s help\n"  		"\n"  		"       " HELP_SPEC_LINK "\n" -		"       " HELP_SPEC_OPTIONS "\n" +		"       " HELP_SPEC_OPTIONS " |\n" +		"                    {-f|--bpffs} | {-n|--nomount} }\n"  		"",  		bin_name, argv[-2]); diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c index 3ddfd4843738..02eaaf065f65 100644 --- a/tools/bpf/bpftool/main.c +++ b/tools/bpf/bpftool/main.c @@ -64,7 +64,8 @@ static int do_help(int argc, char **argv)  		"       %s version\n"  		"\n"  		"       OBJECT := { prog | map | link | cgroup | perf | net | feature | btf | gen | struct_ops | iter }\n" -		"       " HELP_SPEC_OPTIONS "\n" +		"       " HELP_SPEC_OPTIONS " |\n" +		"                    {-V|--version} }\n"  		"",  		bin_name, bin_name, bin_name); diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h index c1cf29798b99..90caa42aac4c 100644 --- a/tools/bpf/bpftool/main.h +++ b/tools/bpf/bpftool/main.h @@ -57,8 +57,7 @@ static inline void *u64_to_ptr(__u64 ptr)  #define HELP_SPEC_PROGRAM						\  	"PROG := { id PROG_ID | pinned FILE | tag PROG_TAG | name PROG_NAME }"  #define HELP_SPEC_OPTIONS						\ -	"OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} |\n"	\ -	"\t            {-m|--mapcompat} | {-n|--nomount} }" +	"OPTIONS := { {-j|--json} [{-p|--pretty}] | {-d|--debug}"  #define HELP_SPEC_MAP							\  	"MAP := { id MAP_ID | pinned FILE | name MAP_NAME }"  #define HELP_SPEC_LINK							\ diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index 09ae0381205b..407071d54ab1 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c @@ -807,10 +807,11 @@ static struct btf *get_map_kv_btf(const struct bpf_map_info *info)  	} else if (info->btf_value_type_id) {  		int err; -		err = btf__get_from_id(info->btf_id, &btf); -		if (err || !btf) { +		btf = btf__load_from_kernel_by_id(info->btf_id); +		err = libbpf_get_error(btf); +		if (err) {  			p_err("failed to get btf"); -			btf = err ? ERR_PTR(err) : ERR_PTR(-ESRCH); +			btf = ERR_PTR(err);  		}  	} @@ -1039,11 +1040,10 @@ static void print_key_value(struct bpf_map_info *info, void *key,  			    void *value)  {  	json_writer_t *btf_wtr; -	struct btf *btf = NULL; -	int err; +	struct btf *btf; -	err = btf__get_from_id(info->btf_id, &btf); -	if (err) { +	btf = btf__load_from_kernel_by_id(info->btf_id); +	if (libbpf_get_error(btf)) {  		p_err("failed to get btf");  		return;  	} @@ -1466,8 +1466,9 @@ static int do_help(int argc, char **argv)  		"                 devmap | devmap_hash | sockmap | cpumap | xskmap | sockhash |\n"  		"                 cgroup_storage | reuseport_sockarray | percpu_cgroup_storage |\n"  		"                 queue | stack | sk_storage | struct_ops | ringbuf | inode_storage |\n" -		"		  task_storage }\n" -		"       " HELP_SPEC_OPTIONS "\n" +		"                 task_storage }\n" +		"       " HELP_SPEC_OPTIONS " |\n" +		"                    {-f|--bpffs} | {-n|--nomount} }\n"  		"",  		bin_name, argv[-2]); diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c index f836d115d7d6..649053704bd7 100644 --- a/tools/bpf/bpftool/net.c +++ b/tools/bpf/bpftool/net.c @@ -729,6 +729,7 @@ static int do_help(int argc, char **argv)  		"\n"  		"       " HELP_SPEC_PROGRAM "\n"  		"       ATTACH_TYPE := { xdp | xdpgeneric | xdpdrv | xdpoffload }\n" +		"       " HELP_SPEC_OPTIONS " }\n"  		"\n"  		"Note: Only xdp and tc attachments are supported now.\n"  		"      For progs attached to cgroups, use \"bpftool cgroup\"\n" diff --git a/tools/bpf/bpftool/perf.c b/tools/bpf/bpftool/perf.c index ad23934819c7..50de087b0db7 100644 --- a/tools/bpf/bpftool/perf.c +++ b/tools/bpf/bpftool/perf.c @@ -231,7 +231,10 @@ static int do_show(int argc, char **argv)  static int do_help(int argc, char **argv)  {  	fprintf(stderr, -		"Usage: %1$s %2$s { show | list | help }\n" +		"Usage: %1$s %2$s { show | list }\n" +		"       %1$s %2$s help }\n" +		"\n" +		"       " HELP_SPEC_OPTIONS " }\n"  		"",  		bin_name, argv[-2]); diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index cc48726740ad..9c3e343b7d87 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -249,10 +249,10 @@ static void show_prog_metadata(int fd, __u32 num_maps)  	struct bpf_map_info map_info;  	struct btf_var_secinfo *vsi;  	bool printed_header = false; -	struct btf *btf = NULL;  	unsigned int i, vlen;  	void *value = NULL;  	const char *name; +	struct btf *btf;  	int err;  	if (!num_maps) @@ -263,8 +263,8 @@ static void show_prog_metadata(int fd, __u32 num_maps)  	if (!value)  		return; -	err = btf__get_from_id(map_info.btf_id, &btf); -	if (err || !btf) +	btf = btf__load_from_kernel_by_id(map_info.btf_id); +	if (libbpf_get_error(btf))  		goto out_free;  	t_datasec = btf__type_by_id(btf, map_info.btf_value_type_id); @@ -646,9 +646,12 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,  		member_len = info->xlated_prog_len;  	} -	if (info->btf_id && btf__get_from_id(info->btf_id, &btf)) { -		p_err("failed to get btf"); -		return -1; +	if (info->btf_id) { +		btf = btf__load_from_kernel_by_id(info->btf_id); +		if (libbpf_get_error(btf)) { +			p_err("failed to get btf"); +			return -1; +		}  	}  	func_info = u64_to_ptr(info->func_info); @@ -781,6 +784,8 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,  		kernel_syms_destroy(&dd);  	} +	btf__free(btf); +  	return 0;  } @@ -2002,8 +2007,8 @@ static char *profile_target_name(int tgt_fd)  	struct bpf_prog_info_linear *info_linear;  	struct bpf_func_info *func_info;  	const struct btf_type *t; +	struct btf *btf = NULL;  	char *name = NULL; -	struct btf *btf;  	info_linear = bpf_program__get_prog_info_linear(  		tgt_fd, 1UL << BPF_PROG_INFO_FUNC_INFO); @@ -2012,12 +2017,17 @@ static char *profile_target_name(int tgt_fd)  		return NULL;  	} -	if (info_linear->info.btf_id == 0 || -	    btf__get_from_id(info_linear->info.btf_id, &btf)) { +	if (info_linear->info.btf_id == 0) {  		p_err("prog FD %d doesn't have valid btf", tgt_fd);  		goto out;  	} +	btf = btf__load_from_kernel_by_id(info_linear->info.btf_id); +	if (libbpf_get_error(btf)) { +		p_err("failed to load btf for prog FD %d", tgt_fd); +		goto out; +	} +  	func_info = u64_to_ptr(info_linear->info.func_info);  	t = btf__type_by_id(btf, func_info[0].type_id);  	if (!t) { @@ -2027,6 +2037,7 @@ static char *profile_target_name(int tgt_fd)  	}  	name = strdup(btf__name_by_offset(btf, t->name_off));  out: +	btf__free(btf);  	free(info_linear);  	return name;  } @@ -2245,10 +2256,12 @@ static int do_help(int argc, char **argv)  		"                 cgroup/sendmsg6 | cgroup/recvmsg4 | cgroup/recvmsg6 |\n"  		"                 cgroup/getsockopt | cgroup/setsockopt | cgroup/sock_release |\n"  		"                 struct_ops | fentry | fexit | freplace | sk_lookup }\n" -		"       ATTACH_TYPE := { msg_verdict | stream_verdict | stream_parser |\n" -		"                        flow_dissector }\n" +		"       ATTACH_TYPE := { msg_verdict | skb_verdict | stream_verdict |\n" +		"                        stream_parser | flow_dissector }\n"  		"       METRIC := { cycles | instructions | l1d_loads | llc_misses | itlb_misses | dtlb_misses }\n" -		"       " HELP_SPEC_OPTIONS "\n" +		"       " HELP_SPEC_OPTIONS " |\n" +		"                    {-f|--bpffs} | {-m|--mapcompat} | {-n|--nomount} |\n" +		"                    {-L|--use-loader} }\n"  		"",  		bin_name, argv[-2]); diff --git a/tools/bpf/bpftool/struct_ops.c b/tools/bpf/bpftool/struct_ops.c index b58b91f62ffb..ab2d2290569a 100644 --- a/tools/bpf/bpftool/struct_ops.c +++ b/tools/bpf/bpftool/struct_ops.c @@ -572,8 +572,8 @@ static int do_help(int argc, char **argv)  		"       %1$s %2$s unregister STRUCT_OPS_MAP\n"  		"       %1$s %2$s help\n"  		"\n" -		"       OPTIONS := { {-j|--json} [{-p|--pretty}] }\n"  		"       STRUCT_OPS_MAP := [ id STRUCT_OPS_MAP_ID | name STRUCT_OPS_MAP_NAME ]\n" +		"       " HELP_SPEC_OPTIONS " }\n"  		"",  		bin_name, argv[-2]); | 
