Skip to content

Commit f412eed

Browse files
Jakub Kicinskiborkmann
authored andcommitted
tools: bpftool: add simple perf event output reader
Users of BPF sooner or later discover perf_event_output() helpers and BPF_MAP_TYPE_PERF_EVENT_ARRAY. Dumping this array type is not possible, however, we can add simple reading of perf events. Create a new event_pipe subcommand for maps, this sub command will only work with BPF_MAP_TYPE_PERF_EVENT_ARRAY maps. Parts of the code from samples/bpf/trace_output_user.c. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent e64d525 commit f412eed

File tree

8 files changed

+444
-19
lines changed

8 files changed

+444
-19
lines changed

tools/bpf/bpftool/Documentation/bpftool-map.rst

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ MAP COMMANDS
2222
=============
2323

2424
| **bpftool** **map { show | list }** [*MAP*]
25-
| **bpftool** **map dump** *MAP*
26-
| **bpftool** **map update** *MAP* **key** *DATA* **value** *VALUE* [*UPDATE_FLAGS*]
27-
| **bpftool** **map lookup** *MAP* **key** *DATA*
28-
| **bpftool** **map getnext** *MAP* [**key** *DATA*]
29-
| **bpftool** **map delete** *MAP* **key** *DATA*
30-
| **bpftool** **map pin** *MAP* *FILE*
25+
| **bpftool** **map dump** *MAP*
26+
| **bpftool** **map update** *MAP* **key** *DATA* **value** *VALUE* [*UPDATE_FLAGS*]
27+
| **bpftool** **map lookup** *MAP* **key** *DATA*
28+
| **bpftool** **map getnext** *MAP* [**key** *DATA*]
29+
| **bpftool** **map delete** *MAP* **key** *DATA*
30+
| **bpftool** **map pin** *MAP* *FILE*
31+
| **bpftool** **map event_pipe** *MAP* [**cpu** *N* **index** *M*]
3132
| **bpftool** **map help**
3233
|
3334
| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
@@ -76,6 +77,22 @@ DESCRIPTION
7677

7778
Note: *FILE* must be located in *bpffs* mount.
7879

80+
**bpftool** **map event_pipe** *MAP* [**cpu** *N* **index** *M*]
81+
Read events from a BPF_MAP_TYPE_PERF_EVENT_ARRAY map.
82+
83+
Install perf rings into a perf event array map and dump
84+
output of any bpf_perf_event_output() call in the kernel.
85+
By default read the number of CPUs on the system and
86+
install perf ring for each CPU in the corresponding index
87+
in the array.
88+
89+
If **cpu** and **index** are specified, install perf ring
90+
for given **cpu** at **index** in the array (single ring).
91+
92+
Note that installing a perf ring into an array will silently
93+
replace any existing ring. Any other application will stop
94+
receiving events if it installed its rings earlier.
95+
7996
**bpftool map help**
8097
Print short help message.
8198

tools/bpf/bpftool/Documentation/bpftool.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ SYNOPSIS
2323
2424
*MAP-COMMANDS* :=
2525
{ **show** | **list** | **dump** | **update** | **lookup** | **getnext** | **delete**
26-
| **pin** | **help** }
26+
| **pin** | **event_pipe** | **help** }
2727
2828
*PROG-COMMANDS* := { **show** | **list** | **dump jited** | **dump xlated** | **pin**
2929
| **load** | **help** }

tools/bpf/bpftool/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ CC = gcc
3939

4040
CFLAGS += -O2
4141
CFLAGS += -W -Wall -Wextra -Wno-unused-parameter -Wshadow -Wno-missing-field-initializers
42-
CFLAGS += -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ -I$(srctree)/tools/include/uapi -I$(srctree)/tools/include -I$(srctree)/tools/lib/bpf -I$(srctree)/kernel/bpf/
42+
CFLAGS += -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ \
43+
-I$(srctree)/kernel/bpf/ \
44+
-I$(srctree)/tools/include \
45+
-I$(srctree)/tools/include/uapi \
46+
-I$(srctree)/tools/lib/bpf \
47+
-I$(srctree)/tools/perf
4348
CFLAGS += -DBPFTOOL_VERSION='"$(BPFTOOL_VERSION)"'
4449
LIBS = -lelf -lbfd -lopcodes $(LIBBPF)
4550

tools/bpf/bpftool/bash-completion/bpftool

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# bpftool(8) bash completion -*- shell-script -*-
22
#
3-
# Copyright (C) 2017 Netronome Systems, Inc.
3+
# Copyright (C) 2017-2018 Netronome Systems, Inc.
44
#
55
# This software is dual licensed under the GNU General License
66
# Version 2, June 1991 as shown in the file COPYING in the top-level
@@ -79,6 +79,14 @@ _bpftool_get_map_ids()
7979
command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
8080
}
8181

