mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	[CPUFREQ] return error when failing to set minfreq
I just stumbled on this bug/feature, this is how to reproduce it: # echo 450000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq # echo 450000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq # echo powersave > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor # cpufreq-info -p 450000 450000 powersave # echo 1800000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq ; echo $? 0 # cpufreq-info -p 450000 450000 powersave Here it is. The kernel refuses to set a min_freq higher than the max_freq but it allows a max_freq lower than min_freq (lowering min_freq also). This behaviour is pretty straightforward (but undocumented) and it doesn't return an error altough failing to accomplish the requested action (set min_freq). The problem (IMO) is basically that userspace is not allowed to set a full policy atomically while the kernel always does that thus it must enforce an ordering on operations. The attached patch returns -EINVAL if trying to increase frequencies starting from scaling_min_freq and documents the correct ordering of writes. Signed-off-by: Mattia Dongili <malattia@linux.it> Signed-off-by: Dominik Brodowski <linux at dominikbrodowski.net> Signed-off-by: Dave Jones <davej@redhat.com> --
This commit is contained in:
		
							parent
							
								
									49b1e3ea19
								
							
						
					
					
						commit
						9c9a43ed27
					
				
					 2 changed files with 9 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -157,6 +157,9 @@ scaling_min_freq and
 | 
			
		|||
scaling_max_freq		show the current "policy limits" (in
 | 
			
		||||
				kHz). By echoing new values into these
 | 
			
		||||
				files, you can change these limits.
 | 
			
		||||
				NOTE: when setting a policy you need to
 | 
			
		||||
				first set scaling_max_freq, then
 | 
			
		||||
				scaling_min_freq.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
If you have selected the "userspace" governor which allows you to
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1343,6 +1343,11 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
 | 
			
		|||
 | 
			
		||||
	memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo));
 | 
			
		||||
 | 
			
		||||
	if (policy->min > data->min && policy->min > policy->max) {
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
		goto error_out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* verify the cpu speed can be set within this limit */
 | 
			
		||||
	ret = cpufreq_driver->verify(policy);
 | 
			
		||||
	if (ret)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue