[PATCH V10 1/8] perf,tools: introduce generic FEAT for CPU attributes

From: kan . liang
Date: Wed Sep 16 2015 - 17:38:15 EST


From: Kan Liang <kan.liang@xxxxxxxxx>

This patch introduces generic FEAT for CPU attributes. For the patch
set, we only need cpu max frequency. But it can be easily extented to
support more other CPU attributes.

Signed-off-by: Kan Liang <kan.liang@xxxxxxxxx>
Acked-by: Jiri Olsa <jolsa@xxxxxxxxxx>
---
tools/perf/util/env.h | 11 +++++++++
tools/perf/util/header.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/header.h | 1 +
3 files changed, 74 insertions(+)

diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 0132b95..0eee628 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -6,6 +6,11 @@ struct cpu_topology_map {
int core_id;
};

+enum perf_header_cpu_attr {
+ PERF_HEADER_CPU_MAX_FREQ = 0,
+ PERF_HEADER_CPU_ATTR_MAX,
+};
+
struct perf_env {
char *hostname;
char *os_release;
@@ -31,6 +36,12 @@ struct perf_env {
char *numa_nodes;
char *pmu_mappings;
struct cpu_topology_map *cpu;
+ union {
+ unsigned long long cpu_attr[PERF_HEADER_CPU_ATTR_MAX];
+ struct {
+ unsigned long long max_freq;
+ } cpuattr;
+ };
};

extern struct perf_env perf_env;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 4383800..e4326f3 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <sys/utsname.h>
+#include <api/cpu.h>

#include "evlist.h"
#include "evsel.h"
@@ -847,6 +848,25 @@ write_it:
return do_write_string(fd, buffer);
}

+static int write_cpu_attributes(int fd, struct perf_header *h __maybe_unused,
+ struct perf_evlist *evlist __maybe_unused)
+{
+ u32 tag_id;
+ unsigned long long max_freq;
+ int ret;
+
+ tag_id = PERF_HEADER_CPU_MAX_FREQ;
+ ret = do_write(fd, &tag_id, sizeof(tag_id));
+ if (ret < 0)
+ return ret;
+
+ ret = cpu__get_max_freq(&max_freq);
+ if (ret < 0)
+ return ret;
+
+ return do_write(fd, &max_freq, sizeof(max_freq));
+}
+
static int write_branch_stack(int fd __maybe_unused,
struct perf_header *h __maybe_unused,
struct perf_evlist *evlist __maybe_unused)
@@ -1147,6 +1167,11 @@ static void print_cpuid(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
fprintf(fp, "# cpuid : %s\n", ph->env.cpuid);
}

+static void print_cpu_attributes(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
+{
+ fprintf(fp, "# CPU attributes: max frequency = %llu KHz\n", ph->env.cpuattr.max_freq);
+}
+
static void print_branch_stack(struct perf_header *ph __maybe_unused,
int fd __maybe_unused, FILE *fp)
{
@@ -1460,6 +1485,42 @@ static int process_cpuid(struct perf_file_section *section __maybe_unused,
return ph->env.cpuid ? 0 : -ENOMEM;
}

+static int process_cpu_attributes(struct perf_file_section *section __maybe_unused,
+ struct perf_header *ph, int fd,
+ void *data __maybe_unused)
+{
+ ssize_t ret;
+ u32 i, tag_id;
+ u64 nr;
+
+ for (i = 0; i < PERF_HEADER_CPU_ATTR_MAX; i++) {
+
+ ret = readn(fd, &tag_id, sizeof(tag_id));
+ if (ret != sizeof(tag_id))
+ return (ret < 0) ? errno : -1;
+
+ if (ph->needs_swap)
+ nr = bswap_32(tag_id);
+
+ if (tag_id >= PERF_HEADER_CPU_ATTR_MAX) {
+ pr_debug("The number of cpu attributes is not expected. "
+ "You may need to upgrade the perf tool.\n");
+ return -EINVAL;
+ }
+
+ ret = readn(fd, &nr, sizeof(nr));
+ if (ret != sizeof(nr))
+ return (ret < 0) ? errno : -1;
+
+ if (ph->needs_swap)
+ nr = bswap_64(nr);
+
+ ph->env.cpu_attr[tag_id] = nr;
+ }
+
+ return 0;
+}
+
static int process_total_mem(struct perf_file_section *section __maybe_unused,
struct perf_header *ph, int fd,
void *data __maybe_unused)
@@ -1948,6 +2009,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
FEAT_OPP(HEADER_PMU_MAPPINGS, pmu_mappings),
FEAT_OPP(HEADER_GROUP_DESC, group_desc),
FEAT_OPP(HEADER_AUXTRACE, auxtrace),
+ FEAT_OPP(HEADER_CPU_ATTR, cpu_attributes),
};

struct header_print_data {
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 05f27cb..09e6e1f 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -31,6 +31,7 @@ enum {
HEADER_PMU_MAPPINGS,
HEADER_GROUP_DESC,
HEADER_AUXTRACE,
+ HEADER_CPU_ATTR,
HEADER_LAST_FEATURE,
HEADER_FEAT_BITS = 256,
};
--
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/