Skip to content

Commit 4446243

Browse files
Jin Yaoacmel
authored andcommitted
perf pmu: Save detected hybrid pmus to a global pmu list
We identify the cpu_core pmu and cpu_atom pmu by explicitly checking following files: For cpu_core, checks: "/sys/bus/event_source/devices/cpu_core/cpus" For cpu_atom, checks: "/sys/bus/event_source/devices/cpu_atom/cpus" If the 'cpus' file exists and it has data, the pmu exists. But in order not to hardcode the "cpu_core" and "cpu_atom", and make the code in a generic way. So if the path "/sys/bus/event_source/devices/cpu_xxx/cpus" exists, the hybrid pmu exists. All the detected hybrid pmus are linked to a global list 'perf_pmu__hybrid_pmus' and then next we just need to iterate the list to get all hybrid pmu by using perf_pmu__for_each_hybrid_pmu. Signed-off-by: Jin Yao <[email protected]> Reviewed-by: Jiri Olsa <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Kan Liang <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 32705de commit 4446243

File tree

5 files changed

+80
-1
lines changed

5 files changed

+80
-1
lines changed

tools/perf/util/Build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ perf-y += parse-events-bison.o
6969
perf-y += pmu.o
7070
perf-y += pmu-flex.o
7171
perf-y += pmu-bison.o
72+
perf-y += pmu-hybrid.o
7273
perf-y += trace-event-read.o
7374
perf-y += trace-event-info.o
7475
perf-y += trace-event-scripting.o

tools/perf/util/pmu-hybrid.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <linux/list.h>
3+
#include <linux/compiler.h>
4+
#include <linux/string.h>
5+
#include <linux/zalloc.h>
6+
#include <sys/types.h>
7+
#include <errno.h>
8+
#include <fcntl.h>
9+
#include <sys/stat.h>
10+
#include <unistd.h>
11+
#include <stdio.h>
12+
#include <stdbool.h>
13+
#include <stdarg.h>
14+
#include <locale.h>
15+
#include <api/fs/fs.h>
16+
#include "fncache.h"
17+
#include "pmu-hybrid.h"
18+
19+
LIST_HEAD(perf_pmu__hybrid_pmus);
20+
21+
bool perf_pmu__hybrid_mounted(const char *name)
22+
{
23+
char path[PATH_MAX];
24+
const char *sysfs;
25+
FILE *file;
26+
int n, cpu;
27+
28+
if (strncmp(name, "cpu_", 4))
29+
return false;
30+
31+
sysfs = sysfs__mountpoint();
32+
if (!sysfs)
33+
return false;
34+
35+
snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, name);
36+
if (!file_available(path))
37+
return false;
38+
39+
file = fopen(path, "r");
40+
if (!file)
41+
return false;
42+
43+
n = fscanf(file, "%u", &cpu);
44+
fclose(file);
45+
if (n <= 0)
46+
return false;
47+
48+
return true;
49+
}

tools/perf/util/pmu-hybrid.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef __PMU_HYBRID_H
3+
#define __PMU_HYBRID_H
4+
5+
#include <linux/perf_event.h>
6+
#include <linux/compiler.h>
7+
#include <linux/list.h>
8+
#include <stdbool.h>
9+
#include "pmu.h"
10+
11+
extern struct list_head perf_pmu__hybrid_pmus;
12+
13+
#define perf_pmu__for_each_hybrid_pmu(pmu) \
14+
list_for_each_entry(pmu, &perf_pmu__hybrid_pmus, hybrid_list)
15+
16+
bool perf_pmu__hybrid_mounted(const char *name);
17+
18+
#endif /* __PMU_HYBRID_H */

tools/perf/util/pmu.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "string2.h"
2626
#include "strbuf.h"
2727
#include "fncache.h"
28+
#include "pmu-hybrid.h"
2829

2930
struct perf_pmu perf_pmu__fake;
3031

@@ -613,7 +614,6 @@ static struct perf_cpu_map *__pmu_cpumask(const char *path)
613614
*/
614615
#define SYS_TEMPLATE_ID "./bus/event_source/devices/%s/identifier"
615616
#define CPUS_TEMPLATE_UNCORE "%s/bus/event_source/devices/%s/cpumask"
616-
#define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus"
617617

618618
static struct perf_cpu_map *pmu_cpumask(const char *name)
619619
{
@@ -645,6 +645,9 @@ static bool pmu_is_uncore(const char *name)
645645
char path[PATH_MAX];
646646
const char *sysfs;
647647

648+
if (perf_pmu__hybrid_mounted(name))
649+
return false;
650+
648651
sysfs = sysfs__mountpoint();
649652
snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name);
650653
return file_available(path);
@@ -951,6 +954,7 @@ static struct perf_pmu *pmu_lookup(const char *name)
951954
pmu->is_uncore = pmu_is_uncore(name);
952955
if (pmu->is_uncore)
953956
pmu->id = pmu_id(name);
957+
pmu->is_hybrid = perf_pmu__hybrid_mounted(name);
954958
pmu->max_precise = pmu_max_precise(name);
955959
pmu_add_cpu_aliases(&aliases, pmu);
956960
pmu_add_sys_aliases(&aliases, pmu);
@@ -962,6 +966,9 @@ static struct perf_pmu *pmu_lookup(const char *name)
962966
list_splice(&aliases, &pmu->aliases);
963967
list_add_tail(&pmu->list, &pmus);
964968

969+
if (pmu->is_hybrid)
970+
list_add_tail(&pmu->hybrid_list, &perf_pmu__hybrid_pmus);
971+
965972
pmu->default_config = perf_pmu__get_default_config(pmu);
966973

967974
return pmu;

tools/perf/util/pmu.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/bitmap.h>
66
#include <linux/compiler.h>
77
#include <linux/perf_event.h>
8+
#include <linux/list.h>
89
#include <stdbool.h>
910
#include "parse-events.h"
1011
#include "pmu-events/pmu-events.h"
@@ -19,6 +20,7 @@ enum {
1920

2021
#define PERF_PMU_FORMAT_BITS 64
2122
#define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
23+
#define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus"
2224

2325
struct perf_event_attr;
2426

@@ -34,6 +36,7 @@ struct perf_pmu {
3436
__u32 type;
3537
bool selectable;
3638
bool is_uncore;
39+
bool is_hybrid;
3740
bool auxtrace;
3841
int max_precise;
3942
struct perf_event_attr *default_config;
@@ -42,6 +45,7 @@ struct perf_pmu {
4245
struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */
4346
struct list_head caps; /* HEAD struct perf_pmu_caps -> list */
4447
struct list_head list; /* ELEM */
48+
struct list_head hybrid_list;
4549
};
4650

4751
extern struct perf_pmu perf_pmu__fake;

0 commit comments

Comments
 (0)