diff options
Diffstat (limited to 'arch/arm/kernel/smp.c')
| -rw-r--r-- | arch/arm/kernel/smp.c | 30 | 
1 files changed, 20 insertions, 10 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index facd4240ca02..ebc53804d57b 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -70,6 +70,10 @@ enum ipi_msg_type {  	IPI_CPU_STOP,  	IPI_IRQ_WORK,  	IPI_COMPLETION, +	/* +	 * CPU_BACKTRACE is special and not included in NR_IPI +	 * or tracable with trace_ipi_* +	 */  	IPI_CPU_BACKTRACE,  	/*  	 * SGI8-15 can be reserved by secure firmware, and thus may @@ -754,15 +758,20 @@ static int cpufreq_callback(struct notifier_block *nb,  					unsigned long val, void *data)  {  	struct cpufreq_freqs *freq = data; -	int cpu = freq->cpu; +	struct cpumask *cpus = freq->policy->cpus; +	int cpu, first = cpumask_first(cpus); +	unsigned int lpj;  	if (freq->flags & CPUFREQ_CONST_LOOPS)  		return NOTIFY_OK; -	if (!per_cpu(l_p_j_ref, cpu)) { -		per_cpu(l_p_j_ref, cpu) = -			per_cpu(cpu_data, cpu).loops_per_jiffy; -		per_cpu(l_p_j_ref_freq, cpu) = freq->old; +	if (!per_cpu(l_p_j_ref, first)) { +		for_each_cpu(cpu, cpus) { +			per_cpu(l_p_j_ref, cpu) = +				per_cpu(cpu_data, cpu).loops_per_jiffy; +			per_cpu(l_p_j_ref_freq, cpu) = freq->old; +		} +  		if (!global_l_p_j_ref) {  			global_l_p_j_ref = loops_per_jiffy;  			global_l_p_j_ref_freq = freq->old; @@ -774,10 +783,11 @@ static int cpufreq_callback(struct notifier_block *nb,  		loops_per_jiffy = cpufreq_scale(global_l_p_j_ref,  						global_l_p_j_ref_freq,  						freq->new); -		per_cpu(cpu_data, cpu).loops_per_jiffy = -			cpufreq_scale(per_cpu(l_p_j_ref, cpu), -					per_cpu(l_p_j_ref_freq, cpu), -					freq->new); + +		lpj = cpufreq_scale(per_cpu(l_p_j_ref, first), +				    per_cpu(l_p_j_ref_freq, first), freq->new); +		for_each_cpu(cpu, cpus) +			per_cpu(cpu_data, cpu).loops_per_jiffy = lpj;  	}  	return NOTIFY_OK;  } @@ -797,7 +807,7 @@ core_initcall(register_cpufreq_notifier);  static void raise_nmi(cpumask_t *mask)  { -	smp_cross_call(mask, IPI_CPU_BACKTRACE); +	__smp_cross_call(mask, IPI_CPU_BACKTRACE);  }  void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)  |