forked from mirrors/linux
		
	ACPI: processor: Use CPUIDLE_FLAG_TIMER_STOP
Make acpi_processor_idle use the common broadcast code, there's no reason not to. This also removes some RCU usage after rcu_idle_enter(). Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reported-by: Borislav Petkov <bp@suse.de> Tested-by: Borislav Petkov <bp@suse.de> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
		
							parent
							
								
									856deb866d
								
							
						
					
					
						commit
						aa6b43d57f
					
				
					 1 changed files with 15 additions and 32 deletions
				
			
		|  | @ -161,18 +161,10 @@ static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Power(C) State timer broadcast control */ | /* Power(C) State timer broadcast control */ | ||||||
| static void lapic_timer_state_broadcast(struct acpi_processor *pr, | static bool lapic_timer_needs_broadcast(struct acpi_processor *pr, | ||||||
| 				       struct acpi_processor_cx *cx, | 					struct acpi_processor_cx *cx) | ||||||
| 				       int broadcast) |  | ||||||
| { | { | ||||||
| 	int state = cx - pr->power.states; | 	return cx - pr->power.states >= pr->power.timer_broadcast_on_state; | ||||||
| 
 |  | ||||||
| 	if (state >= pr->power.timer_broadcast_on_state) { |  | ||||||
| 		if (broadcast) |  | ||||||
| 			tick_broadcast_enter(); |  | ||||||
| 		else |  | ||||||
| 			tick_broadcast_exit(); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #else | #else | ||||||
|  | @ -180,9 +172,9 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr, | ||||||
| static void lapic_timer_check_state(int state, struct acpi_processor *pr, | static void lapic_timer_check_state(int state, struct acpi_processor *pr, | ||||||
| 				   struct acpi_processor_cx *cstate) { } | 				   struct acpi_processor_cx *cstate) { } | ||||||
| static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { } | static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { } | ||||||
| static void lapic_timer_state_broadcast(struct acpi_processor *pr, | 
 | ||||||
| 				       struct acpi_processor_cx *cx, | static bool lapic_timer_needs_broadcast(struct acpi_processor *pr, | ||||||
| 				       int broadcast) | 					struct acpi_processor_cx *cx) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -568,20 +560,12 @@ static DEFINE_RAW_SPINLOCK(c3_lock); | ||||||
|  * acpi_idle_enter_bm - enters C3 with proper BM handling |  * acpi_idle_enter_bm - enters C3 with proper BM handling | ||||||
|  * @pr: Target processor |  * @pr: Target processor | ||||||
|  * @cx: Target state context |  * @cx: Target state context | ||||||
|  * @timer_bc: Whether or not to change timer mode to broadcast |  | ||||||
|  */ |  */ | ||||||
| static void acpi_idle_enter_bm(struct acpi_processor *pr, | static void acpi_idle_enter_bm(struct acpi_processor *pr, | ||||||
| 			       struct acpi_processor_cx *cx, bool timer_bc) | 			       struct acpi_processor_cx *cx) | ||||||
| { | { | ||||||
| 	acpi_unlazy_tlb(smp_processor_id()); | 	acpi_unlazy_tlb(smp_processor_id()); | ||||||
| 
 | 
 | ||||||
| 	/*
 |  | ||||||
| 	 * Must be done before busmaster disable as we might need to |  | ||||||
| 	 * access HPET ! |  | ||||||
| 	 */ |  | ||||||
| 	if (timer_bc) |  | ||||||
| 		lapic_timer_state_broadcast(pr, cx, 1); |  | ||||||
| 
 |  | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * disable bus master | 	 * disable bus master | ||||||
| 	 * bm_check implies we need ARB_DIS | 	 * bm_check implies we need ARB_DIS | ||||||
|  | @ -609,9 +593,6 @@ static void acpi_idle_enter_bm(struct acpi_processor *pr, | ||||||
| 		c3_cpu_count--; | 		c3_cpu_count--; | ||||||
| 		raw_spin_unlock(&c3_lock); | 		raw_spin_unlock(&c3_lock); | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	if (timer_bc) |  | ||||||
| 		lapic_timer_state_broadcast(pr, cx, 0); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int acpi_idle_enter(struct cpuidle_device *dev, | static int acpi_idle_enter(struct cpuidle_device *dev, | ||||||
|  | @ -630,7 +611,7 @@ static int acpi_idle_enter(struct cpuidle_device *dev, | ||||||
| 			cx = per_cpu(acpi_cstate[index], dev->cpu); | 			cx = per_cpu(acpi_cstate[index], dev->cpu); | ||||||
| 		} else if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check) { | 		} else if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check) { | ||||||
| 			if (cx->bm_sts_skip || !acpi_idle_bm_check()) { | 			if (cx->bm_sts_skip || !acpi_idle_bm_check()) { | ||||||
| 				acpi_idle_enter_bm(pr, cx, true); | 				acpi_idle_enter_bm(pr, cx); | ||||||
| 				return index; | 				return index; | ||||||
| 			} else if (drv->safe_state_index >= 0) { | 			} else if (drv->safe_state_index >= 0) { | ||||||
| 				index = drv->safe_state_index; | 				index = drv->safe_state_index; | ||||||
|  | @ -642,15 +623,11 @@ static int acpi_idle_enter(struct cpuidle_device *dev, | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	lapic_timer_state_broadcast(pr, cx, 1); |  | ||||||
| 
 |  | ||||||
| 	if (cx->type == ACPI_STATE_C3) | 	if (cx->type == ACPI_STATE_C3) | ||||||
| 		ACPI_FLUSH_CPU_CACHE(); | 		ACPI_FLUSH_CPU_CACHE(); | ||||||
| 
 | 
 | ||||||
| 	acpi_idle_do_entry(cx); | 	acpi_idle_do_entry(cx); | ||||||
| 
 | 
 | ||||||
| 	lapic_timer_state_broadcast(pr, cx, 0); |  | ||||||
| 
 |  | ||||||
| 	return index; | 	return index; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -666,7 +643,7 @@ static int acpi_idle_enter_s2idle(struct cpuidle_device *dev, | ||||||
| 			return 0; | 			return 0; | ||||||
| 
 | 
 | ||||||
| 		if (pr->flags.bm_check) { | 		if (pr->flags.bm_check) { | ||||||
| 			acpi_idle_enter_bm(pr, cx, false); | 			acpi_idle_enter_bm(pr, cx); | ||||||
| 			return 0; | 			return 0; | ||||||
| 		} else { | 		} else { | ||||||
| 			ACPI_FLUSH_CPU_CACHE(); | 			ACPI_FLUSH_CPU_CACHE(); | ||||||
|  | @ -682,6 +659,7 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, | ||||||
| { | { | ||||||
| 	int i, count = ACPI_IDLE_STATE_START; | 	int i, count = ACPI_IDLE_STATE_START; | ||||||
| 	struct acpi_processor_cx *cx; | 	struct acpi_processor_cx *cx; | ||||||
|  | 	struct cpuidle_state *state; | ||||||
| 
 | 
 | ||||||
| 	if (max_cstate == 0) | 	if (max_cstate == 0) | ||||||
| 		max_cstate = 1; | 		max_cstate = 1; | ||||||
|  | @ -694,6 +672,11 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, | ||||||
| 
 | 
 | ||||||
| 		per_cpu(acpi_cstate[count], dev->cpu) = cx; | 		per_cpu(acpi_cstate[count], dev->cpu) = cx; | ||||||
| 
 | 
 | ||||||
|  | 		if (lapic_timer_needs_broadcast(pr, cx)) { | ||||||
|  | 			state = &acpi_idle_driver.states[count]; | ||||||
|  | 			state->flags |= CPUIDLE_FLAG_TIMER_STOP; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		count++; | 		count++; | ||||||
| 		if (count == CPUIDLE_STATE_MAX) | 		if (count == CPUIDLE_STATE_MAX) | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Peter Zijlstra
						Peter Zijlstra