Skip to content

Commit d002aab

Browse files
captain5050namhyung
authored andcommitted
perf tp_pmu: Factor existing tracepoint logic to new file
Start the creation of a tracepoint PMU abstraction. Tracepoint events don't follow the regular sysfs perf conventions. Eventually the new PMU abstraction will bridge the gap so tracepoint events look more like regular perf ones. Signed-off-by: Ian Rogers <[email protected]> Tested-by: Arnaldo Carvalho de Melo <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Namhyung Kim <[email protected]>
1 parent 6e9fa41 commit d002aab

File tree

5 files changed

+170
-106
lines changed

5 files changed

+170
-106
lines changed

tools/perf/util/Build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ perf-util-y += pmu-bison.o
8888
perf-util-y += drm_pmu.o
8989
perf-util-y += hwmon_pmu.o
9090
perf-util-y += tool_pmu.o
91+
perf-util-y += tp_pmu.o
9192
perf-util-y += svghelper.o
9293
perf-util-y += trace-event-info.o
9394
perf-util-y += trace-event-scripting.o

tools/perf/util/evsel.c

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include "drm_pmu.h"
6161
#include "hwmon_pmu.h"
6262
#include "tool_pmu.h"
63+
#include "tp_pmu.h"
6364
#include "rlimit.h"
6465
#include "../perf-sys.h"
6566
#include "util/parse-branch-options.h"
@@ -572,24 +573,6 @@ struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig)
572573
return NULL;
573574
}
574575

575-
static int trace_event__id(const char *sys, const char *name)
576-
{
577-
char *tp_dir = get_events_file(sys);
578-
char path[PATH_MAX];
579-
int id, err;
580-
581-
if (!tp_dir)
582-
return -1;
583-
584-
scnprintf(path, PATH_MAX, "%s/%s/id", tp_dir, name);
585-
put_events_file(tp_dir);
586-
err = filename__read_int(path, &id);
587-
if (err)
588-
return err;
589-
590-
return id;
591-
}
592-
593576
/*
594577
* Returns pointer with encoded error via <linux/err.h> interface.
595578
*/
@@ -623,7 +606,7 @@ struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx, bool
623606
event_attr_init(&attr);
624607

