Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2218145/?format=api
{ "id": 2218145, "url": "http://patchwork.ozlabs.org/api/patches/2218145/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20260331131622.30505-9-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-9-frederic@kernel.org>", "list_archive_url": "https://lore.kernel.org/linuxppc-dev/20260331131622.30505-9-frederic@kernel.org/", "date": "2026-03-31T13:16:16", "name": "[08/14] tick/sched: Move dyntick-idle cputime accounting to cputime code", "commit_ref": null, "pull_url": null, "state": "handled-elsewhere", "archived": false, "hash": "8654ee06699e86be8257072d07eb827a5ceec8c0", "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-9-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/2218145/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2218145/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linuxppc-dev+bounces-19088-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=IyNg2bGv;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org\n (client-ip=112.213.38.117; helo=lists.ozlabs.org;\n envelope-from=linuxppc-dev+bounces-19088-incoming=patchwork.ozlabs.org@lists.ozlabs.org;\n receiver=patchwork.ozlabs.org)", "lists.ozlabs.org;\n arc=none smtp.remote-ip=\"2600:3c04:e001:324:0:1991:8:25\"", "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=IyNg2bGv;\n\tdkim-atps=neutral", "lists.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=kernel.org\n (client-ip=2600:3c04:e001:324:0:1991:8:25; helo=tor.source.kernel.org;\n envelope-from=frederic@kernel.org; receiver=lists.ozlabs.org)" ], "Received": [ "from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117])\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 4flTDx3NxQz1y1q\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 01 Apr 2026 00:17:37 +1100 (AEDT)", "from boromir.ozlabs.org (localhost [127.0.0.1])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 4flTDv5Pq8z2yjm;\n\tWed, 01 Apr 2026 00:17:35 +1100 (AEDT)", "from tor.source.kernel.org (tor.source.kernel.org\n [IPv6:2600:3c04:e001:324:0:1991:8:25])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n\t(No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 4flTDt4sqYz2ygh\n\tfor <linuxppc-dev@lists.ozlabs.org>; Wed, 01 Apr 2026 00:17:34 +1100 (AEDT)", "from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58])\n\tby tor.source.kernel.org (Postfix) with ESMTP id 995B36024D;\n\tTue, 31 Mar 2026 13:17:32 +0000 (UTC)", "by smtp.kernel.org (Postfix) with ESMTPSA id 778F3C2BCB1;\n\tTue, 31 Mar 2026 13:17:25 +0000 (UTC)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1774963055;\n\tcv=none;\n b=A+/N0ixEW7452qT+0XJQMMxMeH5LPOPQ9SE6l+9QFR5nXK9mGF0o+ORozBpw6CbqN7h9Iueu3lnPkpvUhs3XjysLdKkvvGO/AqtAqaBJGrZxkoFFm+xgYIbOh9uq1riB5DioWMwaJDN8jR6zQEsX0vd44amDbFPN6xlOuAR2JQz1vdPi7qYIjxF5yHu3OXUWhjHzJds8zOOUuCsg8WFpPj6Gmz8JYstdOXVTg/7RBH9s6lrhkO0kdIPAUGYWifRJ8cCjavpH2kgBHslzlXG/cT+BiapB5Z0jBdyztZpozRqeqajGXlNPS4sj01bZfY54k3Lw9YLHXnsKMQt5UB5dmA==", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707;\n\tt=1774963055; c=relaxed/relaxed;\n\tbh=wqVFAkxJs3l7xNt/BRJmr1B0U/i2GFKFxv3Ix/i5mTQ=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=iNCmM+iT2KBGG1TJL5XFcNAkl98UDwuUlZaNEYRrv0TvgdNzRb1twHOeUWKCblcLvaVFIlvpmZPycKowLoDmFGsMf4rV+LBGGjlsBg4/NVG547c0n0DzGVxHlRUZDwb0WUyvLAP5FtmIZLOW2wUDfRUuCcALtwaF6C9JXWb9KdNapMe4kcTQnxXB6k8emqjO1KdKl8H1UFXEEm4g8r0N7+GMYIKq3k66TrGAsU5K2VvUzJaql4kDPyTeL/2JkPHELwfymObNiloju3M0Mnrtp+XyVGXNbvdkj770MGyMHPFm/ptk/T9XWfO0UAMPx5UwGRFBMwHwzu+zHcaPyWTfkA==", "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=IyNg2bGv; dkim-atps=neutral;\n spf=pass (client-ip=2600:3c04:e001:324:0:1991:8:25;\n helo=tor.source.kernel.org; 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=1774963052;\n\tbh=fNJ/wOIp6ZL2N5olFop6YLLXoKkblq8P3RraqV3W0Bk=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=IyNg2bGvIjMzMN1RqgNoFjJLrp2MyjlWYmLE/RJmrZONO+C3e6m9GHSltE8x1RleT\n\t I9GERowGleebRMcIPfR347ccW1ZqaI6NV0xFl6SNvrBoI1rMQUBCBysHIN8c4CenM4\n\t sNmaIDsmg4ESgnFDDkqfOdV1k1AHIrF2j0Bi1L/dwKv7T89wq69iGCPwBvkVSnQZCc\n\t 0wDCfjiZQ42OSLDoKXcoTd79C+F7UlGBbXKYAViMmXLNv9fhX2DKHjp6KqtfkMl1fq\n\t p0n9xtCxQIEjR3OYOwDRyDQ5UfkYWvJppIHfkpQeiRKj1PrVOpQ0ttoFUMrWKv77s9\n\t D4tVDpWZW95zw==", "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 08/14] tick/sched: Move dyntick-idle cputime accounting to\n cputime code", "Date": "Tue, 31 Mar 2026 15:16:16 +0200", "Message-ID": "<20260331131622.30505-9-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": "Although the dynticks-idle cputime accounting is necessarily tied to\nthe tick subsystem, the actual related accounting code has no business\nresiding there and should be part of the scheduler cputime code.\n\nMove away the relevant pieces and state machine to where they belong.\n\nSigned-off-by: Frederic Weisbecker <frederic@kernel.org>\nTested-by: Shrikanth Hegde <sshegde@linux.ibm.com>\n---\n include/linux/kernel_stat.h | 14 +++-\n kernel/sched/cputime.c | 149 +++++++++++++++++++++++++++++++--\n kernel/time/tick-sched.c | 162 +++++++-----------------------------\n 3 files changed, 184 insertions(+), 141 deletions(-)", "diff": "diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h\nindex ba65aad308a1..9343353ac7a3 100644\n--- a/include/linux/kernel_stat.h\n+++ b/include/linux/kernel_stat.h\n@@ -35,9 +35,12 @@ enum cpu_usage_stat {\n \n struct kernel_cpustat {\n #ifdef CONFIG_NO_HZ_COMMON\n-\tint idle_dyntick;\n+\tbool\t\tidle_dyntick;\n+\tbool\t\tidle_elapse;\n+\tseqcount_t\tidle_sleeptime_seq;\n+\tu64\t\tidle_entrytime;\n #endif\n-\tu64 cpustat[NR_STATS];\n+\tu64\t\tcpustat[NR_STATS];\n };\n \n struct kernel_stat {\n@@ -103,8 +106,11 @@ static inline unsigned long kstat_cpu_irqs_sum(unsigned int cpu)\n }\n \n #ifdef CONFIG_NO_HZ_COMMON\n-extern void kcpustat_dyntick_start(void);\n-extern void kcpustat_dyntick_stop(void);\n+extern void kcpustat_dyntick_start(u64 now);\n+extern void kcpustat_dyntick_stop(u64 now);\n+extern void kcpustat_irq_enter(u64 now);\n+extern void kcpustat_irq_exit(u64 now);\n+\n static inline bool kcpustat_idle_dyntick(void)\n {\n \treturn __this_cpu_read(kernel_cpustat.idle_dyntick);\ndiff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c\nindex 4934c537f5e3..4a259f2700a1 100644\n--- a/kernel/sched/cputime.c\n+++ b/kernel/sched/cputime.c\n@@ -2,6 +2,7 @@\n /*\n * Simple CPU accounting cgroup controller\n */\n+#include <linux/sched/clock.h>\n #include <linux/sched/cputime.h>\n #include <linux/tsacct_kern.h>\n #include \"sched.h\"\n@@ -420,22 +421,156 @@ static inline void irqtime_account_process_tick(struct task_struct *p, int user_\n #endif /* !CONFIG_IRQ_TIME_ACCOUNTING */\n \n #ifdef CONFIG_NO_HZ_COMMON\n-void kcpustat_dyntick_start(void)\n+static void kcpustat_idle_stop(struct kernel_cpustat *kc, u64 now)\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+\tu64 *cpustat = kc->cpustat;\n+\tu64 delta;\n+\n+\tif (!kc->idle_elapse)\n+\t\treturn;\n+\n+\tdelta = now - kc->idle_entrytime;\n+\n+\twrite_seqcount_begin(&kc->idle_sleeptime_seq);\n+\tif (nr_iowait_cpu(smp_processor_id()) > 0)\n+\t\tcpustat[CPUTIME_IOWAIT] += delta;\n+\telse\n+\t\tcpustat[CPUTIME_IDLE] += delta;\n+\n+\tkc->idle_entrytime = now;\n+\tkc->idle_elapse = false;\n+\twrite_seqcount_end(&kc->idle_sleeptime_seq);\n }\n \n-void kcpustat_dyntick_stop(void)\n+static void kcpustat_idle_start(struct kernel_cpustat *kc, u64 now)\n {\n+\twrite_seqcount_begin(&kc->idle_sleeptime_seq);\n+\tkc->idle_entrytime = now;\n+\tkc->idle_elapse = true;\n+\twrite_seqcount_end(&kc->idle_sleeptime_seq);\n+}\n+\n+void kcpustat_dyntick_stop(u64 now)\n+{\n+\tstruct kernel_cpustat *kc = kcpustat_this_cpu;\n+\n \tif (!vtime_generic_enabled_this_cpu()) {\n-\t\t__this_cpu_write(kernel_cpustat.idle_dyntick, 0);\n+\t\tWARN_ON_ONCE(!kc->idle_dyntick);\n+\t\tkcpustat_idle_stop(kc, now);\n+\t\tkc->idle_dyntick = false;\n \t\tvtime_dyntick_stop();\n \t\tsteal_account_process_time(ULONG_MAX);\n \t}\n }\n+\n+void kcpustat_dyntick_start(u64 now)\n+{\n+\tstruct kernel_cpustat *kc = kcpustat_this_cpu;\n+\n+\tif (!vtime_generic_enabled_this_cpu()) {\n+\t\tvtime_dyntick_start();\n+\t\tkc->idle_dyntick = true;\n+\t\tkcpustat_idle_start(kc, now);\n+\t}\n+}\n+\n+void kcpustat_irq_enter(u64 now)\n+{\n+\tstruct kernel_cpustat *kc = kcpustat_this_cpu;\n+\n+\tif (!vtime_generic_enabled_this_cpu())\n+\t\tkcpustat_idle_stop(kc, now);\n+}\n+\n+void kcpustat_irq_exit(u64 now)\n+{\n+\tstruct kernel_cpustat *kc = kcpustat_this_cpu;\n+\n+\tif (!vtime_generic_enabled_this_cpu())\n+\t\tkcpustat_idle_start(kc, now);\n+}\n+\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 kernel_cpustat *kc = &kcpustat_cpu(cpu);\n+\tu64 *cpustat = kc->cpustat;\n+\tunsigned int seq;\n+\tktime_t now;\n+\tu64 idle;\n+\n+\tnow = ktime_get();\n+\tif (last_update_time)\n+\t\t*last_update_time = ktime_to_us(now);\n+\n+\tif (vtime_generic_enabled_cpu(cpu)) {\n+\t\tidle = kcpustat_field(idx, cpu);\n+\t\tgoto to_us;\n+\t}\n+\n+\tdo {\n+\t\tseq = read_seqcount_begin(&kc->idle_sleeptime_seq);\n+\n+\t\tif (kc->idle_elapse && compute_delta)\n+\t\t\tidle = cpustat[idx] + (now - kc->idle_entrytime);\n+\t\telse\n+\t\t\tidle = cpustat[idx];\n+\t} while (read_seqcount_retry(&kc->idle_sleeptime_seq, seq));\n+\n+to_us:\n+\tdo_div(idle, NSEC_PER_USEC);\n+\n+\treturn idle;\n+}\n+\n+/**\n+ * get_cpu_idle_time_us - get the total idle time of a CPU\n+ * @cpu: CPU number to query\n+ * @last_update_time: variable to store update time in. Do not update\n+ * counters if NULL.\n+ *\n+ * Return the cumulative idle time (since boot) for a given\n+ * CPU, in microseconds. Note that this is partially broken due to\n+ * the counter of iowait tasks that can be remotely updated without\n+ * any synchronization. Therefore it is possible to observe backward\n+ * values within two consecutive reads.\n+ *\n+ * This time is measured via accounting rather than sampling,\n+ * and is as accurate as ktime_get() is.\n+ *\n+ * Return: -1 if generic vtime is enabled, else total idle time of the @cpu\n+ */\n+u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)\n+{\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+\n+/**\n+ * get_cpu_iowait_time_us - get the total iowait time of a CPU\n+ * @cpu: CPU number to query\n+ * @last_update_time: variable to store update time in. Do not update\n+ * counters if NULL.\n+ *\n+ * Return the cumulative iowait time (since boot) for a given\n+ * CPU, in microseconds. Note this is partially broken due to\n+ * the counter of iowait tasks that can be remotely updated without\n+ * any synchronization. Therefore it is possible to observe backward\n+ * values within two consecutive reads.\n+ *\n+ * This time is measured via accounting rather than sampling,\n+ * and is as accurate as ktime_get() is.\n+ *\n+ * Return: -1 if generic vtime is enabled, else total iowait time of @cpu\n+ */\n+u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time)\n+{\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+\n #endif /* CONFIG_NO_HZ_COMMON */\n \n /*\ndiff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c\nindex 6cd7777755dd..0da83d9b324a 100644\n--- a/kernel/time/tick-sched.c\n+++ b/kernel/time/tick-sched.c\n@@ -749,125 +749,6 @@ static void tick_nohz_update_jiffies(ktime_t now)\n \ttouch_softlockup_watchdog_sched();\n }\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-\tdelta = ktime_sub(now, ts->idle_entrytime);\n-\n-\twrite_seqcount_begin(&ts->idle_sleeptime_seq);\n-\tif (nr_iowait_cpu(smp_processor_id()) > 0)\n-\t\tcpustat[CPUTIME_IOWAIT] = ktime_add(cpustat[CPUTIME_IOWAIT], delta);\n-\telse\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-\twrite_seqcount_end(&ts->idle_sleeptime_seq);\n-\n-\tsched_clock_idle_wakeup_event();\n-}\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-\tsched_clock_idle_sleep_event();\n-}\n-\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-\tnow = ktime_get();\n-\tif (last_update_time)\n-\t\t*last_update_time = ktime_to_us(now);\n-\n-\tif (vtime_generic_enabled_cpu(cpu)) {\n-\t\tidle = kcpustat_field(idx, cpu);\n-\t\treturn ktime_to_us(idle);\n-\t}\n-\n-\tdo {\n-\t\tseq = read_seqcount_begin(&ts->idle_sleeptime_seq);\n-\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(cpustat[idx], delta);\n-\t\t} else {\n-\t\t\tidle = cpustat[idx];\n-\t\t}\n-\t} while (read_seqcount_retry(&ts->idle_sleeptime_seq, seq));\n-\n-\treturn ktime_to_us(idle);\n-\n-}\n-\n-/**\n- * get_cpu_idle_time_us - get the total idle time of a CPU\n- * @cpu: CPU number to query\n- * @last_update_time: variable to store update time in. Do not update\n- * counters if NULL.\n- *\n- * Return the cumulative idle time (since boot) for a given\n- * CPU, in microseconds. Note that this is partially broken due to\n- * the counter of iowait tasks that can be remotely updated without\n- * any synchronization. Therefore it is possible to observe backward\n- * values within two consecutive reads.\n- *\n- * This time is measured via accounting rather than sampling,\n- * and is as accurate as ktime_get() is.\n- *\n- * Return: -1 if generic vtime is enabled, else total idle time of the @cpu\n- */\n-u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)\n-{\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-\n-/**\n- * get_cpu_iowait_time_us - get the total iowait time of a CPU\n- * @cpu: CPU number to query\n- * @last_update_time: variable to store update time in. Do not update\n- * counters if NULL.\n- *\n- * Return the cumulative iowait time (since boot) for a given\n- * CPU, in microseconds. Note this is partially broken due to\n- * the counter of iowait tasks that can be remotely updated without\n- * any synchronization. Therefore it is possible to observe backward\n- * values within two consecutive reads.\n- *\n- * This time is measured via accounting rather than sampling,\n- * and is as accurate as ktime_get() is.\n- *\n- * Return: -1 if generic vtime is enabled, else total iowait time of @cpu\n- */\n-u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time)\n-{\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-\n static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)\n {\n \thrtimer_cancel(&ts->sched_timer);\n@@ -1275,6 +1156,20 @@ void tick_nohz_idle_retain_tick(void)\n \ttick_nohz_retain_tick(this_cpu_ptr(&tick_cpu_sched));\n }\n \n+static void tick_nohz_clock_sleep(struct tick_sched *ts)\n+{\n+\ttick_sched_flag_set(ts, TS_FLAG_IDLE_ACTIVE);\n+\tsched_clock_idle_sleep_event();\n+}\n+\n+static void tick_nohz_clock_wakeup(struct tick_sched *ts)\n+{\n+\tif (tick_sched_flag_test(ts, TS_FLAG_IDLE_ACTIVE)) {\n+\t\ttick_sched_flag_clear(ts, TS_FLAG_IDLE_ACTIVE);\n+\t\tsched_clock_idle_wakeup_event();\n+\t}\n+}\n+\n /**\n * tick_nohz_idle_enter - prepare for entering idle on the current CPU\n *\n@@ -1289,12 +1184,11 @@ void tick_nohz_idle_enter(void)\n \tlocal_irq_disable();\n \n \tts = this_cpu_ptr(&tick_cpu_sched);\n-\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+\tts->idle_entrytime = ktime_get();\n+\tkcpustat_dyntick_start(ts->idle_entrytime);\n+\ttick_nohz_clock_sleep(ts);\n \n \tlocal_irq_enable();\n }\n@@ -1322,10 +1216,13 @@ void tick_nohz_irq_exit(void)\n {\n \tstruct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);\n \n-\tif (tick_sched_flag_test(ts, TS_FLAG_INIDLE))\n-\t\ttick_nohz_start_idle(ts);\n-\telse\n+\tif (tick_sched_flag_test(ts, TS_FLAG_INIDLE)) {\n+\t\tts->idle_entrytime = ktime_get();\n+\t\tkcpustat_irq_exit(ts->idle_entrytime);\n+\t\ttick_nohz_clock_sleep(ts);\n+\t} else {\n \t\ttick_nohz_full_update_tick(ts);\n+\t}\n }\n \n /**\n@@ -1470,11 +1367,11 @@ void tick_nohz_idle_exit(void)\n \t\tnow = ktime_get();\n \n \tif (idle_active)\n-\t\ttick_nohz_stop_idle(ts, now);\n+\t\ttick_nohz_clock_wakeup(ts);\n \n \tif (tick_stopped)\n \t\ttick_nohz_idle_update_tick(ts, now);\n-\tkcpustat_dyntick_stop();\n+\tkcpustat_dyntick_stop(now);\n \n \tlocal_irq_enable();\n }\n@@ -1530,9 +1427,14 @@ static inline void tick_nohz_irq_enter(void)\n \n \tif (!tick_sched_flag_test(ts, TS_FLAG_STOPPED | TS_FLAG_IDLE_ACTIVE))\n \t\treturn;\n+\n \tnow = ktime_get();\n-\tif (tick_sched_flag_test(ts, TS_FLAG_IDLE_ACTIVE))\n-\t\ttick_nohz_stop_idle(ts, now);\n+\n+\tif (tick_sched_flag_test(ts, TS_FLAG_IDLE_ACTIVE)) {\n+\t\ttick_nohz_clock_wakeup(ts);\n+\t\tkcpustat_irq_enter(now);\n+\t}\n+\n \t/*\n \t * If all CPUs are idle we may need to update a stale jiffies value.\n \t * Note nohz_full is a special case: a timekeeper is guaranteed to stay\n", "prefixes": [ "08/14" ] }