82+
_bpftool_get_perf_map_ids()
83+
{
84+
COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
85+
command grep -C2 perf_event_array | \
86+
command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
87+
}
88+
89+
8290
_bpftool_get_prog_ids()
8391
{
8492
COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
@@ -359,10 +367,34 @@ _bpftool()
359367
fi
360368
return 0
361369
;;
370+
event_pipe)
371+
case $prev in
372+
$command)
373+
COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
374+
return 0
375+
;;
376+
id)
377+
_bpftool_get_perf_map_ids
378+
return 0
379+
;;
380+
cpu)
381+
return 0
382+
;;
383+
index)
384+
return 0
385+
;;
386+
*)
387+
_bpftool_once_attr 'cpu'
388+
_bpftool_once_attr 'index'
389+
return 0
390+
;;
391+
esac
392+
;;
362393
*)
363394
[[ $prev == $object ]] && \
364395
COMPREPLY=( $( compgen -W 'delete dump getnext help \
365-
lookup pin show list update' -- "$cur" ) )
396+
lookup pin event_pipe show list update' -- \
397+
"$cur" ) )
366398
;;
367399
esac
368400
;;

tools/bpf/bpftool/common.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,16 @@ char *get_fdinfo(int fd, const char *key)
331331
return NULL;
332332
}
333333

334+
void print_data_json(uint8_t *data, size_t len)
335+
{
336+
unsigned int i;
337+
338+
jsonw_start_array(json_wtr);
339+
for (i = 0; i < len; i++)
340+
jsonw_printf(json_wtr, "%d", data[i]);
341+
jsonw_end_array(json_wtr);
342+
}
343+
334344
void print_hex_data_json(uint8_t *data, size_t len)
335345
{
336346
unsigned int i;
@@ -421,6 +431,15 @@ void delete_pinned_obj_table(struct pinned_obj_table *tab)
421431
}
422432
}
423433

434+
unsigned int get_page_size(void)
435+
{
436+
static int result;
437+
438+
if (!result)
439+
result = getpagesize();
440+
return result;
441+
}
442+
424443
unsigned int get_possible_cpus(void)
425444
{
426445
static unsigned int result;

tools/bpf/bpftool/main.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,18 @@ int do_pin_fd(int fd, const char *name);
117117

118118
int do_prog(int argc, char **arg);
119119
int do_map(int argc, char **arg);
120+
int do_event_pipe(int argc, char **argv);
120121
int do_cgroup(int argc, char **arg);
121122

122123
int prog_parse_fd(int *argc, char ***argv);
124+
int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len);
123125

124126
void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
125127
const char *arch);
128+
void print_data_json(uint8_t *data, size_t len);
126129
void print_hex_data_json(uint8_t *data, size_t len);
127130

131+
unsigned int get_page_size(void);
128132
unsigned int get_possible_cpus(void);
129133
const char *ifindex_to_bfd_name_ns(__u32 ifindex, __u64 ns_dev, __u64 ns_ino);
130134

tools/bpf/bpftool/map.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ static int map_parse_fd(int *argc, char ***argv)
130130
return -1;
131131
}
132132

133-
static int
134-
map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len)
133+
int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len)
135134
{
136135
int err;
137136
int fd;
@@ -817,12 +816,13 @@ static int do_help(int argc, char **argv)
817816

818817
fprintf(stderr,
819818
"Usage: %s %s { show | list } [MAP]\n"
820-
" %s %s dump MAP\n"
821-
" %s %s update MAP key DATA value VALUE [UPDATE_FLAGS]\n"
822-
" %s %s lookup MAP key DATA\n"
823-
" %s %s getnext MAP [key DATA]\n"
824-
" %s %s delete MAP key DATA\n"
825-
" %s %s pin MAP FILE\n"
819+
" %s %s dump MAP\n"
820+
" %s %s update MAP key DATA value VALUE [UPDATE_FLAGS]\n"
821+
" %s %s lookup MAP key DATA\n"
822+
" %s %s getnext MAP [key DATA]\n"
823+
" %s %s delete MAP key DATA\n"
824+
" %s %s pin MAP FILE\n"
825+
" %s %s event_pipe MAP [cpu N index M]\n"
826826
" %s %s help\n"
827827
"\n"
828828
" MAP := { id MAP_ID | pinned FILE }\n"
@@ -834,7 +834,7 @@ static int do_help(int argc, char **argv)
834834
"",
835835
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
836836
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
837-
bin_name, argv[-2], bin_name, argv[-2]);
837+
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]);
838838

839839
return 0;
840840
}
@@ -849,6 +849,7 @@ static const struct cmd cmds[] = {
849849
{ "getnext", do_getnext },
850850
{ "delete", do_delete },
851851
{ "pin", do_pin },
852+
{ "event_pipe", do_event_pipe },
852853
{ 0 }
853854
};
854855

0 commit comments

Comments
 (0)