[CRIU] [PATCH 05/15] cpuinfo: x86 -- Rework cpuinfo parsing
Pavel Emelyanov
xemul at parallels.com
Tue Sep 23 11:05:36 PDT 2014
On 09/19/2014 06:03 PM, Cyrill Gorcunov wrote:
> 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);
OMG. Is there some better way of getting this mask? Via sysfs maybe?
> + }
> +
> + /*
> + * 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 7fade0669426..4707fee00ee8 100644
> --- a/include/proc_parse.h
> +++ b/include/proc_parse.h
> @@ -210,7 +210,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 9aa17d4ec483..a06034180894 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(PROC_GEN, "cpuinfo");
> 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 */
>
More information about the CRIU
mailing list