[CRIU] [PATCH 5/6] cpuinfo: x86 -- Rework cpuinfo parsing
Cyrill Gorcunov
gorcunov at openvz.org
Mon Sep 1 02:06:53 PDT 2014
We need more data to handle not features only.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
arch/x86/cpu.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++---
include/proc_parse.h | 2 +-
proc_parse.c | 18 ++---
3 files changed, 199 insertions(+), 21 deletions(-)
diff --git a/arch/x86/cpu.c b/arch/x86/cpu.c
index 2ea4e06bccc0..1ff8de1831ad 100644
--- a/arch/x86/cpu.c
+++ b/arch/x86/cpu.c
@@ -28,6 +28,7 @@
static CpuinfoEntry cpu_info = CPUINFO_ENTRY__INIT;
static CpuinfoX86Entry cpu_x86_info = CPUINFO_X86_ENTRY__INIT;
static CpuinfoX86Entry *cpu_x86_info_ptr = &cpu_x86_info;
+static char cpu_model_name[256];
const char * const x86_cap_flags[NCAPINTS_BITS] = {
[X86_FEATURE_FPU] = "fpu",
@@ -102,14 +103,197 @@ bool cpu_has_feature(unsigned int feature)
return false;
}
-static int proc_cpuinfo_match(char *tok)
+static int proc_cpuinfo_handler(char *line)
{
- if (!strcmp(tok, x86_cap_flags[X86_FEATURE_FXSR]))
- cpu_set_feature(X86_FEATURE_FXSR);
- else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_XSAVE]))
- cpu_set_feature(X86_FEATURE_XSAVE);
- else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_FPU]))
- cpu_set_feature(X86_FEATURE_FPU);
+ /*
+ * Typical structure is (per-core/ht)
+ *
+ * processor : 3
+ * vendor_id : GenuineIntel
+ * cpu family : 6
+ * model : 42
+ * model name : Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz
+ * stepping : 7
+ * microcode : 0x29
+ * cpu MHz : 800.195
+ * cache size : 3072 KB
+ * physical id : 0
+ * siblings : 4
+ * core id : 1
+ * cpu cores : 2
+ * apicid : 3
+ * initial apicid : 3
+ * fpu : yes
+ * fpu_exception : yes
+ * cpuid level : 13
+ * wp : yes
+ * flags : fpu vme de pse tsc msr pae mce cx8 apic ...
+ * bogomips : 4984.07
+ * clflush size : 64
+ * cache_alignment : 64
+ * address sizes : 36 bits physical, 48 bits virtual
+ * power management:
+ *
+ * Note we assume that all CPUs in the system are same
+ * class and parse only first one. Still if needed we may
+ * parse every core entry increasing the numbers of entries
+ * in protobuf image. For a while it's not needed so lets
+ * stick with simple.
+ */
+
+ if (!strncmp(line, "vendor_id\t: ", 12)) {
+ if (!strncmp(&line[12], "GenuineIntel", 12)) {
+ cpu_x86_info.vendor_id = CPUINFO_X86_ENTRY__VENDOR__INTEL;
+ } else if (!strncmp(&line[12], "AuthenticAMD", 12)) {
+ cpu_x86_info.vendor_id = CPUINFO_X86_ENTRY__VENDOR__AMD;
+ } else {
+ pr_err("Unsupported CPU vendor `%s'\n", &line[12]);
+ return -1;
+ }
+ } else if (!strncmp(line, "cpu family\t: ", 13)) {
+ cpu_x86_info.cpu_family = atoi(&line[13]);
+ } else if (!strncmp(line, "model\t\t: ", 9)) {
+ cpu_x86_info.model = atoi(&line[9]);
+ } else if (!strncmp(line, "model name\t: ", 13)) {
+ strncpy(cpu_model_name, &line[13], min(sizeof(cpu_model_name),
+ strlen(&line[13]) - 1));
+ cpu_x86_info.model_name = cpu_model_name;
+ } else if (!strncmp(line, "stepping\t: ", 11)) {
+ cpu_x86_info.has_stepping = true;
+ cpu_x86_info.stepping = atoi(&line[11]);
+ } else if (!strncmp(line, "physical id\t: ", 14)) {
+ cpu_x86_info.has_physical_id = true;
+ cpu_x86_info.physical_id = atoi(&line[14]);
+ } else if (!strncmp(line, "siblings\t: ", 11)) {
+ cpu_x86_info.has_siblings = true;
+ cpu_x86_info.siblings = atoi(&line[11]);
+ } else if (!strncmp(line, "core id\t\t: ", 11)) {
+ cpu_x86_info.has_core_id = true;
+ cpu_x86_info.core_id = atoi(&line[11]);
+ } else if (!strncmp(line, "cpu cores\t: ", 12)) {
+ cpu_x86_info.has_cpu_cores = true;
+ cpu_x86_info.cpu_cores = atoi(&line[12]);
+ } else if (!strncmp(line, "flags\t\t:", 8)) {
+ char *tok;
+
+ for (tok = strtok(line, " \t\n"); tok;
+ tok = strtok(NULL, " \t\n")) {
+ if (!strcmp(tok, x86_cap_flags[X86_FEATURE_FPU]))
+ cpu_set_feature(X86_FEATURE_FPU);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_CX8]))
+ cpu_set_feature(X86_FEATURE_CX8);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_CMOV]))
+ cpu_set_feature(X86_FEATURE_CMOV);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_CLFLUSH]))
+ cpu_set_feature(X86_FEATURE_CLFLUSH);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_MMX]))
+ cpu_set_feature(X86_FEATURE_MMX);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_FXSR]))
+ cpu_set_feature(X86_FEATURE_FXSR);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_XMM]))
+ cpu_set_feature(X86_FEATURE_XMM);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_XMM2]))
+ cpu_set_feature(X86_FEATURE_XMM2);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_SYSCALL]))
+ cpu_set_feature(X86_FEATURE_SYSCALL);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_MMXEXT]))
+ cpu_set_feature(X86_FEATURE_MMXEXT);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_RDTSCP]))
+ cpu_set_feature(X86_FEATURE_RDTSCP);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_3DNOWEXT]))
+ cpu_set_feature(X86_FEATURE_3DNOWEXT);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_3DNOW]))
+ cpu_set_feature(X86_FEATURE_3DNOW);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_REP_GOOD]))
+ cpu_set_feature(X86_FEATURE_REP_GOOD);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_NOPL]))
+ cpu_set_feature(X86_FEATURE_NOPL);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_XMM3]))
+ cpu_set_feature(X86_FEATURE_XMM3);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_PCLMULQDQ]))
+ cpu_set_feature(X86_FEATURE_PCLMULQDQ);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_MWAIT]))
+ cpu_set_feature(X86_FEATURE_MWAIT);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_TM2]))
+ cpu_set_feature(X86_FEATURE_TM2);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_SSSE3]))
+ cpu_set_feature(X86_FEATURE_SSSE3);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_FMA]))
+ cpu_set_feature(X86_FEATURE_FMA);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_CX16]))
+ cpu_set_feature(X86_FEATURE_CX16);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_XMM4_1]))
+ cpu_set_feature(X86_FEATURE_XMM4_1);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_XMM4_2]))
+ cpu_set_feature(X86_FEATURE_XMM4_2);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_MOVBE]))
+ cpu_set_feature(X86_FEATURE_MOVBE);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_POPCNT]))
+ cpu_set_feature(X86_FEATURE_POPCNT);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_AES]))
+ cpu_set_feature(X86_FEATURE_AES);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_XSAVE]))
+ cpu_set_feature(X86_FEATURE_XSAVE);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_AVX]))
+ cpu_set_feature(X86_FEATURE_AVX);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_F16C]))
+ cpu_set_feature(X86_FEATURE_F16C);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_RDRAND]))
+ cpu_set_feature(X86_FEATURE_RDRAND);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_ABM]))
+ cpu_set_feature(X86_FEATURE_ABM);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_SSE4A]))
+ cpu_set_feature(X86_FEATURE_SSE4A);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_MISALIGNSSE]))
+ cpu_set_feature(X86_FEATURE_MISALIGNSSE);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_3DNOWPREFETCH]))
+ cpu_set_feature(X86_FEATURE_3DNOWPREFETCH);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_XOP]))
+ cpu_set_feature(X86_FEATURE_XOP);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_FMA4]))
+ cpu_set_feature(X86_FEATURE_FMA4);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_TBM]))
+ cpu_set_feature(X86_FEATURE_TBM);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_XSAVEOPT]))
+ cpu_set_feature(X86_FEATURE_XSAVEOPT);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_BMI1]))
+ cpu_set_feature(X86_FEATURE_BMI1);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_HLE]))
+ cpu_set_feature(X86_FEATURE_HLE);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_AVX2]))
+ cpu_set_feature(X86_FEATURE_AVX2);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_BMI2]))
+ cpu_set_feature(X86_FEATURE_BMI2);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_ERMS]))
+ cpu_set_feature(X86_FEATURE_ERMS);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_INVPCID]))
+ cpu_set_feature(X86_FEATURE_INVPCID);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_RTM]))
+ cpu_set_feature(X86_FEATURE_RTM);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_MPX]))
+ cpu_set_feature(X86_FEATURE_MPX);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_AVX512F]))
+ cpu_set_feature(X86_FEATURE_AVX512F);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_RDSEED]))
+ cpu_set_feature(X86_FEATURE_RDSEED);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_ADX]))
+ cpu_set_feature(X86_FEATURE_ADX);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_CLFLUSHOPT]))
+ cpu_set_feature(X86_FEATURE_CLFLUSHOPT);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_AVX512PF]))
+ cpu_set_feature(X86_FEATURE_AVX512PF);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_AVX512ER]))
+ cpu_set_feature(X86_FEATURE_AVX512ER);
+ else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_AVX512CD]))
+ cpu_set_feature(X86_FEATURE_AVX512CD);
+ }
+
+ /*
+ * CPU features flags are last in the output!
+ */
+ return 1;
+ }
+
return 0;
}
@@ -129,7 +313,7 @@ int cpu_init(void)
{
cpu_init_protobuf();
- if (parse_cpuinfo_features(proc_cpuinfo_match))
+ if (parse_cpuinfo(proc_cpuinfo_handler))
return -1;
BUILD_BUG_ON(sizeof(struct xsave_struct) != XSAVE_SIZE);
diff --git a/include/proc_parse.h b/include/proc_parse.h
index 3ac25b260869..4baf626ae320 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -185,7 +185,7 @@ extern int parse_fdinfo(int fd, int type,
int (*cb)(union fdinfo_entries *e, void *arg), void *arg);
extern int parse_fdinfo_pid(int pid, int fd, int type,
int (*cb)(union fdinfo_entries *e, void *arg), void *arg);
-extern int parse_cpuinfo_features(int (*handler)(char *tok));
+extern int parse_cpuinfo(int (*handler)(char *line));
extern int parse_file_locks(void);
struct pid;
diff --git a/proc_parse.c b/proc_parse.c
index def91b2a3acb..94adf9d8388f 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -43,9 +43,10 @@ static char *buf = __buf.buf;
#define BUF_SIZE sizeof(__buf.buf)
-int parse_cpuinfo_features(int (*handler)(char *tok))
+int parse_cpuinfo(int (*handler)(char *line))
{
FILE *cpuinfo;
+ int ret = -1;
cpuinfo = fopen("/proc/cpuinfo", "r");
if (!cpuinfo) {
@@ -54,20 +55,13 @@ int parse_cpuinfo_features(int (*handler)(char *tok))
}
while (fgets(buf, BUF_SIZE, cpuinfo)) {
- char *tok;
-
- if (strncmp(buf, "flags\t\t:", 8))
- continue;
-
- for (tok = strtok(buf, " \t\n"); tok;
- tok = strtok(NULL, " \t\n")) {
- if (handler(tok) < 0)
- break;
- }
+ ret = handler(buf);
+ if (ret)
+ break;
}
fclose(cpuinfo);
- return 0;
+ return ret == 1 ? 0 : ret;
}
/* check the @line starts with "%lx-%lx" format */
--
1.9.3
More information about the CRIU
mailing list