Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753326AbbG1SqK (ORCPT ); Tue, 28 Jul 2015 14:46:10 -0400 Received: from mga11.intel.com ([192.55.52.93]:19665 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752246AbbG1Sof (ORCPT ); Tue, 28 Jul 2015 14:44:35 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,564,1432623600"; d="scan'208";a="531811758" From: kan.liang@intel.com To: a.p.zijlstra@chello.nl, acme@kernel.org Cc: luto@kernel.org, mingo@redhat.com, eranian@google.com, ak@linux.intel.com, mark.rutland@arm.com, adrian.hunter@intel.com, jolsa@kernel.org, namhyung@kernel.org, linux-kernel@vger.kernel.org, Kan Liang Subject: [PATCH V3 1/5] perf,tools: introduce generic FEAT for CPU attributes Date: Tue, 28 Jul 2015 07:29:31 -0400 Message-Id: <1438082975-47730-2-git-send-email-kan.liang@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1438082975-47730-1-git-send-email-kan.liang@intel.com> References: <1438082975-47730-1-git-send-email-kan.liang@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4939 Lines: 174 From: Kan Liang 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. The cpu max frequency is from the first online cpu. Signed-off-by: Kan Liang --- tools/perf/util/cpumap.c | 32 ++++++++++++++++++++++++++++++++ tools/perf/util/cpumap.h | 1 + tools/perf/util/header.c | 35 +++++++++++++++++++++++++++++++++++ tools/perf/util/header.h | 7 +++++++ 4 files changed, 75 insertions(+) diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 3667e21..ef7e57e 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -499,3 +499,35 @@ int cpu__setup_cpunode_map(void) closedir(dir1); return 0; } + +u64 get_cpu_max_freq(void) +{ + const char *mnt; + char path[PATH_MAX], tmp; + FILE *fp; + u64 freq; + int cpu = 0; + int ret; + + mnt = sysfs__mountpoint(); + if (!mnt) + return 0; + + snprintf(path, PATH_MAX, "%s/devices/system/cpu/online", mnt); + fp = fopen(path, "r"); + if (fp) { + ret = fscanf(fp, "%u%c", &cpu, &tmp); + fclose(fp); + if (ret < 1) + return 0; + } + + snprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", mnt, cpu); + fp = fopen(path, "r"); + if (!fp) + return 0; + ret = fscanf(fp, "%lu", &freq); + fclose(fp); + + return (ret == 1) ? freq : 0; +} diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 0af9cec..8fd2bd6 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -58,6 +58,7 @@ int max_node_num; int *cpunode_map; int cpu__setup_cpunode_map(void); +u64 get_cpu_max_freq(void); static inline int cpu__max_node(void) { diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 03ace57..31be7bc 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -862,6 +862,16 @@ 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) +{ + u64 freq; + + freq = get_cpu_max_freq(); + + return do_write(fd, &freq, sizeof(freq)); +} + static int write_branch_stack(int fd __maybe_unused, struct perf_header *h __maybe_unused, struct perf_evlist *evlist __maybe_unused) @@ -1158,6 +1168,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 = %lu KHz\n", ph->env.cpu_attr[PERF_HEADER_CPU_MAX_FREQ]); +} + static void print_branch_stack(struct perf_header *ph __maybe_unused, int fd __maybe_unused, FILE *fp) { @@ -1471,6 +1486,25 @@ 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; + u64 nr; + + ret = readn(fd, &nr, sizeof(nr)); + if (ret != sizeof(nr)) + return -1; + + if (ph->needs_swap) + nr = bswap_64(nr); + + ph->env.cpu_attr[PERF_HEADER_CPU_MAX_FREQ] = 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) @@ -1885,6 +1919,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { FEAT_OPP(HEADER_NRCPUS, nrcpus), FEAT_OPP(HEADER_CPUDESC, cpudesc), FEAT_OPP(HEADER_CPUID, cpuid), + FEAT_OPP(HEADER_CPU_ATTR, cpu_attributes), FEAT_OPP(HEADER_TOTAL_MEM, total_mem), FEAT_OPP(HEADER_EVENT_DESC, event_desc), FEAT_OPP(HEADER_CMDLINE, cmdline), diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index d4d5796..fe1654c 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -22,6 +22,7 @@ enum { HEADER_NRCPUS, HEADER_CPUDESC, HEADER_CPUID, + HEADER_CPU_ATTR, HEADER_TOTAL_MEM, HEADER_CMDLINE, HEADER_EVENT_DESC, @@ -66,6 +67,11 @@ struct perf_header; int perf_file_header__read(struct perf_file_header *header, struct perf_header *ph, int fd); +enum perf_header_cpu_attr { + PERF_HEADER_CPU_MAX_FREQ = 0, + PERF_HEADER_CPU_ATTR_MAX, +}; + struct perf_session_env { char *hostname; char *os_release; @@ -75,6 +81,7 @@ struct perf_session_env { int nr_cpus_avail; char *cpu_desc; char *cpuid; + u64 cpu_attr[PERF_HEADER_CPU_ATTR_MAX]; unsigned long long total_mem; int nr_cmdline; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/