[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