perf tools riscv: Add support for get_cpuid_str function
authorNikita Shubin <n.shubin@yadro.com>
Mon, 15 Aug 2022 13:22:38 +0000 (16:22 +0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 27 Oct 2022 19:37:24 +0000 (16:37 -0300)
The get_cpuid_str function returns the string that contains values of
MVENDORID, MARCHID and MIMPID in hex format separated by coma.

The values themselves are taken from first cpu entry in "/proc/cpuid"
that contains "mvendorid", "marchid" and "mimpid".

Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
Tested-by: Kautuk Consul <kconsul@ventanamicro.com>
Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Anup Patel <anup@brainfault.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: linux-riscv@lists.infradead.org
Cc: linux@yadro.com
Link: https://lore.kernel.org/r/20220815132251.25702-2-nikita.shubin@maquefel.me
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/arch/riscv/util/Build
tools/perf/arch/riscv/util/header.c [new file with mode: 0644]

index 7d3050134ae0fd4b1bacabb41a95fa51903beff3..603dbb5ae4dc9df5e6fcc2d3db1453d4f520ac4d 100644 (file)
@@ -1,4 +1,5 @@
 perf-y += perf_regs.o
+perf-y += header.o
 
 perf-$(CONFIG_DWARF) += dwarf-regs.o
 perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
diff --git a/tools/perf/arch/riscv/util/header.c b/tools/perf/arch/riscv/util/header.c
new file mode 100644 (file)
index 0000000..4a41856
--- /dev/null
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Implementation of get_cpuid().
+ *
+ * Author: Nikita Shubin <n.shubin@yadro.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <api/fs/fs.h>
+#include <errno.h>
+#include "../../util/debug.h"
+#include "../../util/header.h"
+
+#define CPUINFO_MVEN   "mvendorid"
+#define CPUINFO_MARCH  "marchid"
+#define CPUINFO_MIMP   "mimpid"
+#define CPUINFO                "/proc/cpuinfo"
+
+static char *_get_field(const char *line)
+{
+       char *line2, *nl;
+
+       line2 = strrchr(line, ' ');
+       if (!line2)
+               return NULL;
+
+       line2++;
+       nl = strrchr(line, '\n');
+       if (!nl)
+               return NULL;
+
+       return strndup(line2, nl - line2);
+}
+
+static char *_get_cpuid(void)
+{
+       char *line = NULL;
+       char *mvendorid = NULL;
+       char *marchid = NULL;
+       char *mimpid = NULL;
+       char *cpuid = NULL;
+       int read;
+       unsigned long line_sz;
+       FILE *cpuinfo;
+
+       cpuinfo = fopen(CPUINFO, "r");
+       if (cpuinfo == NULL)
+               return cpuid;
+
+       while ((read = getline(&line, &line_sz, cpuinfo)) != -1) {
+               if (!strncmp(line, CPUINFO_MVEN, strlen(CPUINFO_MVEN))) {
+                       mvendorid = _get_field(line);
+                       if (!mvendorid)
+                               goto free;
+               } else if (!strncmp(line, CPUINFO_MARCH, strlen(CPUINFO_MARCH))) {
+                       marchid = _get_field(line);
+                       if (!marchid)
+                               goto free;
+               } else if (!strncmp(line, CPUINFO_MIMP, strlen(CPUINFO_MIMP))) {
+                       mimpid = _get_field(line);
+                       if (!mimpid)
+                               goto free;
+
+                       break;
+               }
+       }
+
+       if (!mvendorid || !marchid || !mimpid)
+               goto free;
+
+       if (asprintf(&cpuid, "%s-%s-%s", mvendorid, marchid, mimpid) < 0)
+               cpuid = NULL;
+
+free:
+       fclose(cpuinfo);
+       free(mvendorid);
+       free(marchid);
+       free(mimpid);
+
+       return cpuid;
+}
+
+int get_cpuid(char *buffer, size_t sz)
+{
+       char *cpuid = _get_cpuid();
+       int ret = 0;
+
+       if (sz < strlen(cpuid)) {
+               ret = -EINVAL;
+               goto free;
+       }
+
+       scnprintf(buffer, sz, "%s", cpuid);
+free:
+       free(cpuid);
+       return ret;
+}
+
+char *
+get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+{
+       return _get_cpuid();
+}