Re: [PATCH 1/2] tools/perf: Add utility function to read /proc/cpuinfo for any field
From: kajoljain <hidden>
Date: 2022-05-04 13:48:00
Also in:
linux-perf-users
On 4/28/22 20:38, Athira Rajeev wrote:
quoted hunk ↗ jump to hunk
/proc/cpuinfo provides information about type of processor, number of CPU's etc. Reading /proc/cpuinfo file outputs useful information by field name like cpu, platform, model (depending on architecture) and its value separated by colon. Add new utility function "cpuinfo_field" in "util/header.c" which accepts field name as input string to search in /proc/cpuinfo content. This returns the first matching value as resulting string. Example, calling the function "cpuinfo_field(platform)" in powerpc returns the platform value. This can be used to fetch processor information from "cpuinfo" by other utilities/testcases. Signed-off-by: Athira Rajeev <redacted> --- tools/perf/util/header.c | 54 ++++++++++++++++++++++++++++++++++++++++ tools/perf/util/header.h | 1 + 2 files changed, 55 insertions(+)diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index a27132e5a5ef..0c8dfd0c1e78 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c@@ -983,6 +983,60 @@ static int write_dir_format(struct feat_fd *ff, return do_write(ff, &data->dir.version, sizeof(data->dir.version)); } +/* + * Return entry from /proc/cpuinfo + * indicated by "search" parameter. + */ +char *cpuinfo_field(const char *search) +{ + FILE *file; + char *buf = NULL; + char *copy_buf = NULL, *p; + size_t len = 0; + int ret = -1; + + if (!search) + return NULL; + + file = fopen("/proc/cpuinfo", "r"); + if (!file) + return NULL; + + while (getline(&buf, &len, file) > 0) { + ret = strncmp(buf, search, strlen(search)); + if (!ret) + break;
Hi Athira, Do we need ret variable. Since we will come out of the loop only when we reach EOF.
+ } + + if (ret) + goto done; + + /* + * Trim the new line and separate + * value for search field from ":" + * in cpuinfo line output. + * Example output line: + * platform : <value> + */ + copy_buf = buf; + p = strchr(copy_buf, ':'); + if (p && *(p+1) == ' ' && *(p+2))
Can you try using strim instead to remove whitespaces. This function will remove leading and trailing whitespaces from the string.
+ copy_buf = p + 2; + p = strchr(copy_buf, '\n');
do we need to replace `\n` here ?
+ if (p) + *p = '\0'; + + /* Copy the filtered string to buf */ + strcpy(buf, copy_buf)
You are initializing buf to NULL. So do we need to do fclose and return buf separately here? Can you move free(buf) in above condition and reuse `done` code.
quoted hunk ↗ jump to hunk
+ + fclose(file); + return buf;> + +done: + free(buf); + fclose(file); + return NULL; +} /* * Check whether a CPU is online *diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 0eb4bc29a5a4..b0f754364bd4 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h@@ -166,4 +166,5 @@ int get_cpuid(char *buffer, size_t sz); char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused); int strcmp_cpuid_str(const char *s1, const char *s2); +char *cpuinfo_field(const char *search); #endif /* __PERF_HEADER_H */