Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2218143/?format=api
{ "id": 2218143, "url": "http://patchwork.ozlabs.org/api/patches/2218143/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20260331131622.30505-7-frederic@kernel.org/", "project": { "id": 2, "url": "http://patchwork.ozlabs.org/api/projects/2/?format=api", "name": "Linux PPC development", "link_name": "linuxppc-dev", "list_id": "linuxppc-dev.lists.ozlabs.org", "list_email": "linuxppc-dev@lists.ozlabs.org", "web_url": "https://github.com/linuxppc/wiki/wiki", "scm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git", "webscm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/", "list_archive_url": "https://lore.kernel.org/linuxppc-dev/", "list_archive_url_format": "https://lore.kernel.org/linuxppc-dev/{}/", "commit_url_format": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id={}" }, "msgid": "<20260331131622.30505-7-frederic@kernel.org>", "list_archive_url": "https://lore.kernel.org/linuxppc-dev/20260331131622.30505-7-frederic@kernel.org/", "date": "2026-03-31T13:16:14", "name": "[06/14] tick/sched: Unify idle cputime accounting", "commit_ref": null, "pull_url": null, "state": "handled-elsewhere", "archived": false, "hash": "7b42c54fe0910e0d011c27d5dceea0163ee882ac", "submitter": { "id": 79411, "url": "http://patchwork.ozlabs.org/api/people/79411/?format=api", "name": "Frederic Weisbecker", "email": "frederic@kernel.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20260331131622.30505-7-frederic@kernel.org/mbox/", "series": [ { "id": 498198, "url": "http://patchwork.ozlabs.org/api/series/498198/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=498198", "date": "2026-03-31T13:16:08", "name": "tick/sched: Refactor idle cputime accounting", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/498198/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2218143/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2218143/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linuxppc-dev+bounces-19086-incoming=patchwork.ozlabs.org@lists.ozlabs.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linuxppc-dev@lists.ozlabs.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=NjGfNqTY;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org\n (client-ip=2404:9400:21b9:f100::1; helo=lists.ozlabs.org;\n envelope-from=linuxppc-dev+bounces-19086-incoming=patchwork.ozlabs.org@lists.ozlabs.org;\n receiver=patchwork.ozlabs.org)", "lists.ozlabs.org;\n arc=none smtp.remote-ip=172.234.252.31", "lists.ozlabs.org;\n dmarc=pass (p=quarantine dis=none) header.from=kernel.org", "lists.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=NjGfNqTY;\n\tdkim-atps=neutral", "lists.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=kernel.org\n (client-ip=172.234.252.31; helo=sea.source.kernel.org;\n envelope-from=frederic@kernel.org; receiver=lists.ozlabs.org)" ], "Received": [ "from lists.ozlabs.org (lists.ozlabs.org\n [IPv6:2404:9400:21b9:f100::1])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4flTDd6tpwz1y1q\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 01 Apr 2026 00:17:21 +1100 (AEDT)", "from boromir.ozlabs.org (localhost [127.0.0.1])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 4flTDc2yZXz2ytV;\n\tWed, 01 Apr 2026 00:17:20 +1100 (AEDT)", "from sea.source.kernel.org (sea.source.kernel.org [172.234.252.31])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 4flTDb2wR1z2ydn\n\tfor <linuxppc-dev@lists.ozlabs.org>; Wed, 01 Apr 2026 00:17:19 +1100 (AEDT)", "from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58])\n\tby sea.source.kernel.org (Postfix) with ESMTP id D0BBA4180F;\n\tTue, 31 Mar 2026 13:17:17 +0000 (UTC)", "by smtp.kernel.org (Postfix) with ESMTPSA id BADD9C2BCB1;\n\tTue, 31 Mar 2026 13:17:10 +0000 (UTC)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1774963040;\n\tcv=none;\n b=JLm+HmTTmjElyCPg7yLOLGgGFd9dco0NmcC2ksYhA7PCJ3dswYyI1jVagIv3JZcaERGKkzjjgknzwTwTYc9e9yhgvaoMVvnvL6RolkoGxhHCNnBixvCNo/c2nCxmeb3AoWeGT7DYlLCkmnRSP3LnzmM+8i+2R7Pu0q08Yfds8OWVpPYiBCMwGK7F9dPO1YJg5PUoOxlGV8r2nDNkICqtMLXQIz/k6/wQQo6zQuCqKpHUTPVrdjLWVtNAOO/cOfqWe3obRIPg1NzB1Mx7+3qBpf+vdiiaLuKKqrXaWyF92/t8i4hSM5I3R/5sumNZo6MUGVQIENPBih/rqR4xUPvLgg==", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707;\n\tt=1774963040; c=relaxed/relaxed;\n\tbh=V3ke19NAnbK5AdV/EHO0kJITUbwhfRYxnEMspT8Zi20=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=GGRak1PZPtehNooGkva6IXdLkC8n3YWnRNxGIXj2l39T/6OyAeXaZOu0XKVIrafpZrayQjvhHcN9cHrMpgaclaYrvqod1cgE5HUi9NXAG78vZTVHD9xGiDpne+6pC1JWZbNs2bL3obBYKA/ikzNQjHegw6wUdjyho5ta1/0M49ikoM24hNVTm0kCPsjAkQTSSMswK8TvtpiFI3sj0dZ73nwphHE7vMdB7a1pgXzCno2A81l60GSiSxSLcjG9AcH4fwdMOoXiIxUZGWgJdLQWR+OmYSVGgzwVSaCZ3T+unhLMil8LALEAoX/chfI2cXD45gcMiJv0dIA+H2nzvz2CNQ==", "ARC-Authentication-Results": "i=1; lists.ozlabs.org;\n dmarc=pass (p=quarantine dis=none) header.from=kernel.org;\n dkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=NjGfNqTY; dkim-atps=neutral;\n spf=pass (client-ip=172.234.252.31; helo=sea.source.kernel.org;\n envelope-from=frederic@kernel.org;\n receiver=lists.ozlabs.org) smtp.mailfrom=kernel.org", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1774963037;\n\tbh=V9WWlCuXZNggckfE8ISKLn5MtYlSjxloP98rAv/GZCY=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=NjGfNqTYHCzBAhZNeQV9Q40UUniXY9uuLVdzLWvSMLMhbRugEjhJu3ils32yJw5RF\n\t N5PuQTzAZCRY+T199jKi2tftd+yEar6O1Zioy65RHqDYV9dSBaIbnQXMl5bqyREhsz\n\t L1LScojWu7ea7BokCXuN/GiLarxuj60oYAta4orXHXQnoOdpE0F4FLG+QRUSm2SAek\n\t Bye+xyVm7XAngDFlfXQ/XtcsmKrUgOJMh9prUycIjBkE9zoFoSf7yQieM2kVXLHp1R\n\t UUPXnxVn3Mco7OT5dXtCysFDsvgQnXH+QRKIUv9Q4df2c5bHrhrVXYP2uQE/pEvk3c\n\t 7df93M7DZPsIg==", "From": "Frederic Weisbecker <frederic@kernel.org>", "To": "LKML <linux-kernel@vger.kernel.org>", "Cc": "Frederic Weisbecker <frederic@kernel.org>,\n\t\"Christophe Leroy (CS GROUP)\" <chleroy@kernel.org>,\n\t\"Rafael J. Wysocki\" <rafael@kernel.org>,\n\tAlexander Gordeev <agordeev@linux.ibm.com>,\n\tAnna-Maria Behnsen <anna-maria@linutronix.de>,\n\tBen Segall <bsegall@google.com>,\n\tBoqun Feng <boqun.feng@gmail.com>,\n\tChristian Borntraeger <borntraeger@linux.ibm.com>,\n\tDietmar Eggemann <dietmar.eggemann@arm.com>,\n\tHeiko Carstens <hca@linux.ibm.com>,\n\tIngo Molnar <mingo@redhat.com>,\n\tJan Kiszka <jan.kiszka@siemens.com>,\n\tJoel Fernandes <joelagnelf@nvidia.com>,\n\tJuri Lelli <juri.lelli@redhat.com>,\n\tKieran Bingham <kbingham@kernel.org>,\n\tMadhavan Srinivasan <maddy@linux.ibm.com>,\n\tMel Gorman <mgorman@suse.de>,\n\tMichael Ellerman <mpe@ellerman.id.au>,\n\tNeeraj Upadhyay <neeraj.upadhyay@kernel.org>,\n\tNicholas Piggin <npiggin@gmail.com>,\n\t\"Paul E . McKenney\" <paulmck@kernel.org>,\n\tPeter Zijlstra <peterz@infradead.org>,\n\tShrikanth Hegde <sshegde@linux.ibm.com>,\n\tSteven Rostedt <rostedt@goodmis.org>,\n\tSven Schnelle <svens@linux.ibm.com>,\n\tThomas Gleixner <tglx@linutronix.de>,\n\tUladzislau Rezki <urezki@gmail.com>,\n\tValentin Schneider <vschneid@redhat.com>,\n\tVasily Gorbik <gor@linux.ibm.com>,\n\tVincent Guittot <vincent.guittot@linaro.org>,\n\tViresh Kumar <viresh.kumar@linaro.org>,\n\tXin Zhao <jackzxcui1989@163.com>,\n\tlinux-pm@vger.kernel.org,\n\tlinux-s390@vger.kernel.org,\n\tlinuxppc-dev@lists.ozlabs.org", "Subject": "[PATCH 06/14] tick/sched: Unify idle cputime accounting", "Date": "Tue, 31 Mar 2026 15:16:14 +0200", "Message-ID": "<20260331131622.30505-7-frederic@kernel.org>", "X-Mailer": "git-send-email 2.53.0", "In-Reply-To": "<20260331131622.30505-1-frederic@kernel.org>", "References": "<20260331131622.30505-1-frederic@kernel.org>", "X-Mailing-List": "linuxppc-dev@lists.ozlabs.org", "List-Id": "<linuxppc-dev.lists.ozlabs.org>", "List-Help": "<mailto:linuxppc-dev+help@lists.ozlabs.org>", "List-Owner": "<mailto:linuxppc-dev+owner@lists.ozlabs.org>", "List-Post": "<mailto:linuxppc-dev@lists.ozlabs.org>", "List-Archive": "<https://lore.kernel.org/linuxppc-dev/>,\n <https://lists.ozlabs.org/pipermail/linuxppc-dev/>", "List-Subscribe": "<mailto:linuxppc-dev+subscribe@lists.ozlabs.org>,\n <mailto:linuxppc-dev+subscribe-digest@lists.ozlabs.org>,\n <mailto:linuxppc-dev+subscribe-nomail@lists.ozlabs.org>", "List-Unsubscribe": "<mailto:linuxppc-dev+unsubscribe@lists.ozlabs.org>", "Precedence": "list", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-Spam-Status": "No, score=-0.2 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED,\n\tDKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS\n\tautolearn=disabled version=4.0.1 OzLabs 8", "X-Spam-Checker-Version": "SpamAssassin 4.0.1 (2024-03-25) on lists.ozlabs.org" }, "content": "The non-vtime dynticks-idle cputime accounting is a big mess that\naccumulates within two concurrent statistics, each having their own\nshortcomings:\n\n* The accounting for online CPUs which is based on the delta between\n tick_nohz_start_idle() and tick_nohz_stop_idle().\n\n Pros:\n - Works when the tick is off\n\n - Has nsecs granularity\n\n Cons:\n - Account idle steal time but doesn't substract it from idle\n cputime.\n\n - Assumes CONFIG_IRQ_TIME_ACCOUNTING by not accounting IRQs but\n the IRQ time is simply ignored when\n CONFIG_IRQ_TIME_ACCOUNTING=n\n\n - The windows between 1) idle task scheduling and the first call\n to tick_nohz_start_idle() and 2) idle task between the last\n tick_nohz_stop_idle() and the rest of the idle time are\n blindspots wrt. cputime accounting (though mostly insignificant\n amount)\n\n - Relies on private fields outside of kernel stats, with specific\n accessors.\n\n* The accounting for offline CPUs which is based on ticks and the\n jiffies delta during which the tick was stopped.\n\n Pros:\n - Handles steal time correctly\n\n - Handle CONFIG_IRQ_TIME_ACCOUNTING=y and\n CONFIG_IRQ_TIME_ACCOUNTING=n correctly.\n\n - Handles the whole idle task\n\n - Accounts directly to kernel stats, without midlayer accumulator.\n\n Cons:\n - Doesn't elapse when the tick is off, which doesn't make it\n suitable for online CPUs.\n\n - Has TICK_NSEC granularity (jiffies)\n\n - Needs to track the dyntick-idle ticks that were accounted and\n substract them from the total jiffies time spent while the tick\n was stopped. This is an ugly workaround.\n\nHaving two different accounting for a single context is not the only\nproblem: since those accountings are of different natures, it is\npossible to observe the global idle time going backward after a CPU goes\noffline.\n\nClean up the situation with introducing a hybrid approach that stays\ncoherent and works for both online and offline CPUs:\n\n* Tick based or native vtime accounting operate before the idle loop\n is entered and resume once the idle loop prepares to exit.\n\n* When the idle loop starts, switch to dynticks-idle accounting as is\n done currently, except that the statistics accumulate directly to the\n relevant kernel stat fields.\n\n* Private dyntick cputime accounting fields are removed.\n\n* Works on both online and offline case.\n\nFurther improvement will include:\n\n* Only switch to dynticks-idle cputime accounting when the tick actually\n goes in dynticks mode.\n\n* Handle CONFIG_IRQ_TIME_ACCOUNTING=n correctly such that the\n dynticks-idle accounting still elapses while on IRQs.\n\n* Correctly substract idle steal cputime from idle time\n\nReported-by: Xin Zhao <jackzxcui1989@163.com>\nSigned-off-by: Frederic Weisbecker <frederic@kernel.org>\nTested-by: Shrikanth Hegde <sshegde@linux.ibm.com>\n---\n include/linux/kernel_stat.h | 24 ++++++++++---\n include/linux/vtime.h | 7 +++-\n kernel/sched/cputime.c | 62 ++++++++++++++++----------------\n kernel/time/tick-sched.c | 71 +++++++++++--------------------------\n 4 files changed, 76 insertions(+), 88 deletions(-)", "diff": "diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h\nindex dd020ecaf67b..ba65aad308a1 100644\n--- a/include/linux/kernel_stat.h\n+++ b/include/linux/kernel_stat.h\n@@ -34,6 +34,9 @@ enum cpu_usage_stat {\n };\n \n struct kernel_cpustat {\n+#ifdef CONFIG_NO_HZ_COMMON\n+\tint idle_dyntick;\n+#endif\n \tu64 cpustat[NR_STATS];\n };\n \n@@ -99,6 +102,20 @@ static inline unsigned long kstat_cpu_irqs_sum(unsigned int cpu)\n \treturn kstat_cpu(cpu).irqs_sum;\n }\n \n+#ifdef CONFIG_NO_HZ_COMMON\n+extern void kcpustat_dyntick_start(void);\n+extern void kcpustat_dyntick_stop(void);\n+static inline bool kcpustat_idle_dyntick(void)\n+{\n+\treturn __this_cpu_read(kernel_cpustat.idle_dyntick);\n+}\n+#else\n+static inline bool kcpustat_idle_dyntick(void)\n+{\n+\treturn false;\n+}\n+#endif /* CONFIG_NO_HZ_COMMON */\n+\n #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN\n extern u64 kcpustat_field(enum cpu_usage_stat usage, int cpu);\n extern void kcpustat_cpu_fetch(struct kernel_cpustat *dst, int cpu);\n@@ -113,7 +130,7 @@ static inline void kcpustat_cpu_fetch(struct kernel_cpustat *dst, int cpu)\n \t*dst = kcpustat_cpu(cpu);\n }\n \n-#endif\n+#endif /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN */\n \n extern void account_user_time(struct task_struct *, u64);\n extern void account_guest_time(struct task_struct *, u64);\n@@ -127,14 +144,13 @@ extern u64 get_idle_time(struct kernel_cpustat *kcs, int cpu);\n #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE\n static inline void account_process_tick(struct task_struct *tsk, int user)\n {\n-\tvtime_flush(tsk);\n+\tif (!kcpustat_idle_dyntick())\n+\t\tvtime_flush(tsk);\n }\n #else\n extern void account_process_tick(struct task_struct *, int user);\n #endif\n \n-extern void account_idle_ticks(unsigned long ticks);\n-\n #ifdef CONFIG_SCHED_CORE\n extern void __account_forceidle_time(struct task_struct *tsk, u64 delta);\n #endif\ndiff --git a/include/linux/vtime.h b/include/linux/vtime.h\nindex 61b94c12d7dd..a4506336002d 100644\n--- a/include/linux/vtime.h\n+++ b/include/linux/vtime.h\n@@ -31,6 +31,11 @@ static inline bool vtime_generic_enabled_cpu(int cpu)\n \treturn context_tracking_enabled_cpu(cpu);\n }\n \n+static inline bool vtime_generic_enabled_this_cpu(void)\n+{\n+\treturn context_tracking_enabled_this_cpu();\n+}\n+\n #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE\n extern void vtime_account_idle(struct task_struct *tsk);\n extern void vtime_account_irq(struct task_struct *tsk, unsigned int offset);\n@@ -90,7 +95,7 @@ static inline bool vtime_accounting_enabled_cpu(int cpu)\n \n static inline bool vtime_accounting_enabled_this_cpu(void)\n {\n-\treturn context_tracking_enabled_this_cpu();\n+\treturn vtime_generic_enabled_this_cpu();\n }\n \n extern void vtime_task_switch_generic(struct task_struct *prev);\ndiff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c\nindex d91b495457ec..4934c537f5e3 100644\n--- a/kernel/sched/cputime.c\n+++ b/kernel/sched/cputime.c\n@@ -414,16 +414,30 @@ static void irqtime_account_process_tick(struct task_struct *p, int user_tick,\n \t}\n }\n \n-static void irqtime_account_idle_ticks(int ticks)\n-{\n-\tirqtime_account_process_tick(current, 0, ticks);\n-}\n #else /* !CONFIG_IRQ_TIME_ACCOUNTING: */\n-static inline void irqtime_account_idle_ticks(int ticks) { }\n static inline void irqtime_account_process_tick(struct task_struct *p, int user_tick,\n \t\t\t\t\t\tint nr_ticks) { }\n #endif /* !CONFIG_IRQ_TIME_ACCOUNTING */\n \n+#ifdef CONFIG_NO_HZ_COMMON\n+void kcpustat_dyntick_start(void)\n+{\n+\tif (!vtime_generic_enabled_this_cpu()) {\n+\t\tvtime_dyntick_start();\n+\t\t__this_cpu_write(kernel_cpustat.idle_dyntick, 1);\n+\t}\n+}\n+\n+void kcpustat_dyntick_stop(void)\n+{\n+\tif (!vtime_generic_enabled_this_cpu()) {\n+\t\t__this_cpu_write(kernel_cpustat.idle_dyntick, 0);\n+\t\tvtime_dyntick_stop();\n+\t\tsteal_account_process_time(ULONG_MAX);\n+\t}\n+}\n+#endif /* CONFIG_NO_HZ_COMMON */\n+\n /*\n * Use precise platform statistics if available:\n */\n@@ -437,11 +451,15 @@ void vtime_account_irq(struct task_struct *tsk, unsigned int offset)\n \t\tvtime_account_hardirq(tsk);\n \t} else if (pc & SOFTIRQ_OFFSET) {\n \t\tvtime_account_softirq(tsk);\n-\t} else if (!IS_ENABLED(CONFIG_HAVE_VIRT_CPU_ACCOUNTING_IDLE) &&\n-\t\t is_idle_task(tsk)) {\n-\t\tvtime_account_idle(tsk);\n+\t} else if (!kcpustat_idle_dyntick()) {\n+\t\tif (!IS_ENABLED(CONFIG_HAVE_VIRT_CPU_ACCOUNTING_IDLE) &&\n+\t\t is_idle_task(tsk)) {\n+\t\t\tvtime_account_idle(tsk);\n+\t\t} else {\n+\t\t\tvtime_account_kernel(tsk);\n+\t\t}\n \t} else {\n-\t\tvtime_account_kernel(tsk);\n+\t\tvtime_reset();\n \t}\n }\n \n@@ -483,6 +501,9 @@ void account_process_tick(struct task_struct *p, int user_tick)\n \tif (vtime_accounting_enabled_this_cpu())\n \t\treturn;\n \n+\tif (kcpustat_idle_dyntick())\n+\t\treturn;\n+\n \tif (irqtime_enabled()) {\n \t\tirqtime_account_process_tick(p, user_tick, 1);\n \t\treturn;\n@@ -504,29 +525,6 @@ void account_process_tick(struct task_struct *p, int user_tick)\n \t\taccount_idle_time(cputime);\n }\n \n-/*\n- * Account multiple ticks of idle time.\n- * @ticks: number of stolen ticks\n- */\n-void account_idle_ticks(unsigned long ticks)\n-{\n-\tu64 cputime, steal;\n-\n-\tif (irqtime_enabled()) {\n-\t\tirqtime_account_idle_ticks(ticks);\n-\t\treturn;\n-\t}\n-\n-\tcputime = ticks * TICK_NSEC;\n-\tsteal = steal_account_process_time(ULONG_MAX);\n-\n-\tif (steal >= cputime)\n-\t\treturn;\n-\n-\tcputime -= steal;\n-\taccount_idle_time(cputime);\n-}\n-\n /*\n * Adjust tick based cputime random precision against scheduler runtime\n * accounting.\ndiff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c\nindex 7224a50d9c44..2c0f0b81f452 100644\n--- a/kernel/time/tick-sched.c\n+++ b/kernel/time/tick-sched.c\n@@ -285,8 +285,6 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)\n \tif (IS_ENABLED(CONFIG_NO_HZ_COMMON) &&\n \t tick_sched_flag_test(ts, TS_FLAG_STOPPED)) {\n \t\ttouch_softlockup_watchdog_sched();\n-\t\tif (is_idle_task(current))\n-\t\t\tts->idle_jiffies++;\n \t\t/*\n \t\t * In case the current tick fired too early past its expected\n \t\t * expiration, make sure we don't bypass the next clock reprogramming\n@@ -753,8 +751,12 @@ static void tick_nohz_update_jiffies(ktime_t now)\n \n static void tick_nohz_stop_idle(struct tick_sched *ts, ktime_t now)\n {\n+\tu64 *cpustat = kcpustat_this_cpu->cpustat;\n \tktime_t delta;\n \n+\tif (vtime_generic_enabled_this_cpu())\n+\t\treturn;\n+\n \tif (WARN_ON_ONCE(!tick_sched_flag_test(ts, TS_FLAG_IDLE_ACTIVE)))\n \t\treturn;\n \n@@ -762,9 +764,9 @@ static void tick_nohz_stop_idle(struct tick_sched *ts, ktime_t now)\n \n \twrite_seqcount_begin(&ts->idle_sleeptime_seq);\n \tif (nr_iowait_cpu(smp_processor_id()) > 0)\n-\t\tts->iowait_sleeptime = ktime_add(ts->iowait_sleeptime, delta);\n+\t\tcpustat[CPUTIME_IOWAIT] = ktime_add(cpustat[CPUTIME_IOWAIT], delta);\n \telse\n-\t\tts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);\n+\t\tcpustat[CPUTIME_IDLE] = ktime_add(cpustat[CPUTIME_IDLE], delta);\n \n \tts->idle_entrytime = now;\n \ttick_sched_flag_clear(ts, TS_FLAG_IDLE_ACTIVE);\n@@ -775,18 +777,21 @@ static void tick_nohz_stop_idle(struct tick_sched *ts, ktime_t now)\n \n static void tick_nohz_start_idle(struct tick_sched *ts)\n {\n+\tif (vtime_generic_enabled_this_cpu())\n+\t\treturn;\n+\n \twrite_seqcount_begin(&ts->idle_sleeptime_seq);\n \tts->idle_entrytime = ktime_get();\n \ttick_sched_flag_set(ts, TS_FLAG_IDLE_ACTIVE);\n \twrite_seqcount_end(&ts->idle_sleeptime_seq);\n-\n \tsched_clock_idle_sleep_event();\n }\n \n-static u64 get_cpu_sleep_time_us(int cpu, enum cpu_usage_stat idx, ktime_t *sleeptime,\n+static u64 get_cpu_sleep_time_us(int cpu, enum cpu_usage_stat idx,\n \t\t\t\t bool compute_delta, u64 *last_update_time)\n {\n \tstruct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);\n+\tu64 *cpustat = kcpustat_cpu(cpu).cpustat;\n \tktime_t now, idle;\n \tunsigned int seq;\n \n@@ -808,9 +813,9 @@ static u64 get_cpu_sleep_time_us(int cpu, enum cpu_usage_stat idx, ktime_t *slee\n \t\tif (tick_sched_flag_test(ts, TS_FLAG_IDLE_ACTIVE) && compute_delta) {\n \t\t\tktime_t delta = ktime_sub(now, ts->idle_entrytime);\n \n-\t\t\tidle = ktime_add(*sleeptime, delta);\n+\t\t\tidle = ktime_add(cpustat[idx], delta);\n \t\t} else {\n-\t\t\tidle = *sleeptime;\n+\t\t\tidle = cpustat[idx];\n \t\t}\n \t} while (read_seqcount_retry(&ts->idle_sleeptime_seq, seq));\n \n@@ -837,9 +842,7 @@ static u64 get_cpu_sleep_time_us(int cpu, enum cpu_usage_stat idx, ktime_t *slee\n */\n u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)\n {\n-\tstruct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);\n-\n-\treturn get_cpu_sleep_time_us(cpu, CPUTIME_IDLE, &ts->idle_sleeptime,\n+\treturn get_cpu_sleep_time_us(cpu, CPUTIME_IDLE,\n \t\t\t\t !nr_iowait_cpu(cpu), last_update_time);\n }\n EXPORT_SYMBOL_GPL(get_cpu_idle_time_us);\n@@ -863,9 +866,7 @@ EXPORT_SYMBOL_GPL(get_cpu_idle_time_us);\n */\n u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time)\n {\n-\tstruct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);\n-\n-\treturn get_cpu_sleep_time_us(cpu, CPUTIME_IOWAIT, &ts->iowait_sleeptime,\n+\treturn get_cpu_sleep_time_us(cpu, CPUTIME_IOWAIT,\n \t\t\t\t nr_iowait_cpu(cpu), last_update_time);\n }\n EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us);\n@@ -1265,10 +1266,8 @@ void tick_nohz_idle_stop_tick(void)\n \t\tts->idle_sleeps++;\n \t\tts->idle_expires = expires;\n \n-\t\tif (!was_stopped && tick_sched_flag_test(ts, TS_FLAG_STOPPED)) {\n-\t\t\tts->idle_jiffies = ts->last_jiffies;\n+\t\tif (!was_stopped && tick_sched_flag_test(ts, TS_FLAG_STOPPED))\n \t\t\tnohz_balance_enter_idle(cpu);\n-\t\t}\n \t} else {\n \t\ttick_nohz_retain_tick(ts);\n \t}\n@@ -1297,6 +1296,7 @@ void tick_nohz_idle_enter(void)\n \tWARN_ON_ONCE(ts->timer_expires_base);\n \n \ttick_sched_flag_set(ts, TS_FLAG_INIDLE);\n+\tkcpustat_dyntick_start();\n \ttick_nohz_start_idle(ts);\n \n \tlocal_irq_enable();\n@@ -1422,37 +1422,12 @@ unsigned long tick_nohz_get_idle_calls_cpu(int cpu)\n \treturn ts->idle_calls;\n }\n \n-static void tick_nohz_account_idle_time(struct tick_sched *ts,\n-\t\t\t\t\tktime_t now)\n-{\n-\tunsigned long ticks;\n-\n-\tts->idle_exittime = now;\n-\n-\tif (vtime_accounting_enabled_this_cpu())\n-\t\treturn;\n-\t/*\n-\t * We stopped the tick in idle. update_process_times() would miss the\n-\t * time we slept, as it does only a 1 tick accounting.\n-\t * Enforce that this is accounted to idle !\n-\t */\n-\tticks = jiffies - ts->idle_jiffies;\n-\t/*\n-\t * We might be one off. Do not randomly account a huge number of ticks!\n-\t */\n-\tif (ticks && ticks < LONG_MAX)\n-\t\taccount_idle_ticks(ticks);\n-}\n-\n void tick_nohz_idle_restart_tick(void)\n {\n \tstruct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);\n \n-\tif (tick_sched_flag_test(ts, TS_FLAG_STOPPED)) {\n-\t\tktime_t now = ktime_get();\n-\t\ttick_nohz_restart_sched_tick(ts, now);\n-\t\ttick_nohz_account_idle_time(ts, now);\n-\t}\n+\tif (tick_sched_flag_test(ts, TS_FLAG_STOPPED))\n+\t\ttick_nohz_restart_sched_tick(ts, ktime_get());\n }\n \n static void tick_nohz_idle_update_tick(struct tick_sched *ts, ktime_t now)\n@@ -1461,8 +1436,6 @@ static void tick_nohz_idle_update_tick(struct tick_sched *ts, ktime_t now)\n \t\t__tick_nohz_full_update_tick(ts, now);\n \telse\n \t\ttick_nohz_restart_sched_tick(ts, now);\n-\n-\ttick_nohz_account_idle_time(ts, now);\n }\n \n /**\n@@ -1504,6 +1477,7 @@ void tick_nohz_idle_exit(void)\n \n \tif (tick_stopped)\n \t\ttick_nohz_idle_update_tick(ts, now);\n+\tkcpustat_dyntick_stop();\n \n \tlocal_irq_enable();\n }\n@@ -1640,20 +1614,15 @@ void tick_setup_sched_timer(bool hrtimer)\n void tick_sched_timer_dying(int cpu)\n {\n \tstruct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);\n-\tktime_t idle_sleeptime, iowait_sleeptime;\n \tunsigned long idle_calls, idle_sleeps;\n \n \t/* This must happen before hrtimers are migrated! */\n \tif (tick_sched_flag_test(ts, TS_FLAG_HIGHRES))\n \t\thrtimer_cancel(&ts->sched_timer);\n \n-\tidle_sleeptime = ts->idle_sleeptime;\n-\tiowait_sleeptime = ts->iowait_sleeptime;\n \tidle_calls = ts->idle_calls;\n \tidle_sleeps = ts->idle_sleeps;\n \tmemset(ts, 0, sizeof(*ts));\n-\tts->idle_sleeptime = idle_sleeptime;\n-\tts->iowait_sleeptime = iowait_sleeptime;\n \tts->idle_calls = idle_calls;\n \tts->idle_sleeps = idle_sleeps;\n }\n", "prefixes": [ "06/14" ] }