625608
if (format) {
626-
id = trace_event__id(sys, name);
609+
id = tp_pmu__id(sys, name);
627610
if (id < 0) {
628611
err = id;
629612
goto out_free;

tools/perf/util/parse-events.c

Lines changed: 60 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@
1717
#include "string2.h"
1818
#include "strbuf.h"
1919
#include "debug.h"
20-
#include <api/fs/tracing_path.h>
21-
#include <api/io_dir.h>
2220
#include <perf/cpumap.h>
2321
#include <util/parse-events-bison.h>
2422
#include <util/parse-events-flex.h>
2523
#include "pmu.h"
2624
#include "pmus.h"
25+
#include "tp_pmu.h"
2726
#include "asm/bug.h"
2827
#include "ui/ui.h"
2928
#include "util/parse-branch-options.h"
@@ -33,6 +32,7 @@
3332
#include "util/stat.h"
3433
#include "util/util.h"
3534
#include "tracepoint.h"
35+
#include <api/fs/tracing_path.h>
3636

3737
#define MAX_NAME_LEN 100
3838

@@ -599,105 +599,82 @@ static int add_tracepoint(struct parse_events_state *parse_state,
599599
return 0;
600600
}
601601

602-
static int add_tracepoint_multi_event(struct parse_events_state *parse_state,
603-
struct list_head *list,
604-
const char *sys_name, const char *evt_name,
605-
struct parse_events_error *err,
606-
struct parse_events_terms *head_config, YYLTYPE *loc)
607-
{
608-
char *evt_path;
609-
struct io_dirent64 *evt_ent;
610-
struct io_dir evt_dir;
611-
int ret = 0, found = 0;
612-
613-
evt_path = get_events_file(sys_name);
614-
if (!evt_path) {
615-
tracepoint_error(err, errno, sys_name, evt_name, loc->first_column);
616-
return -1;
617-
}
618-
io_dir__init(&evt_dir, open(evt_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY));
619-
if (evt_dir.dirfd < 0) {
620-
put_events_file(evt_path);
621-
tracepoint_error(err, errno, sys_name, evt_name, loc->first_column);
622-
return -1;
623-
}
602+
struct add_tracepoint_multi_args {
603+
struct parse_events_state *parse_state;
604+
struct list_head *list;
605+
const char *sys_glob;
606+
const char *evt_glob;
607+
struct parse_events_error *err;
608+
struct parse_events_terms *head_config;
609+
YYLTYPE *loc;
610+
int found;
611+
};
624612

625-
while (!ret && (evt_ent = io_dir__readdir(&evt_dir))) {
626-
if (!strcmp(evt_ent->d_name, ".")
627-
|| !strcmp(evt_ent->d_name, "..")
628-
|| !strcmp(evt_ent->d_name, "enable")
629-
|| !strcmp(evt_ent->d_name, "filter"))
630-
continue;
613+
static int add_tracepoint_multi_event_cb(void *state, const char *sys_name, const char *evt_name)
614+
{
615+
struct add_tracepoint_multi_args *args = state;
616+
int ret;
631617

632-
if (!strglobmatch(evt_ent->d_name, evt_name))
633-
continue;
618+
if (!strglobmatch(evt_name, args->evt_glob))
619+
return 0;
634620

635-
found++;
621+
args->found++;
622+
ret = add_tracepoint(args->parse_state, args->list, sys_name, evt_name,
623+
args->err, args->head_config, args->loc);
636624

637-
ret = add_tracepoint(parse_state, list, sys_name, evt_ent->d_name,
638-
err, head_config, loc);
639-
}
625+
return ret;
626+
}
640627

641-
if (!found) {
642-
tracepoint_error(err, ENOENT, sys_name, evt_name, loc->first_column);
643-
ret = -1;
628+
static int add_tracepoint_multi_event(struct add_tracepoint_multi_args *args, const char *sys_name)
629+
{
630+
if (strpbrk(args->evt_glob, "*?") == NULL) {
631+
/* Not a glob. */
632+
args->found++;
633+
return add_tracepoint(args->parse_state, args->list, sys_name, args->evt_glob,
634+
args->err, args->head_config, args->loc);
644635
}
645636

646-
put_events_file(evt_path);
647-
close(evt_dir.dirfd);
648-
return ret;
637+
return tp_pmu__for_each_tp_event(sys_name, args, add_tracepoint_multi_event_cb);
649638
}
650639

651-
static int add_tracepoint_event(struct parse_events_state *parse_state,
652-
struct list_head *list,
653-
const char *sys_name, const char *evt_name,
654-
struct parse_events_error *err,
655-
struct parse_events_terms *head_config, YYLTYPE *loc)
640+
static int add_tracepoint_multi_sys_cb(void *state, const char *sys_name)
656641
{
657-
return strpbrk(evt_name, "*?") ?
658-
add_tracepoint_multi_event(parse_state, list, sys_name, evt_name,
659-
err, head_config, loc) :
660-
add_tracepoint(parse_state, list, sys_name, evt_name,
661-
err, head_config, loc);
642+
struct add_tracepoint_multi_args *args = state;
643+
644+
if (!strglobmatch(sys_name, args->sys_glob))
645+
return 0;
646+
647+
return add_tracepoint_multi_event(args, sys_name);
662648
}
663649

664650
static int add_tracepoint_multi_sys(struct parse_events_state *parse_state,
665651
struct list_head *list,
666-
const char *sys_name, const char *evt_name,
652+
const char *sys_glob, const char *evt_glob,
667653
struct parse_events_error *err,
668654
struct parse_events_terms *head_config, YYLTYPE *loc)
669655
{
670-
struct io_dirent64 *events_ent;
671-
struct io_dir events_dir;
672-
int ret = 0;
673-
char *events_dir_path = get_tracing_file("events");
656+
struct add_tracepoint_multi_args args = {
657+
.parse_state = parse_state,
658+
.list = list,
659+
.sys_glob = sys_glob,
660+
.evt_glob = evt_glob,
661+
.err = err,
662+
.head_config = head_config,
663+
.loc = loc,
664+
.found = 0,
665+
};
666+
int ret;
674667

675-
if (!events_dir_path) {
676-
tracepoint_error(err, errno, sys_name, evt_name, loc->first_column);
677-
return -1;
668+
if (strpbrk(sys_glob, "*?") == NULL) {
669+
/* Not a glob. */
670+
ret = add_tracepoint_multi_event(&args, sys_glob);
671+
} else {
672+
ret = tp_pmu__for_each_tp_sys(&args, add_tracepoint_multi_sys_cb);
678673
}
679-
io_dir__init(&events_dir, open(events_dir_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY));
680-
put_events_file(events_dir_path);
681-
if (events_dir.dirfd < 0) {
682-
tracepoint_error(err, errno, sys_name, evt_name, loc->first_column);
683-
return -1;
674+
if (args.found == 0) {
675+
tracepoint_error(err, ENOENT, sys_glob, evt_glob, loc->first_column);
676+
return -ENOENT;
684677
}
685-
686-
while (!ret && (events_ent = io_dir__readdir(&events_dir))) {
687-
if (!strcmp(events_ent->d_name, ".")
688-
|| !strcmp(events_ent->d_name, "..")
689-
|| !strcmp(events_ent->d_name, "enable")
690-
|| !strcmp(events_ent->d_name, "header_event")
691-
|| !strcmp(events_ent->d_name, "header_page"))
692-
continue;
693-
694-
if (!strglobmatch(events_ent->d_name, sys_name))
695-
continue;
696-
697-
ret = add_tracepoint_event(parse_state, list, events_ent->d_name,
698-
evt_name, err, head_config, loc);
699-
}
700-
close(events_dir.dirfd);
701678
return ret;
702679
}
703680

@@ -1406,12 +1383,8 @@ int parse_events_add_tracepoint(struct parse_events_state *parse_state,
14061383
return -EINVAL;
14071384
}
14081385

1409-
if (strpbrk(sys, "*?"))
1410-
return add_tracepoint_multi_sys(parse_state, list, sys, event,
1411-
err, head_config, loc);
1412-
else
1413-
return add_tracepoint_event(parse_state, list, sys, event,
1414-
err, head_config, loc);
1386+
return add_tracepoint_multi_sys(parse_state, list, sys, event,
1387+
err, head_config, loc);
14151388
}
14161389

14171390
static int __parse_events_add_numeric(struct parse_events_state *parse_state,

tools/perf/util/tp_pmu.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2+
#include "tp_pmu.h"
3+
#include <api/fs/fs.h>
4+
#include <api/fs/tracing_path.h>
5+
#include <api/io_dir.h>
6+
#include <linux/kernel.h>
7+
#include <errno.h>
8+
#include <string.h>
9+
10+
int tp_pmu__id(const char *sys, const char *name)
11+
{
12+
char *tp_dir = get_events_file(sys);
13+
char path[PATH_MAX];
14+
int id, err;
15+
16+
if (!tp_dir)
17+
return -1;
18+
19+
scnprintf(path, PATH_MAX, "%s/%s/id", tp_dir, name);
20+
put_events_file(tp_dir);
21+
err = filename__read_int(path, &id);
22+
if (err)
23+
return err;
24+
25+
return id;
26+
}
27+
28+
29+
int tp_pmu__for_each_tp_event(const char *sys, void *state, tp_event_callback cb)
30+
{
31+
char *evt_path;
32+
struct io_dirent64 *evt_ent;
33+
struct io_dir evt_dir;
34+
int ret = 0;
35+
36+
evt_path = get_events_file(sys);
37+
if (!evt_path)
38+
return -errno;
39+
40+
io_dir__init(&evt_dir, open(evt_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY));
41+
if (evt_dir.dirfd < 0) {
42+
ret = -errno;
43+
put_events_file(evt_path);
44+
return ret;
45+
}
46+
put_events_file(evt_path);
47+
48+
while (!ret && (evt_ent = io_dir__readdir(&evt_dir))) {
49+
if (!strcmp(evt_ent->d_name, ".")
50+
|| !strcmp(evt_ent->d_name, "..")
51+
|| !strcmp(evt_ent->d_name, "enable")
52+
|| !strcmp(evt_ent->d_name, "filter"))
53+
continue;
54+
55+
ret = cb(state, sys, evt_ent->d_name);
56+
if (ret)
57+
break;
58+
}
59+
close(evt_dir.dirfd);
60+
return ret;
61+
}
62+
63+
int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb)
64+
{
65+
struct io_dirent64 *events_ent;
66+
struct io_dir events_dir;
67+
int ret = 0;
68+
char *events_dir_path = get_tracing_file("events");
69+
70+
if (!events_dir_path)
71+
return -errno;
72+
73+
io_dir__init(&events_dir, open(events_dir_path, O_CLOEXEC | O_DIRECTORY | O_RDONLY));
74+
if (events_dir.dirfd < 0) {
75+
ret = -errno;
76+
put_events_file(events_dir_path);
77+
return ret;
78+
}
79+
put_events_file(events_dir_path);
80+
81+
while (!ret && (events_ent = io_dir__readdir(&events_dir))) {
82+
if (!strcmp(events_ent->d_name, ".") ||
83+
!strcmp(events_ent->d_name, "..") ||
84+
!strcmp(events_ent->d_name, "enable") ||
85+
!strcmp(events_ent->d_name, "header_event") ||
86+
!strcmp(events_ent->d_name, "header_page"))
87+
continue;
88+
89+
ret = cb(state, events_ent->d_name);
90+
if (ret)
91+
break;
92+
}
93+
close(events_dir.dirfd);
94+
return ret;
95+
}

tools/perf/util/tp_pmu.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
2+
#ifndef __TP_PMU_H
3+
#define __TP_PMU_H
4+
5+
typedef int (*tp_sys_callback)(void *state, const char *sys_name);
6+
typedef int (*tp_event_callback)(void *state, const char *sys_name, const char *evt_name);
7+
8+
int tp_pmu__id(const char *sys, const char *name);
9+
int tp_pmu__for_each_tp_event(const char *sys, void *state, tp_event_callback cb);
10+
int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb);
11+
12+
#endif /* __TP_PMU_H */

0 commit comments

Comments
 (0)