From nobody Mon Jun 8 05:26:40 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 375282F0C74; Tue, 2 Jun 2026 19:30:22 +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=1780428628; cv=none; b=COr+z0U3zzMuJOyX153ahxgD2PP+9srBW0CQcev00YK1DSeFha1PVnglVV+33lRYv+c4nI8awz/wAWkDlE1ob55cbad6rLwRNT+Jk5btopyIJMUQnAMRAd6/rVhXr7xGmSjmLYLbW8FdKIV4VlDnVOpQ+LLm76UAkMgK9eco/KM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780428628; c=relaxed/simple; bh=JRf2Rg/ixz1h+w4NJ9A1Zpo1zXbrZntOIBT4kP0mivQ=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=YbKKydihVs/k5P06NuHWhuirSJ3RyHcbIMYGI3RR13L8dqv1yeA1UeDnSOvDI0li/4L/EcAO1A3uwNYYCzedA5drPAOD66j7e2cuwF+/bsMJ3tDXD+iTLa0O36WoPYnvh0jH9ps7QN9slNQHaTvnlqXtYBfYa4LQvaet0lYTbHI= 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=BtuRMHcR; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=50N96JR0; 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="BtuRMHcR"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="50N96JR0" Date: Tue, 02 Jun 2026 19:30:19 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1780428621; 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=qbcQ2JmaaJ6UPRHVW6xsvSTtjjfcrlmEGK3CQz+tDMA=; b=BtuRMHcRu1uvB2lPyXfQDO3F4dywlnSPU3MZNACALSvhKfdiSUcOJf9xxm03qh1zYjACLp EgoiQ4cEOFrWmVJE+bWd6dKPDBbRC8hDFhk4kaXgj3nPGpg+44r1wxfka5WPGLHQ+zV3Yq Sz6GoER5UyosWe0Bcvhojm6gQjtXX5T0qPaAjJzDFYfx9p2rqTdRyAG3S9Txw5vBVUmrru AZtVaFlXsMxVDlZiOjd3jocUIZc0xwMI0AJxIEnVrxx7dRtaE4QvxsRAWhzqGkW37gRC4e 83Yr6c1TS4L3jjGygCsP/PzhWGLcKZGB2O1ycaP0Pao264Ah4VC0Vtcz0HvC/Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1780428621; 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=qbcQ2JmaaJ6UPRHVW6xsvSTtjjfcrlmEGK3CQz+tDMA=; b=50N96JR0H2jd6vW4Ub5KZluEnrNIqycf02a2Mpp3LlsAfZBXnJqP6Onenk43jq7j6qAxuA GNQDmwUToODoM8Cw== 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: Correctly support generic vtime idle time Cc: Frederic Weisbecker , Thomas Gleixner , Shrikanth Hegde , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20260508131647.43868-5-frederic@kernel.org> References: <20260508131647.43868-5-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: <178042861946.710.10395918539775026192.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: 650a59805a9baeff76379ea9309df1395eb15a46 Gitweb: https://git.kernel.org/tip/650a59805a9baeff76379ea9309df1395= eb15a46 Author: Frederic Weisbecker AuthorDate: Fri, 08 May 2026 15:16:36 +02:00 Committer: Thomas Gleixner CommitterDate: Tue, 02 Jun 2026 21:27:25 +02:00 sched/cputime: Correctly support generic vtime idle time Currently whether generic vtime is running or not, the idle cputime is fetched from the nohz accounting. However generic vtime already does its own idle cputime accounting. Only the kernel stat accessors are not plugged to support it. Read the idle generic vtime cputime when it's running, this will allow to later more clearly split nohz and vtime cputime accounting. Signed-off-by: Frederic Weisbecker Signed-off-by: Thomas Gleixner Tested-by: Shrikanth Hegde Link: https://patch.msgid.link/20260508131647.43868-5-frederic@kernel.org --- include/linux/vtime.h | 9 +++++++-- kernel/sched/cputime.c | 38 +++++++++++++++++++++++++++++--------- kernel/time/tick-sched.c | 12 +++++++++--- 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/include/linux/vtime.h b/include/linux/vtime.h index 29dd5b9..336875b 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h @@ -10,7 +10,6 @@ */ #ifdef CONFIG_VIRT_CPU_ACCOUNTING extern void vtime_account_kernel(struct task_struct *tsk); -extern void vtime_account_idle(struct task_struct *tsk); #endif /* !CONFIG_VIRT_CPU_ACCOUNTING */ =20 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN @@ -27,7 +26,13 @@ static inline void vtime_guest_exit(struct task_struct *= tsk) { } static inline void vtime_init_idle(struct task_struct *tsk, int cpu) { } #endif =20 +static inline bool vtime_generic_enabled_cpu(int cpu) +{ + return context_tracking_enabled_cpu(cpu); +} + #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE +extern void vtime_account_idle(struct task_struct *tsk); extern void vtime_account_irq(struct task_struct *tsk, unsigned int offset= ); extern void vtime_account_softirq(struct task_struct *tsk); extern void vtime_account_hardirq(struct task_struct *tsk); @@ -74,7 +79,7 @@ static inline bool vtime_accounting_enabled(void) =20 static inline bool vtime_accounting_enabled_cpu(int cpu) { - return context_tracking_enabled_cpu(cpu); + return vtime_generic_enabled_cpu(cpu); } =20 static inline bool vtime_accounting_enabled_this_cpu(void) diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index caaaf0a..815d0f7 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -773,9 +773,9 @@ void vtime_guest_exit(struct task_struct *tsk) } EXPORT_SYMBOL_GPL(vtime_guest_exit); =20 -void vtime_account_idle(struct task_struct *tsk) +static void __vtime_account_idle(struct vtime *vtime) { - account_idle_time(get_vtime_delta(&tsk->vtime)); + account_idle_time(get_vtime_delta(vtime)); } =20 void vtime_task_switch_generic(struct task_struct *prev) @@ -784,7 +784,7 @@ void vtime_task_switch_generic(struct task_struct *prev) =20 write_seqcount_begin(&vtime->seqcount); if (vtime->state =3D=3D VTIME_IDLE) - vtime_account_idle(prev); + __vtime_account_idle(vtime); else __vtime_account_kernel(prev, vtime); vtime->state =3D VTIME_INACTIVE; @@ -926,6 +926,7 @@ static int kcpustat_field_vtime(u64 *cpustat, int cpu, u64 *val) { struct vtime *vtime =3D &tsk->vtime; + struct rq *rq =3D cpu_rq(cpu); unsigned int seq; =20 do { @@ -967,6 +968,14 @@ static int kcpustat_field_vtime(u64 *cpustat, if (state =3D=3D VTIME_GUEST && task_nice(tsk) > 0) *val +=3D vtime->gtime + vtime_delta(vtime); break; + case CPUTIME_IDLE: + if (state =3D=3D VTIME_IDLE && !atomic_read(&rq->nr_iowait)) + *val +=3D vtime_delta(vtime); + break; + case CPUTIME_IOWAIT: + if (state =3D=3D VTIME_IDLE && atomic_read(&rq->nr_iowait) > 0) + *val +=3D vtime_delta(vtime); + break; default: break; } @@ -1029,8 +1038,8 @@ static int kcpustat_cpu_fetch_vtime(struct kernel_cpu= stat *dst, *dst =3D *src; cpustat =3D dst->cpustat; =20 - /* Task is sleeping, dead or idle, nothing to add */ - if (state < VTIME_SYS) + /* Task is sleeping or dead, nothing to add */ + if (state < VTIME_IDLE) continue; =20 delta =3D vtime_delta(vtime); @@ -1039,15 +1048,17 @@ static int kcpustat_cpu_fetch_vtime(struct kernel_c= pustat *dst, * Task runs either in user (including guest) or kernel space, * add pending nohz time to the right place. */ - if (state =3D=3D VTIME_SYS) { + switch (state) { + case VTIME_SYS: cpustat[CPUTIME_SYSTEM] +=3D vtime->stime + delta; - } else if (state =3D=3D VTIME_USER) { + break; + case VTIME_USER: if (task_nice(tsk) > 0) cpustat[CPUTIME_NICE] +=3D vtime->utime + delta; else cpustat[CPUTIME_USER] +=3D vtime->utime + delta; - } else { - WARN_ON_ONCE(state !=3D VTIME_GUEST); + break; + case VTIME_GUEST: if (task_nice(tsk) > 0) { cpustat[CPUTIME_GUEST_NICE] +=3D vtime->gtime + delta; cpustat[CPUTIME_NICE] +=3D vtime->gtime + delta; @@ -1055,6 +1066,15 @@ static int kcpustat_cpu_fetch_vtime(struct kernel_cp= ustat *dst, cpustat[CPUTIME_GUEST] +=3D vtime->gtime + delta; cpustat[CPUTIME_USER] +=3D vtime->gtime + delta; } + break; + case VTIME_IDLE: + if (atomic_read(&cpu_rq(cpu)->nr_iowait) > 0) + cpustat[CPUTIME_IOWAIT] +=3D delta; + else + cpustat[CPUTIME_IDLE] +=3D delta; + break; + default: + WARN_ON_ONCE(1); } } while (read_seqcount_retry(&vtime->seqcount, seq)); =20 diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 1713933..597c3a0 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -783,9 +783,10 @@ static void tick_nohz_start_idle(struct tick_sched *ts) sched_clock_idle_sleep_event(); } =20 -static u64 get_cpu_sleep_time_us(struct tick_sched *ts, ktime_t *sleeptime, +static u64 get_cpu_sleep_time_us(int cpu, enum cpu_usage_stat idx, ktime_t= *sleeptime, bool compute_delta, u64 *last_update_time) { + struct tick_sched *ts =3D &per_cpu(tick_cpu_sched, cpu); ktime_t now, idle; unsigned int seq; =20 @@ -796,6 +797,11 @@ static u64 get_cpu_sleep_time_us(struct tick_sched *ts= , ktime_t *sleeptime, if (last_update_time) *last_update_time =3D ktime_to_us(now); =20 + if (vtime_generic_enabled_cpu(cpu)) { + idle =3D kcpustat_field(idx, cpu); + return ktime_to_us(idle); + } + do { ktime_t delta =3D 0; =20 @@ -834,7 +840,7 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) { struct tick_sched *ts =3D &per_cpu(tick_cpu_sched, cpu); =20 - return get_cpu_sleep_time_us(ts, &ts->idle_sleeptime, + return get_cpu_sleep_time_us(cpu, CPUTIME_IDLE, &ts->idle_sleeptime, !nr_iowait_cpu(cpu), last_update_time); } EXPORT_SYMBOL_GPL(get_cpu_idle_time_us); @@ -860,7 +866,7 @@ u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_ti= me) { struct tick_sched *ts =3D &per_cpu(tick_cpu_sched, cpu); =20 - return get_cpu_sleep_time_us(ts, &ts->iowait_sleeptime, + return get_cpu_sleep_time_us(cpu, CPUTIME_IOWAIT, &ts->iowait_sleeptime, nr_iowait_cpu(cpu), last_update_time); } EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us);