From: Zucheng Zheng <zhengzucheng@huawei.com>
To: <mingo@redhat.com>, <peterz@infradead.org>,
<juri.lelli@redhat.com>, <vincent.guittot@linaro.org>,
<dietmar.eggemann@arm.com>, <rostedt@goodmis.org>,
<bsegall@google.com>, <mgorman@suse.de>, <bristot@redhat.com>,
<vschneid@redhat.com>, <frederic@kernel.org>,
<hucool.lihua@huawei.com>
Cc: <linux-kernel@vger.kernel.org>
Subject: [PATCH -next] sched/cputime: Fix the time backward issue about /proc/stat
Date: Wed, 28 Sep 2022 11:34:02 +0800 [thread overview]
Message-ID: <20220928033402.181530-1-zhengzucheng@huawei.com> (raw)
From: Zheng Zucheng <zhengzucheng@huawei.com>
The cputime of cpuN read from /proc/stat has an issue of cputime descent.
For example, the phenomenon of cputime descent of user is as followed:
The value read first is 319, and the value read again is 318. As follows:
first:
cat /proc/stat | grep cpu1
cpu1 319 0 496 41665 0 0 0 0 0 0
again:
cat /proc/stat | grep cpu1
cpu1 318 0 497 41674 0 0 0 0 0 0
The value read from /proc/stat should be monotonically increasing. Otherwise
user may get incorrect CPU usage.
The root cause of this problem is that, in the implementation of
kcpustat_cpu_fetch_vtime, vtime->utime + delta is added to the stack variable
cpustat instantaneously. If the task is switched between two times, the value
added to cpustat for the second time may be smaller than that for the first time.
CPU0 CPU1
First:
show_stat()
->kcpustat_cpu_fetch()
->kcpustat_cpu_fetch_vtime()
->cpustat[CPUTIME_USER] = kcpustat_cpu(cpu) + vtime->utime + delta rq->curr is task A
A switch to B,and A->vtime->utime is less than 1 tick
Then:
show_stat()
->kcpustat_cpu_fetch()
->kcpustat_cpu_fetch_vtime()
->cpustat[CPUTIME_USER] = kcpustat_cpu(cpu) + vtime->utime + delta; rq->curr is task B
Fixes: 74722bb223d0 ("sched/vtime: Bring up complete kcpustat accessor")
Signed-off-by: Li Hua <hucool.lihua@huawei.com>
Signed-off-by: Zheng Zucheng <zhengzucheng@huawei.com>
---
kernel/sched/cputime.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 95fc77853743..c7a812ff1fb7 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -1060,9 +1060,17 @@ static int kcpustat_cpu_fetch_vtime(struct kernel_cpustat *dst,
return 0;
}
+DEFINE_PER_CPU(struct kernel_cpustat, kernel_cpustat_reverse);
+DEFINE_PER_CPU(raw_spinlock_t, kernel_cpustat_reverse_lock);
+
void kcpustat_cpu_fetch(struct kernel_cpustat *dst, int cpu)
{
const struct kernel_cpustat *src = &kcpustat_cpu(cpu);
+ struct kernel_cpustat *reverse = &per_cpu(kernel_cpustat_reverse, cpu);
+ raw_spinlock_t *cpustat_lock = &per_cpu(kernel_cpustat_reverse_lock, cpu);
+ u64 *dstat = dst->cpustat;
+ u64 *restat = reverse->cpustat;
+ unsigned long flags;
struct rq *rq;
int err;
@@ -1087,8 +1095,22 @@ void kcpustat_cpu_fetch(struct kernel_cpustat *dst, int cpu)
err = kcpustat_cpu_fetch_vtime(dst, src, curr, cpu);
rcu_read_unlock();
- if (!err)
+ if (!err) {
+ raw_spin_lock_irqsave(cpustat_lock, flags);
+ if (dstat[CPUTIME_USER] < restat[CPUTIME_USER])
+ dstat[CPUTIME_USER] = restat[CPUTIME_USER];
+ if (dstat[CPUTIME_SYSTEM] < restat[CPUTIME_SYSTEM])
+ dstat[CPUTIME_SYSTEM] = restat[CPUTIME_SYSTEM];
+ if (dstat[CPUTIME_NICE] < restat[CPUTIME_NICE])
+ dstat[CPUTIME_NICE] = restat[CPUTIME_NICE];
+ if (dstat[CPUTIME_GUEST] < restat[CPUTIME_GUEST])
+ dstat[CPUTIME_GUEST] = restat[CPUTIME_GUEST];
+ if (dstat[CPUTIME_GUEST_NICE] < restat[CPUTIME_GUEST_NICE])
+ dstat[CPUTIME_GUEST_NICE] = restat[CPUTIME_GUEST_NICE];
+ *reverse = *dst;
+ raw_spin_unlock_irqrestore(cpustat_lock, flags);
return;
+ }
cpu_relax();
}
--
2.18.0.huawei.25
next reply other threads:[~2022-09-28 3:38 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-28 3:34 Zucheng Zheng [this message]
2022-09-28 8:12 ` [PATCH -next] sched/cputime: Fix the time backward issue about /proc/stat Peter Zijlstra
2022-09-28 12:11 ` Frederic Weisbecker
2022-09-30 2:43 ` zhengzucheng
2022-09-30 12:16 ` Frederic Weisbecker
2022-10-09 2:28 ` zhengzucheng
2022-09-30 12:14 ` [sched/cputime] 131c995687: BUG:spinlock_trylock_failure_on_UP_on_CPU kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220928033402.181530-1-zhengzucheng@huawei.com \
--to=zhengzucheng@huawei.com \
--cc=bristot@redhat.com \
--cc=bsegall@google.com \
--cc=dietmar.eggemann@arm.com \
--cc=frederic@kernel.org \
--cc=hucool.lihua@huawei.com \
--cc=juri.lelli@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).