56 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			56 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <linux/sched.h>
 | |
| #include <linux/math64.h>
 | |
| #include <linux/percpu.h>
 | |
| #include <linux/irqflags.h>
 | |
| 
 | |
| #include <asm/cpufeature.h>
 | |
| #include <asm/processor.h>
 | |
| 
 | |
| #ifdef CONFIG_SMP
 | |
| 
 | |
| static DEFINE_PER_CPU(struct aperfmperf, old_perf_sched);
 | |
| 
 | |
| static unsigned long scale_aperfmperf(void)
 | |
| {
 | |
| 	struct aperfmperf val, *old = &__get_cpu_var(old_perf_sched);
 | |
| 	unsigned long ratio, flags;
 | |
| 
 | |
| 	local_irq_save(flags);
 | |
| 	get_aperfmperf(&val);
 | |
| 	local_irq_restore(flags);
 | |
| 
 | |
| 	ratio = calc_aperfmperf_ratio(old, &val);
 | |
| 	*old = val;
 | |
| 
 | |
| 	return ratio;
 | |
| }
 | |
| 
 | |
| unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu)
 | |
| {
 | |
| 	/*
 | |
| 	 * do aperf/mperf on the cpu level because it includes things
 | |
| 	 * like turbo mode, which are relevant to full cores.
 | |
| 	 */
 | |
| 	if (boot_cpu_has(X86_FEATURE_APERFMPERF))
 | |
| 		return scale_aperfmperf();
 | |
| 
 | |
| 	/*
 | |
| 	 * maybe have something cpufreq here
 | |
| 	 */
 | |
| 
 | |
| 	return default_scale_freq_power(sd, cpu);
 | |
| }
 | |
| 
 | |
| unsigned long arch_scale_smt_power(struct sched_domain *sd, int cpu)
 | |
| {
 | |
| 	/*
 | |
| 	 * aperf/mperf already includes the smt gain
 | |
| 	 */
 | |
| 	if (boot_cpu_has(X86_FEATURE_APERFMPERF))
 | |
| 		return SCHED_LOAD_SCALE;
 | |
| 
 | |
| 	return default_scale_smt_power(sd, cpu);
 | |
| }
 | |
| 
 | |
| #endif
 |