From nobody Mon Jun 8 05:26:39 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 476BC3D667B; Tue, 2 Jun 2026 19:30:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780428607; cv=none; b=YC/Shgjk+FIEChLLhr16+fQgt/D0HCNjcjXfDFMOZTnyus3qrNJdccQd4r+tFTYKNce2kKrkoKyPgb2Wz/dotbAjBhknB36FjrrtCM41Ki58hiOkdlUsCjr0TYkaWgi1XXk/eGaYoQM6XqcyhZ51mKvQ7NdGfkgFajiPNWEPqHk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780428607; c=relaxed/simple; bh=OP0BZl71yPfoRyz5SWKdKRUuPqJrWGYqt8SO+PmwUNY=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=FpkcMdBdJt0UhfxqzGEMBf+7YVkB2gSTRlAXVe/ArmieNAJExMLOkI0fi/hG+f4L0KtDRUMsV3pJnYwNo5mHq9FTtSEO5AdT1pGuP9BgsAE1DQTAh5rOopP4lhKkybEIW5PDVEFi+k8X9IQfYP47HPQyHjj1Xx19UqoLJMVImnY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=XFTlFmi4; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=b1DKGxcD; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="XFTlFmi4"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="b1DKGxcD" Date: Tue, 02 Jun 2026 19:30:03 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1780428604; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8DzeZCTkNlbfEGovTi/JuX1NkqYrv4E4Azv7MZRUDwo=; b=XFTlFmi41eJTdYnoe5dCVxnDd+uYLI+Ihnt5Whap+0HLr46MfV/5EOCaODXfTnKhUUEsl0 B2FA510H6Gx2b4HofZ5fbMxRZ9ayiCOgR3x3E4Dl5cBSVqmgAn9Dk8D8CTnXTXwEWn0YPo VkcKGXb2r9gkgxPD+02gjmZiXLZp7MfmgcwQ3b+No3spBaAX7vhgBs1z26FWDG36jx2t+k BFRpHZs3p5WuM+kh0YPWZ2Yz1abQ8CvwChEPLKHt17M9Jpo6+8oiPekRB7OjiA1K9K5yIL GLSj25Rx1TwL+iBwVQVs2dMg3JxqkiPgn5Gii8TJ4hloNE6Vthy/Exhckk0cgQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1780428604; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8DzeZCTkNlbfEGovTi/JuX1NkqYrv4E4Azv7MZRUDwo=; b=b1DKGxcDknyfiJEQY5lTV4i6HmGzWceW2u050zr/0M+IhXG3l0q69SNSHoI7CQy/6IdxrR oHF7fEqwxPl8TfAw== From: "tip-bot2 for Frederic Weisbecker" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: timers/nohz] sched/cputime: Handle dyntick-idle steal time correctly Cc: Frederic Weisbecker , Thomas Gleixner , Shrikanth Hegde , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20260508131647.43868-16-frederic@kernel.org> References: <20260508131647.43868-16-frederic@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <178042860321.710.17410796296233941593.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the timers/nohz branch of tip: Commit-ID: 6199f9999a9b62b2b84a1bf5b52a9fd0bb8de5af Gitweb: https://git.kernel.org/tip/6199f9999a9b62b2b84a1bf5b52a9fd0b= b8de5af Author: Frederic Weisbecker AuthorDate: Fri, 08 May 2026 15:16:47 +02:00 Committer: Thomas Gleixner CommitterDate: Tue, 02 Jun 2026 21:27:26 +02:00 sched/cputime: Handle dyntick-idle steal time correctly The dyntick-idle steal time is currently accounted when the tick restarts but the stolen idle time is not subtracted from the idle time that was already accounted. This is to avoid observing the idle time going backward as the dyntick-idle cputime accessors can't reliably know in advance the stolen idle time. In order to maintain a forward progressing idle cputime while subtracting idle steal time from it, keep track of the previously accounted idle stolen time and substract it from _later_ idle cputime accounting. Signed-off-by: Frederic Weisbecker Signed-off-by: Thomas Gleixner Tested-by: Shrikanth Hegde Link: https://patch.msgid.link/20260508131647.43868-16-frederic@kernel.org --- include/linux/kernel_stat.h | 1 + kernel/sched/cputime.c | 28 +++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 512104b..fce1392 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -39,6 +39,7 @@ struct kernel_cpustat { bool idle_elapse; seqcount_t idle_sleeptime_seq; u64 idle_entrytime; + u64 idle_stealtime[2]; #endif u64 cpustat[NR_STATS]; }; diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 94be22a..244b574 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -425,19 +425,32 @@ static inline void irqtime_account_process_tick(struc= t task_struct *p, int user_ static void kcpustat_idle_stop(struct kernel_cpustat *kc, u64 now) { u64 *cpustat =3D kc->cpustat; - u64 delta; + u64 delta, steal, steal_delta; + int iowait; =20 if (!kc->idle_elapse) return; =20 + iowait =3D nr_iowait_cpu(smp_processor_id()) > 0; delta =3D now - kc->idle_entrytime; + steal =3D steal_account_process_time(delta); =20 + /* + * Record the idle time after substracting the steal time from + * previous update sequence. Don't substract the steal time from + * the current update sequence to avoid readers moving backward. + */ write_seqcount_begin(&kc->idle_sleeptime_seq); - if (nr_iowait_cpu(smp_processor_id()) > 0) + steal_delta =3D min_t(u64, kc->idle_stealtime[iowait], delta); + delta -=3D steal_delta; + kc->idle_stealtime[iowait] -=3D steal_delta; + + if (iowait) cpustat[CPUTIME_IOWAIT] +=3D delta; else cpustat[CPUTIME_IDLE] +=3D delta; =20 + kc->idle_stealtime[iowait] +=3D steal; kc->idle_entrytime =3D now; kc->idle_elapse =3D false; write_seqcount_end(&kc->idle_sleeptime_seq); @@ -464,7 +477,6 @@ void kcpustat_dyntick_stop(u64 now) kcpustat_idle_stop(kc, now); kc->idle_dyntick =3D false; vtime_dyntick_stop(); - steal_account_process_time(ULONG_MAX); } } =20 @@ -508,6 +520,7 @@ static u64 kcpustat_field_dyntick(int cpu, enum cpu_usa= ge_stat idx, bool compute_delta, u64 now) { struct kernel_cpustat *kc =3D &kcpustat_cpu(cpu); + int iowait =3D idx =3D=3D CPUTIME_IOWAIT; u64 *cpustat =3D kc->cpustat; unsigned int seq; u64 idle; @@ -516,8 +529,13 @@ static u64 kcpustat_field_dyntick(int cpu, enum cpu_us= age_stat idx, seq =3D read_seqcount_begin(&kc->idle_sleeptime_seq); =20 idle =3D cpustat[idx]; - if (kc->idle_elapse && compute_delta && now > kc->idle_entrytime) - idle +=3D (now - kc->idle_entrytime); + + if (kc->idle_elapse && compute_delta && now > kc->idle_entrytime) { + u64 delta =3D now - kc->idle_entrytime; + + delta -=3D min_t(u64, kc->idle_stealtime[iowait], delta); + idle +=3D delta; + } } while (read_seqcount_retry(&kc->idle_sleeptime_seq, seq)); =20 return idle;