]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - tools/perf/util/bpf-loader.c
Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / tools / perf / util / bpf-loader.c
1 /*
2  * bpf-loader.c
3  *
4  * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
5  * Copyright (C) 2015 Huawei Inc.
6  */
7
8 #include <bpf/libbpf.h>
9 #include <linux/err.h>
10 #include "perf.h"
11 #include "debug.h"
12 #include "bpf-loader.h"
13 #include "probe-event.h"
14 #include "probe-finder.h" // for MAX_PROBES
15 #include "llvm-utils.h"
16
17 #define DEFINE_PRINT_FN(name, level) \
18 static int libbpf_##name(const char *fmt, ...)  \
19 {                                               \
20         va_list args;                           \
21         int ret;                                \
22                                                 \
23         va_start(args, fmt);                    \
24         ret = veprintf(level, verbose, pr_fmt(fmt), args);\
25         va_end(args);                           \
26         return ret;                             \
27 }
28
29 DEFINE_PRINT_FN(warning, 0)
30 DEFINE_PRINT_FN(info, 0)
31 DEFINE_PRINT_FN(debug, 1)
32
33 struct bpf_prog_priv {
34         struct perf_probe_event pev;
35 };
36
37 struct bpf_object *bpf__prepare_load(const char *filename, bool source)
38 {
39         struct bpf_object *obj;
40         static bool libbpf_initialized;
41
42         if (!libbpf_initialized) {
43                 libbpf_set_print(libbpf_warning,
44                                  libbpf_info,
45                                  libbpf_debug);
46                 libbpf_initialized = true;
47         }
48
49         if (source) {
50                 int err;
51                 void *obj_buf;
52                 size_t obj_buf_sz;
53
54                 err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz);
55                 if (err)
56                         return ERR_PTR(err);
57                 obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename);
58                 free(obj_buf);
59         } else
60                 obj = bpf_object__open(filename);
61
62         if (!obj) {
63                 pr_debug("bpf: failed to load %s\n", filename);
64                 return ERR_PTR(-EINVAL);
65         }
66
67         return obj;
68 }
69
70 void bpf__clear(void)
71 {
72         struct bpf_object *obj, *tmp;
73
74         bpf_object__for_each_safe(obj, tmp) {
75                 bpf__unprobe(obj);
76                 bpf_object__close(obj);
77         }
78 }
79
80 static void
81 bpf_prog_priv__clear(struct bpf_program *prog __maybe_unused,
82                      void *_priv)
83 {
84         struct bpf_prog_priv *priv = _priv;
85
86         cleanup_perf_probe_events(&priv->pev, 1);
87         free(priv);
88 }
89
90 static int
91 config_bpf_program(struct bpf_program *prog)
92 {
93         struct perf_probe_event *pev = NULL;
94         struct bpf_prog_priv *priv = NULL;
95         const char *config_str;
96         int err;
97
98         config_str = bpf_program__title(prog, false);
99         if (!config_str) {
100                 pr_debug("bpf: unable to get title for program\n");
101                 return -EINVAL;
102         }
103
104         priv = calloc(sizeof(*priv), 1);
105         if (!priv) {
106                 pr_debug("bpf: failed to alloc priv\n");
107                 return -ENOMEM;
108         }
109         pev = &priv->pev;
110
111         pr_debug("bpf: config program '%s'\n", config_str);
112         err = parse_perf_probe_command(config_str, pev);
113         if (err < 0) {
114                 pr_debug("bpf: '%s' is not a valid config string\n",
115                          config_str);
116                 err = -EINVAL;
117                 goto errout;
118         }
119
120         if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) {
121                 pr_debug("bpf: '%s': group for event is set and not '%s'.\n",
122                          config_str, PERF_BPF_PROBE_GROUP);
123                 err = -EINVAL;
124                 goto errout;
125         } else if (!pev->group)
126                 pev->group = strdup(PERF_BPF_PROBE_GROUP);
127
128         if (!pev->group) {
129                 pr_debug("bpf: strdup failed\n");
130                 err = -ENOMEM;
131                 goto errout;
132         }
133
134         if (!pev->event) {
135                 pr_debug("bpf: '%s': event name is missing\n",
136                          config_str);
137                 err = -EINVAL;
138                 goto errout;
139         }
140         pr_debug("bpf: config '%s' is ok\n", config_str);
141
142         err = bpf_program__set_private(prog, priv, bpf_prog_priv__clear);
143         if (err) {
144                 pr_debug("Failed to set priv for program '%s'\n", config_str);
145                 goto errout;
146         }
147
148         return 0;
149
150 errout:
151         if (pev)
152                 clear_perf_probe_event(pev);
153         free(priv);
154         return err;
155 }
156
157 static int bpf__prepare_probe(void)
158 {
159         static int err = 0;
160         static bool initialized = false;
161
162         /*
163          * Make err static, so if init failed the first, bpf__prepare_probe()
164          * fails each time without calling init_probe_symbol_maps multiple
165          * times.
166          */
167         if (initialized)
168                 return err;
169
170         initialized = true;
171         err = init_probe_symbol_maps(false);
172         if (err < 0)
173                 pr_debug("Failed to init_probe_symbol_maps\n");
174         probe_conf.max_probes = MAX_PROBES;
175         return err;
176 }
177
178 int bpf__probe(struct bpf_object *obj)
179 {
180         int err = 0;
181         struct bpf_program *prog;
182         struct bpf_prog_priv *priv;
183         struct perf_probe_event *pev;
184
185         err = bpf__prepare_probe();
186         if (err) {
187                 pr_debug("bpf__prepare_probe failed\n");
188                 return err;
189         }
190
191         bpf_object__for_each_program(prog, obj) {
192                 err = config_bpf_program(prog);
193                 if (err)
194                         goto out;
195
196                 err = bpf_program__get_private(prog, (void **)&priv);
197                 if (err || !priv)
198                         goto out;
199                 pev = &priv->pev;
200
201                 err = convert_perf_probe_events(pev, 1);
202                 if (err < 0) {
203                         pr_debug("bpf_probe: failed to convert perf probe events");
204                         goto out;
205                 }
206
207                 err = apply_perf_probe_events(pev, 1);
208                 if (err < 0) {
209                         pr_debug("bpf_probe: failed to apply perf probe events");
210                         goto out;
211                 }
212         }
213 out:
214         return err < 0 ? err : 0;
215 }
216
217 #define EVENTS_WRITE_BUFSIZE  4096
218 int bpf__unprobe(struct bpf_object *obj)
219 {
220         int err, ret = 0;
221         struct bpf_program *prog;
222         struct bpf_prog_priv *priv;
223
224         bpf_object__for_each_program(prog, obj) {
225                 int i;
226
227                 err = bpf_program__get_private(prog, (void **)&priv);
228                 if (err || !priv)
229                         continue;
230
231                 for (i = 0; i < priv->pev.ntevs; i++) {
232                         struct probe_trace_event *tev = &priv->pev.tevs[i];
233                         char name_buf[EVENTS_WRITE_BUFSIZE];
234                         struct strfilter *delfilter;
235
236                         snprintf(name_buf, EVENTS_WRITE_BUFSIZE,
237                                  "%s:%s", tev->group, tev->event);
238                         name_buf[EVENTS_WRITE_BUFSIZE - 1] = '\0';
239
240                         delfilter = strfilter__new(name_buf, NULL);
241                         if (!delfilter) {
242                                 pr_debug("Failed to create filter for unprobing\n");
243                                 ret = -ENOMEM;
244                                 continue;
245                         }
246
247                         err = del_perf_probe_events(delfilter);
248                         strfilter__delete(delfilter);
249                         if (err) {
250                                 pr_debug("Failed to delete %s\n", name_buf);
251                                 ret = err;
252                                 continue;
253                         }
254                 }
255         }
256         return ret;
257 }
258
259 int bpf__load(struct bpf_object *obj)
260 {
261         int err;
262
263         err = bpf_object__load(obj);
264         if (err) {
265                 pr_debug("bpf: load objects failed\n");
266                 return err;
267         }
268         return 0;
269 }
270
271 int bpf__foreach_tev(struct bpf_object *obj,
272                      bpf_prog_iter_callback_t func,
273                      void *arg)
274 {
275         struct bpf_program *prog;
276         int err;
277
278         bpf_object__for_each_program(prog, obj) {
279                 struct probe_trace_event *tev;
280                 struct perf_probe_event *pev;
281                 struct bpf_prog_priv *priv;
282                 int i, fd;
283
284                 err = bpf_program__get_private(prog,
285                                 (void **)&priv);
286                 if (err || !priv) {
287                         pr_debug("bpf: failed to get private field\n");
288                         return -EINVAL;
289                 }
290
291                 pev = &priv->pev;
292                 for (i = 0; i < pev->ntevs; i++) {
293                         tev = &pev->tevs[i];
294
295                         fd = bpf_program__fd(prog);
296                         if (fd < 0) {
297                                 pr_debug("bpf: failed to get file descriptor\n");
298                                 return fd;
299                         }
300
301                         err = (*func)(tev, fd, arg);
302                         if (err) {
303                                 pr_debug("bpf: call back failed, stop iterate\n");
304                                 return err;
305                         }
306                 }
307         }
308         return 0;
309 }
310
311 #define bpf__strerror_head(err, buf, size) \
312         char sbuf[STRERR_BUFSIZE], *emsg;\
313         if (!size)\
314                 return 0;\
315         if (err < 0)\
316                 err = -err;\
317         emsg = strerror_r(err, sbuf, sizeof(sbuf));\
318         switch (err) {\
319         default:\
320                 scnprintf(buf, size, "%s", emsg);\
321                 break;
322
323 #define bpf__strerror_entry(val, fmt...)\
324         case val: {\
325                 scnprintf(buf, size, fmt);\
326                 break;\
327         }
328
329 #define bpf__strerror_end(buf, size)\
330         }\
331         buf[size - 1] = '\0';
332
333 int bpf__strerror_probe(struct bpf_object *obj __maybe_unused,
334                         int err, char *buf, size_t size)
335 {
336         bpf__strerror_head(err, buf, size);
337         bpf__strerror_entry(EEXIST, "Probe point exist. Try use 'perf probe -d \"*\"'");
338         bpf__strerror_entry(EPERM, "You need to be root, and /proc/sys/kernel/kptr_restrict should be 0\n");
339         bpf__strerror_entry(ENOENT, "You need to check probing points in BPF file\n");
340         bpf__strerror_end(buf, size);
341         return 0;
342 }
343
344 int bpf__strerror_load(struct bpf_object *obj __maybe_unused,
345                        int err, char *buf, size_t size)
346 {
347         bpf__strerror_head(err, buf, size);
348         bpf__strerror_entry(EINVAL, "%s: Are you root and runing a CONFIG_BPF_SYSCALL kernel?",
349                             emsg)
350         bpf__strerror_end(buf, size);
351         return 0;
352 }