linux/tools/perf/arch/s390/util/header.c
Ian Rogers 494c403ff1 perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
On ARM the cpuid is dependent on the core type of the CPU in
question. The PMU was passed for the sake of the CPU map but this
means in places a temporary PMU is created just to pass a CPU
value. Just pass the CPU and fix up the callers.

As there are no longer PMU users in header.h, shuffle forward
declarations earlier to work around build failures.

Reviewed-by: James Clark <james.clark@linaro.org>
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Xu Yang <xu.yang_2@nxp.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ben Zong-You Xie <ben717@andestech.com>
Cc: Benjamin Gray <bgray@linux.ibm.com>
Cc: Bibo Mao <maobibo@loongson.cn>
Cc: Clément Le Goffic <clement.legoffic@foss.st.com>
Cc: Dima Kogan <dima@secretsauce.net>
Cc: Dr. David Alan Gilbert <linux@treblig.org>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mike Leach <mike.leach@linaro.org>
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: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yicong Yang <yangyicong@hisilicon.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-riscv@lists.infradead.org
Link: https://lore.kernel.org/r/20241107162035.52206-7-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-11-16 16:40:30 -03:00

147 lines
3.9 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Implementation of get_cpuid().
*
* Copyright IBM Corp. 2014, 2018
* Author(s): Alexander Yarygin <yarygin@linux.vnet.ibm.com>
* Thomas Richter <tmricht@linux.vnet.ibm.com>
*/
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/zalloc.h>
#include "../../util/header.h"
#define SYSINFO_MANU "Manufacturer:"
#define SYSINFO_TYPE "Type:"
#define SYSINFO_MODEL "Model:"
#define SRVLVL_CPUMF "CPU-MF:"
#define SRVLVL_VERSION "version="
#define SRVLVL_AUTHORIZATION "authorization="
#define SYSINFO "/proc/sysinfo"
#define SRVLVL "/proc/service_levels"
int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
{
char *cp, *line = NULL, *line2;
char type[8], model[33], version[8], manufacturer[32], authorization[8];
int tpsize = 0, mdsize = 0, vssize = 0, mfsize = 0, atsize = 0;
int read;
unsigned long line_sz;
size_t nbytes;
FILE *sysinfo;
/*
* Scan /proc/sysinfo line by line and read out values for
* Manufacturer:, Type: and Model:, for example:
* Manufacturer: IBM
* Type: 2964
* Model: 702 N96
* The first word is the Model Capacity and the second word is
* Model (can be omitted). Both words have a maximum size of 16
* bytes.
*/
memset(manufacturer, 0, sizeof(manufacturer));
memset(type, 0, sizeof(type));
memset(model, 0, sizeof(model));
memset(version, 0, sizeof(version));
memset(authorization, 0, sizeof(authorization));
sysinfo = fopen(SYSINFO, "r");
if (sysinfo == NULL)
return errno;
while ((read = getline(&line, &line_sz, sysinfo)) != -1) {
if (!strncmp(line, SYSINFO_MANU, strlen(SYSINFO_MANU))) {
line2 = line + strlen(SYSINFO_MANU);
while ((cp = strtok_r(line2, "\n ", &line2))) {
mfsize += scnprintf(manufacturer + mfsize,
sizeof(manufacturer) - mfsize, "%s", cp);
}
}
if (!strncmp(line, SYSINFO_TYPE, strlen(SYSINFO_TYPE))) {
line2 = line + strlen(SYSINFO_TYPE);
while ((cp = strtok_r(line2, "\n ", &line2))) {
tpsize += scnprintf(type + tpsize,
sizeof(type) - tpsize, "%s", cp);
}
}
if (!strncmp(line, SYSINFO_MODEL, strlen(SYSINFO_MODEL))) {
line2 = line + strlen(SYSINFO_MODEL);
while ((cp = strtok_r(line2, "\n ", &line2))) {
mdsize += scnprintf(model + mdsize, sizeof(model) - mdsize,
"%s%s", model[0] ? "," : "", cp);
}
break;
}
}
fclose(sysinfo);
/* Missing manufacturer, type or model information should not happen */
if (!manufacturer[0] || !type[0] || !model[0])
return EINVAL;
/*
* Scan /proc/service_levels and return the CPU-MF counter facility
* version number and authorization level.
* Optional, does not exist on z/VM guests.
*/
sysinfo = fopen(SRVLVL, "r");
if (sysinfo == NULL)
goto skip_sysinfo;
while ((read = getline(&line, &line_sz, sysinfo)) != -1) {
if (strncmp(line, SRVLVL_CPUMF, strlen(SRVLVL_CPUMF)))
continue;
line2 = line + strlen(SRVLVL_CPUMF);
while ((cp = strtok_r(line2, "\n ", &line2))) {
if (!strncmp(cp, SRVLVL_VERSION,
strlen(SRVLVL_VERSION))) {
char *sep = strchr(cp, '=');
vssize += scnprintf(version + vssize,
sizeof(version) - vssize, "%s", sep + 1);
}
if (!strncmp(cp, SRVLVL_AUTHORIZATION,
strlen(SRVLVL_AUTHORIZATION))) {
char *sep = strchr(cp, '=');
atsize += scnprintf(authorization + atsize,
sizeof(authorization) - atsize, "%s", sep + 1);
}
}
}
fclose(sysinfo);
skip_sysinfo:
free(line);
if (version[0] && authorization[0] )
nbytes = snprintf(buffer, sz, "%s,%s,%s,%s,%s",
manufacturer, type, model, version,
authorization);
else
nbytes = snprintf(buffer, sz, "%s,%s,%s", manufacturer, type,
model);
return (nbytes >= sz) ? ENOBUFS : 0;
}
char *get_cpuid_str(struct perf_cpu cpu)
{
char *buf = malloc(128);
if (buf && get_cpuid(buf, 128, cpu))
zfree(&buf);
return buf;
}