.. | .. |
---|
12 | 12 | #include <linux/err.h> |
---|
13 | 13 | #include <linux/kernel.h> |
---|
14 | 14 | #include <linux/string.h> |
---|
| 15 | +#include <linux/zalloc.h> |
---|
15 | 16 | #include <errno.h> |
---|
16 | | -#include "perf.h" |
---|
| 17 | +#include <stdlib.h> |
---|
17 | 18 | #include "debug.h" |
---|
| 19 | +#include "evlist.h" |
---|
18 | 20 | #include "bpf-loader.h" |
---|
19 | 21 | #include "bpf-prologue.h" |
---|
20 | 22 | #include "probe-event.h" |
---|
21 | 23 | #include "probe-finder.h" // for MAX_PROBES |
---|
22 | 24 | #include "parse-events.h" |
---|
23 | 25 | #include "strfilter.h" |
---|
| 26 | +#include "util.h" |
---|
24 | 27 | #include "llvm-utils.h" |
---|
25 | 28 | #include "c++/clang-c.h" |
---|
26 | 29 | |
---|
27 | | -#define DEFINE_PRINT_FN(name, level) \ |
---|
28 | | -static int libbpf_##name(const char *fmt, ...) \ |
---|
29 | | -{ \ |
---|
30 | | - va_list args; \ |
---|
31 | | - int ret; \ |
---|
32 | | - \ |
---|
33 | | - va_start(args, fmt); \ |
---|
34 | | - ret = veprintf(level, verbose, pr_fmt(fmt), args);\ |
---|
35 | | - va_end(args); \ |
---|
36 | | - return ret; \ |
---|
37 | | -} |
---|
| 30 | +#include <internal/xyarray.h> |
---|
38 | 31 | |
---|
39 | | -DEFINE_PRINT_FN(warning, 1) |
---|
40 | | -DEFINE_PRINT_FN(info, 1) |
---|
41 | | -DEFINE_PRINT_FN(debug, 1) |
---|
| 32 | +static int libbpf_perf_print(enum libbpf_print_level level __attribute__((unused)), |
---|
| 33 | + const char *fmt, va_list args) |
---|
| 34 | +{ |
---|
| 35 | + return veprintf(1, verbose, pr_fmt(fmt), args); |
---|
| 36 | +} |
---|
42 | 37 | |
---|
43 | 38 | struct bpf_prog_priv { |
---|
44 | 39 | bool is_tp; |
---|
.. | .. |
---|
59 | 54 | struct bpf_object *obj; |
---|
60 | 55 | |
---|
61 | 56 | if (!libbpf_initialized) { |
---|
62 | | - libbpf_set_print(libbpf_warning, |
---|
63 | | - libbpf_info, |
---|
64 | | - libbpf_debug); |
---|
| 57 | + libbpf_set_print(libbpf_perf_print); |
---|
65 | 58 | libbpf_initialized = true; |
---|
66 | 59 | } |
---|
67 | 60 | |
---|
.. | .. |
---|
79 | 72 | struct bpf_object *obj; |
---|
80 | 73 | |
---|
81 | 74 | if (!libbpf_initialized) { |
---|
82 | | - libbpf_set_print(libbpf_warning, |
---|
83 | | - libbpf_info, |
---|
84 | | - libbpf_debug); |
---|
| 75 | + libbpf_set_print(libbpf_perf_print); |
---|
85 | 76 | libbpf_initialized = true; |
---|
86 | 77 | } |
---|
87 | 78 | |
---|
.. | .. |
---|
99 | 90 | if (err) |
---|
100 | 91 | return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE); |
---|
101 | 92 | } else |
---|
102 | | - pr_debug("bpf: successfull builtin compilation\n"); |
---|
| 93 | + pr_debug("bpf: successful builtin compilation\n"); |
---|
103 | 94 | obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename); |
---|
104 | 95 | |
---|
105 | 96 | if (!IS_ERR_OR_NULL(obj) && llvm_param.dump_obj) |
---|
.. | .. |
---|
337 | 328 | probe_conf.no_inlines = false; |
---|
338 | 329 | probe_conf.force_add = false; |
---|
339 | 330 | |
---|
340 | | - config_str = bpf_program__title(prog, false); |
---|
341 | | - if (IS_ERR(config_str)) { |
---|
342 | | - pr_debug("bpf: unable to get title for program\n"); |
---|
343 | | - return PTR_ERR(config_str); |
---|
344 | | - } |
---|
345 | | - |
---|
346 | 331 | priv = calloc(sizeof(*priv), 1); |
---|
347 | 332 | if (!priv) { |
---|
348 | 333 | pr_debug("bpf: failed to alloc priv\n"); |
---|
.. | .. |
---|
350 | 335 | } |
---|
351 | 336 | pev = &priv->pev; |
---|
352 | 337 | |
---|
| 338 | + config_str = bpf_program__section_name(prog); |
---|
353 | 339 | pr_debug("bpf: config program '%s'\n", config_str); |
---|
354 | 340 | err = parse_prog_config(config_str, &main_str, &is_tp, pev); |
---|
355 | 341 | if (err) |
---|
.. | .. |
---|
463 | 449 | if (err) { |
---|
464 | 450 | const char *title; |
---|
465 | 451 | |
---|
466 | | - title = bpf_program__title(prog, false); |
---|
467 | | - if (!title) |
---|
468 | | - title = "[unknown]"; |
---|
469 | | - |
---|
| 452 | + title = bpf_program__section_name(prog); |
---|
470 | 453 | pr_debug("Failed to generate prologue for program %s\n", |
---|
471 | 454 | title); |
---|
472 | 455 | return err; |
---|
.. | .. |
---|
775 | 758 | |
---|
776 | 759 | if (priv->is_tp) { |
---|
777 | 760 | fd = bpf_program__fd(prog); |
---|
778 | | - err = (*func)(priv->sys_name, priv->evt_name, fd, arg); |
---|
| 761 | + err = (*func)(priv->sys_name, priv->evt_name, fd, obj, arg); |
---|
779 | 762 | if (err) { |
---|
780 | 763 | pr_debug("bpf: tracepoint call back failed, stop iterate\n"); |
---|
781 | 764 | return err; |
---|
.. | .. |
---|
800 | 783 | return fd; |
---|
801 | 784 | } |
---|
802 | 785 | |
---|
803 | | - err = (*func)(tev->group, tev->event, fd, arg); |
---|
| 786 | + err = (*func)(tev->group, tev->event, fd, obj, arg); |
---|
804 | 787 | if (err) { |
---|
805 | 788 | pr_debug("bpf: call back failed, stop iterate\n"); |
---|
806 | 789 | return err; |
---|
.. | .. |
---|
829 | 812 | } k; |
---|
830 | 813 | union { |
---|
831 | 814 | u64 value; |
---|
832 | | - struct perf_evsel *evsel; |
---|
| 815 | + struct evsel *evsel; |
---|
833 | 816 | } v; |
---|
834 | 817 | }; |
---|
835 | 818 | |
---|
.. | .. |
---|
841 | 824 | bpf_map_op__delete(struct bpf_map_op *op) |
---|
842 | 825 | { |
---|
843 | 826 | if (!list_empty(&op->list)) |
---|
844 | | - list_del(&op->list); |
---|
| 827 | + list_del_init(&op->list); |
---|
845 | 828 | if (op->key_type == BPF_MAP_KEY_RANGES) |
---|
846 | 829 | parse_events__clear_array(&op->k.array); |
---|
847 | 830 | free(op); |
---|
.. | .. |
---|
1055 | 1038 | static int |
---|
1056 | 1039 | bpf_map__config_value(struct bpf_map *map, |
---|
1057 | 1040 | struct parse_events_term *term, |
---|
1058 | | - struct perf_evlist *evlist __maybe_unused) |
---|
| 1041 | + struct evlist *evlist __maybe_unused) |
---|
1059 | 1042 | { |
---|
1060 | 1043 | if (!term->err_val) { |
---|
1061 | 1044 | pr_debug("Config value not set\n"); |
---|
.. | .. |
---|
1073 | 1056 | static int |
---|
1074 | 1057 | __bpf_map__config_event(struct bpf_map *map, |
---|
1075 | 1058 | struct parse_events_term *term, |
---|
1076 | | - struct perf_evlist *evlist) |
---|
| 1059 | + struct evlist *evlist) |
---|
1077 | 1060 | { |
---|
1078 | | - struct perf_evsel *evsel; |
---|
| 1061 | + struct evsel *evsel; |
---|
1079 | 1062 | const struct bpf_map_def *def; |
---|
1080 | 1063 | struct bpf_map_op *op; |
---|
1081 | 1064 | const char *map_name = bpf_map__name(map); |
---|
.. | .. |
---|
1115 | 1098 | static int |
---|
1116 | 1099 | bpf_map__config_event(struct bpf_map *map, |
---|
1117 | 1100 | struct parse_events_term *term, |
---|
1118 | | - struct perf_evlist *evlist) |
---|
| 1101 | + struct evlist *evlist) |
---|
1119 | 1102 | { |
---|
1120 | 1103 | if (!term->err_val) { |
---|
1121 | 1104 | pr_debug("Config value not set\n"); |
---|
.. | .. |
---|
1133 | 1116 | struct bpf_obj_config__map_func { |
---|
1134 | 1117 | const char *config_opt; |
---|
1135 | 1118 | int (*config_func)(struct bpf_map *, struct parse_events_term *, |
---|
1136 | | - struct perf_evlist *); |
---|
| 1119 | + struct evlist *); |
---|
1137 | 1120 | }; |
---|
1138 | 1121 | |
---|
1139 | 1122 | struct bpf_obj_config__map_func bpf_obj_config__map_funcs[] = { |
---|
.. | .. |
---|
1181 | 1164 | static int |
---|
1182 | 1165 | bpf__obj_config_map(struct bpf_object *obj, |
---|
1183 | 1166 | struct parse_events_term *term, |
---|
1184 | | - struct perf_evlist *evlist, |
---|
| 1167 | + struct evlist *evlist, |
---|
1185 | 1168 | int *key_scan_pos) |
---|
1186 | 1169 | { |
---|
1187 | 1170 | /* key is "map:<mapname>.<config opt>" */ |
---|
.. | .. |
---|
1232 | 1215 | pr_debug("ERROR: Invalid map config option '%s'\n", map_opt); |
---|
1233 | 1216 | err = -BPF_LOADER_ERRNO__OBJCONF_MAP_OPT; |
---|
1234 | 1217 | out: |
---|
1235 | | - free(map_name); |
---|
1236 | 1218 | if (!err) |
---|
1237 | | - key_scan_pos += strlen(map_opt); |
---|
| 1219 | + *key_scan_pos += strlen(map_opt); |
---|
| 1220 | + |
---|
| 1221 | + free(map_name); |
---|
1238 | 1222 | return err; |
---|
1239 | 1223 | } |
---|
1240 | 1224 | |
---|
1241 | 1225 | int bpf__config_obj(struct bpf_object *obj, |
---|
1242 | 1226 | struct parse_events_term *term, |
---|
1243 | | - struct perf_evlist *evlist, |
---|
| 1227 | + struct evlist *evlist, |
---|
1244 | 1228 | int *error_pos) |
---|
1245 | 1229 | { |
---|
1246 | 1230 | int key_scan_pos = 0; |
---|
.. | .. |
---|
1413 | 1397 | |
---|
1414 | 1398 | static int |
---|
1415 | 1399 | apply_config_evsel_for_key(const char *name, int map_fd, void *pkey, |
---|
1416 | | - struct perf_evsel *evsel) |
---|
| 1400 | + struct evsel *evsel) |
---|
1417 | 1401 | { |
---|
1418 | | - struct xyarray *xy = evsel->fd; |
---|
| 1402 | + struct xyarray *xy = evsel->core.fd; |
---|
1419 | 1403 | struct perf_event_attr *attr; |
---|
1420 | 1404 | unsigned int key, events; |
---|
1421 | 1405 | bool check_pass = false; |
---|
.. | .. |
---|
1433 | 1417 | return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTDIM; |
---|
1434 | 1418 | } |
---|
1435 | 1419 | |
---|
1436 | | - attr = &evsel->attr; |
---|
| 1420 | + attr = &evsel->core.attr; |
---|
1437 | 1421 | if (attr->inherit) { |
---|
1438 | 1422 | pr_debug("ERROR: Can't put inherit event into map %s\n", name); |
---|
1439 | 1423 | return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTINH; |
---|
1440 | 1424 | } |
---|
1441 | 1425 | |
---|
1442 | | - if (perf_evsel__is_bpf_output(evsel)) |
---|
| 1426 | + if (evsel__is_bpf_output(evsel)) |
---|
1443 | 1427 | check_pass = true; |
---|
1444 | 1428 | if (attr->type == PERF_TYPE_RAW) |
---|
1445 | 1429 | check_pass = true; |
---|
.. | .. |
---|
1503 | 1487 | struct bpf_map *map; |
---|
1504 | 1488 | int err; |
---|
1505 | 1489 | |
---|
1506 | | - bpf_map__for_each(map, obj) { |
---|
| 1490 | + bpf_object__for_each_map(map, obj) { |
---|
1507 | 1491 | err = apply_obj_config_map(map); |
---|
1508 | 1492 | if (err) |
---|
1509 | 1493 | return err; |
---|
.. | .. |
---|
1527 | 1511 | |
---|
1528 | 1512 | #define bpf__for_each_map(pos, obj, objtmp) \ |
---|
1529 | 1513 | bpf_object__for_each_safe(obj, objtmp) \ |
---|
1530 | | - bpf_map__for_each(pos, obj) |
---|
| 1514 | + bpf_object__for_each_map(pos, obj) |
---|
1531 | 1515 | |
---|
1532 | 1516 | #define bpf__for_each_map_named(pos, obj, objtmp, name) \ |
---|
1533 | 1517 | bpf__for_each_map(pos, obj, objtmp) \ |
---|
.. | .. |
---|
1535 | 1519 | (strcmp(name, \ |
---|
1536 | 1520 | bpf_map__name(pos)) == 0)) |
---|
1537 | 1521 | |
---|
1538 | | -struct perf_evsel *bpf__setup_output_event(struct perf_evlist *evlist, const char *name) |
---|
| 1522 | +struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name) |
---|
1539 | 1523 | { |
---|
1540 | 1524 | struct bpf_map_priv *tmpl_priv = NULL; |
---|
1541 | 1525 | struct bpf_object *obj, *tmp; |
---|
1542 | | - struct perf_evsel *evsel = NULL; |
---|
| 1526 | + struct evsel *evsel = NULL; |
---|
1543 | 1527 | struct bpf_map *map; |
---|
1544 | 1528 | int err; |
---|
1545 | 1529 | bool need_init = false; |
---|
.. | .. |
---|
1577 | 1561 | return ERR_PTR(-err); |
---|
1578 | 1562 | } |
---|
1579 | 1563 | |
---|
1580 | | - evsel = perf_evlist__last(evlist); |
---|
| 1564 | + evsel = evlist__last(evlist); |
---|
1581 | 1565 | } |
---|
1582 | 1566 | |
---|
1583 | 1567 | bpf__for_each_map_named(map, obj, tmp, name) { |
---|
.. | .. |
---|
1603 | 1587 | |
---|
1604 | 1588 | op = bpf_map__add_newop(map, NULL); |
---|
1605 | 1589 | if (IS_ERR(op)) |
---|
1606 | | - return ERR_PTR(PTR_ERR(op)); |
---|
| 1590 | + return ERR_CAST(op); |
---|
1607 | 1591 | op->op_type = BPF_MAP_OP_SET_EVSEL; |
---|
1608 | 1592 | op->v.evsel = evsel; |
---|
1609 | 1593 | } |
---|
.. | .. |
---|
1612 | 1596 | return evsel; |
---|
1613 | 1597 | } |
---|
1614 | 1598 | |
---|
1615 | | -int bpf__setup_stdout(struct perf_evlist *evlist) |
---|
| 1599 | +int bpf__setup_stdout(struct evlist *evlist) |
---|
1616 | 1600 | { |
---|
1617 | | - struct perf_evsel *evsel = bpf__setup_output_event(evlist, "__bpf_stdout__"); |
---|
1618 | | - return IS_ERR(evsel) ? PTR_ERR(evsel) : 0; |
---|
| 1601 | + struct evsel *evsel = bpf__setup_output_event(evlist, "__bpf_stdout__"); |
---|
| 1602 | + return PTR_ERR_OR_ZERO(evsel); |
---|
1619 | 1603 | } |
---|
1620 | 1604 | |
---|
1621 | 1605 | #define ERRNO_OFFSET(e) ((e) - __BPF_LOADER_ERRNO__START) |
---|
.. | .. |
---|
1768 | 1752 | |
---|
1769 | 1753 | int bpf__strerror_config_obj(struct bpf_object *obj __maybe_unused, |
---|
1770 | 1754 | struct parse_events_term *term __maybe_unused, |
---|
1771 | | - struct perf_evlist *evlist __maybe_unused, |
---|
| 1755 | + struct evlist *evlist __maybe_unused, |
---|
1772 | 1756 | int *error_pos __maybe_unused, int err, |
---|
1773 | 1757 | char *buf, size_t size) |
---|
1774 | 1758 | { |
---|
.. | .. |
---|
1792 | 1776 | return 0; |
---|
1793 | 1777 | } |
---|
1794 | 1778 | |
---|
1795 | | -int bpf__strerror_setup_output_event(struct perf_evlist *evlist __maybe_unused, |
---|
| 1779 | +int bpf__strerror_setup_output_event(struct evlist *evlist __maybe_unused, |
---|
1796 | 1780 | int err, char *buf, size_t size) |
---|
1797 | 1781 | { |
---|
1798 | 1782 | bpf__strerror_head(err, buf, size); |
---|