[CRIU] [PATCH 06/22] cpu: Prepare scaffold for obtaining cpu features

Pavel Emelyanov xemul at parallels.com
Wed Dec 12 09:09:11 EST 2012


On 12/12/2012 06:04 PM, Cyrill Gorcunov wrote:
> On Wed, Dec 12, 2012 at 05:47:29PM +0400, Pavel Emelyanov wrote:
>>> +#define X86_FEATURE_MTRR		(0*32+12) /* Memory Type Range Registers */
>>> +#define X86_FEATURE_PGE			(0*32+13) /* Page Global Enable */
>>> +#define X86_FEATURE_MCA			(0*32+14) /* Machine Check Architecture */
>>> +#define X86_FEATURE_CMOV		(0*32+15) /* CMOV instructions */
>>> +						  /* (plus FCMOVcc, FCOMI with FPU) */
>>
>> Why do we need all this crap, while we use only 3 of them?
> 
> These are common bits and I don't know which else we might need in near
> future. Keeping the whole cpuid infrastructure close to one implemented
> in kernel is certainly a win.
> 
>>> +int cpu_parse_flags(CpuFeature *feature, char *line)
>>> +{
>>> +	char *tok;
>>> +
>>> +	for (tok = strtok(line, " \t\n"); tok;
>>> +	     tok = strtok(NULL, " \t\n")) {
>>> +		if (!strcmp(tok, x86_cap_flags[X86_FEATURE_FXSR]))
>>> +			feature->fxsr = true;
>>> +		else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_XSAVE]))
>>> +			feature->xsave = true;
>>> +		else if (!strcmp(tok, x86_cap_flags[X86_FEATURE_FPU]))
>>> +			feature->fpu = true;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>
>> Should be in proc_parse.c
> 
> Hmmm, well I did it on purpose to relax proc_parse from  specific code,
> but sure I can update it.
> 
>>> +int cpu_fill_feature(CpuFeature *feature)
>>> +{
>>> +	/*
>>> +	 * Simply fills the cache if nil passed.
>>> +	 */
>>> +
>>> +	if (feature) {
>>> +		cpu_feature__init(feature);
>>> +		if (likely(use_cached_feature)) {
>>> +			feature->fpu	= cached_feature.fpu;
>>> +			feature->fxsr	= cached_feature.fxsr;
>>> +			feature->xsave	= cached_feature.xsave;
>>> +			return 0;
>>> +		}
>>> +	}
>>> +
>>> +	if (parse_cpuinfo_features(&cached_feature))
>>> +		return -1;
>>> +
>>> +	use_cached_feature = true;
>>> +
>>> +	if (!feature)
>>> +		return 0;
>>> +
>>> +	return cpu_fill_feature(feature);
>>
>> This is awful :( This kind of code is typically written like
>>
>> if (!cache)
>> 	cache = refill_cache
>>
>> val = cache
> 
> Doesn't look that awful for me, but sure, will update.
> 
>>> +bool cpu_check_feature(CpuFeature *feature)
>>> +{
> 
>> Name of function is bad.
> 
> Would cpu_verify_feature make you happy?

No. Since this function checks some _specific_ (_hardcoded_) feature, it should
be named respectively.

>>> +int cpu_rt_init(void)
>>> +{
>>> +	u32 eax, ebx, ecx, edx;
>>> +
>>> +	/*
>>> +	 * Make sure the cpu we're running on
>>> +	 * can run FPU related stuff.
>>> +	 */
>>> +	cpuid(1, &eax, &ebx, &ecx, &edx);
>>> +	((u32 *)rt_cpu_features)[0] = edx;
>>> +	((u32 *)rt_cpu_features)[4] = ecx;
>>> +
>>
>> First we call cpuid...
>>
>>> +	if (cpu_fill_feature(NULL))
>>> +		return -1;
>>> +
>>> +	if (!cpu_check_feature(&cached_feature))
>>> +		return -1;
>>> +
>>> +	return 0;
>>> +}
>>
>> ... then read /proc/cpuinfo. What for?
> 
>>From changelog
> 
>      - adds ability to find some of rt-features the _cpu_ supports. In
>        particular if xsave insn is supported we need to know how big memory
>        slab is needed to keep complete fpu frame
> 
> this gives us the size of fpu frame. Moreover, since we need to call cpuid
> anyway, we do a fast early check for features we need from cpuid results.
> If we have bits needed on hw level, we still need to check if kernel was not booted
> with "nofxsr", which disables fxsave instruction and prevents us from continue
> working, if everything is fine -- we can do restore.

That's OK, but why not use _one_ way of getting this -- either cpuid or proc?
Why both?

> 	Cyrill
> .
> 




More information about the CRIU mailing list