mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	sched/cputime: Fix steal time accounting vs. CPU hotplug
On CPU hotplug the steal time accounting can keep a stale rq->prev_steal_time value over CPU down and up. So after the CPU comes up again the delta calculation in steal_account_process_tick() wreckages itself due to the unsigned math: u64 steal = paravirt_steal_clock(smp_processor_id()); steal -= this_rq()->prev_steal_time; So if steal is smaller than rq->prev_steal_time we end up with an insane large value which then gets added to rq->prev_steal_time, resulting in a permanent wreckage of the accounting. As a consequence the per CPU stats in /proc/stat become stale. Nice trick to tell the world how idle the system is (100%) while the CPU is 100% busy running tasks. Though we prefer realistic numbers. None of the accounting values which use a previous value to account for fractions is reset at CPU hotplug time. update_rq_clock_task() has a sanity check for prev_irq_time and prev_steal_time_rq, but that sanity check solely deals with clock warps and limits the /proc/stat visible wreckage. The prev_time values are still wrong. Solution is simple: Reset rq->prev_*_time when the CPU is plugged in again. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Rik van Riel <riel@redhat.com> Cc: <stable@vger.kernel.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Glauber Costa <glommer@parallels.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Fixes: commit095c0aa83e"sched: adjust scheduler cpu power for stolen time" Fixes: commitaa48380851"sched: Remove irq time from available CPU power" Fixes: commite6e6685acc"KVM guest: Steal time accounting" Link: http://lkml.kernel.org/r/alpine.DEB.2.11.1603041539490.3686@nanos Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
		
							parent
							
								
									48be3a67da
								
							
						
					
					
						commit
						e9532e69b8
					
				
					 2 changed files with 14 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -5627,6 +5627,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
 | 
			
		|||
 | 
			
		||||
	case CPU_UP_PREPARE:
 | 
			
		||||
		rq->calc_load_update = calc_load_update;
 | 
			
		||||
		account_reset_rq(rq);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CPU_ONLINE:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1738,3 +1738,16 @@ static inline u64 irq_time_read(int cpu)
 | 
			
		|||
}
 | 
			
		||||
#endif /* CONFIG_64BIT */
 | 
			
		||||
#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
 | 
			
		||||
 | 
			
		||||
static inline void account_reset_rq(struct rq *rq)
 | 
			
		||||
{
 | 
			
		||||
#ifdef CONFIG_IRQ_TIME_ACCOUNTING
 | 
			
		||||
	rq->prev_irq_time = 0;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CONFIG_PARAVIRT
 | 
			
		||||
	rq->prev_steal_time = 0;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
 | 
			
		||||
	rq->prev_steal_time_rq = 0;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue