From: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
To: linux-kernel@vger.kernel.org
Cc: Fernando Luis Vazquez Cao <fernando_b1@lab.ntt.co.jp>,
Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>,
Frederic Weisbecker <fweisbec@gmail.com>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Andrew Morton <akpm@linux-foundation.org>,
Arjan van de Ven <arjan@linux.intel.com>,
Oleg Nesterov <oleg@redhat.com>,
Preeti U Murthy <preeti@linux.vnet.ibm.com>,
Denys Vlasenko <vda.linux@googlemail.com>
Subject: [PATCH 2/8] cputime, nohz: handle last_iowait for nohz
Date: Thu, 26 Jun 2014 18:09:37 +0900 [thread overview]
Message-ID: <53ABE351.9000602@jp.fujitsu.com> (raw)
In-Reply-To: <53ABE28F.6010402@jp.fujitsu.com>
Now observer cpu can refer both of idle entry time and iowait exit
time of observed sleeping cpu, so observer can get idle/iowait time
of sleeping cpu by calculating cputimes not accounted yet.
Not-Tested-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
---
include/linux/sched.h | 1 +
kernel/sched/core.c | 27 +++++++++++++++++++++++++
kernel/time/tick-sched.c | 48 +++++++++++++++++++++++++++++++++------------
3 files changed, 63 insertions(+), 13 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 306f4f0..29e1af0 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -168,6 +168,7 @@ extern int nr_processes(void);
extern unsigned long nr_running(void);
extern unsigned long nr_iowait(void);
extern unsigned long nr_iowait_cpu(int cpu);
+extern void nr_iowait_deltas(int cpu, ktime_t start, ktime_t now, ktime_t *iowait, ktime_t *idle);
extern unsigned long this_cpu_load(void);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e759238..814ee2e 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2384,6 +2384,33 @@ unsigned long nr_iowait_cpu(int cpu)
return cpu_rq(cpu)->nr_iowait;
}
+/*
+ * nr_iowait_deltas - divide idle time into idle delta and iowait delta
+ *
+ * @start: time stamp at start of idle span
+ * @now: time stamp at end of idle span
+ * @iowait_delta: address to store calculated iowait
+ * @idle_delta: address to store calculated idle
+ */
+void nr_iowait_deltas(int cpu, ktime_t start, ktime_t now,
+ ktime_t *iowait_delta, ktime_t *idle_delta)
+{
+ struct rq *rq = cpu_rq(cpu);
+
+ raw_spin_lock(&rq->iowait_lock);
+ if (rq->nr_iowait || ktime_compare(rq->last_iowait, now) > 0) {
+ *iowait_delta = ktime_sub(now, start);
+ *idle_delta = ktime_set(0, 0);
+ } else if (ktime_compare(rq->last_iowait, start) > 0) {
+ *iowait_delta = ktime_sub(rq->last_iowait, start);
+ *idle_delta = ktime_sub(now, rq->last_iowait);
+ } else {
+ *iowait_delta = ktime_set(0, 0);
+ *idle_delta = ktime_sub(now, start);
+ }
+ raw_spin_unlock(&rq->iowait_lock);
+}
+
#ifdef CONFIG_SMP
/*
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 44eb187..8d23af5 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -408,16 +408,22 @@ static void tick_nohz_update_jiffies(ktime_t now)
static void tick_nohz_stop_idle(struct tick_sched *ts, ktime_t now)
{
- ktime_t delta;
+ static const ktime_t ktime_zero = { .tv64 = 0 };
+ ktime_t iowait_delta = ktime_zero, idle_delta = ktime_zero;
write_seqcount_begin(&ts->idle_sleeptime_seq);
/* Updates the per cpu time idle statistics counters */
- delta = ktime_sub(now, ts->idle_entrytime);
- if (nr_iowait_cpu(smp_processor_id()) > 0)
- ts->iowait_sleeptime = ktime_add(ts->iowait_sleeptime, delta);
- else
- ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);
+ if (ts->idle_active == 2) {
+ nr_iowait_deltas(smp_processor_id(), ts->idle_entrytime, now,
+ &iowait_delta, &idle_delta);
+ ts->iowait_sleeptime = ktime_add(ts->iowait_sleeptime,
+ iowait_delta);
+ } else {
+ idle_delta = ktime_sub(now, ts->idle_entrytime);
+ }
+ ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, idle_delta);
+
ts->idle_entrytime = now;
ts->idle_active = 0;
@@ -432,7 +438,13 @@ static ktime_t tick_nohz_start_idle(struct tick_sched *ts)
write_seqcount_begin(&ts->idle_sleeptime_seq);
ts->idle_entrytime = now;
- ts->idle_active = 1;
+ /*
+ * idle_active:
+ * 0: cpu is not idle
+ * 1: cpu is performing idle
+ * 2: cpu is performing iowait and idle
+ */
+ ts->idle_active = 1 + !!nr_iowait_cpu(smp_processor_id());
write_seqcount_end(&ts->idle_sleeptime_seq);
sched_clock_idle_sleep_event();
@@ -467,10 +479,18 @@ u64 get_cpu_idle_time_us(int cpu, u64 *wall)
do {
seq = read_seqcount_begin(&ts->idle_sleeptime_seq);
-
- if (ts->idle_active && !nr_iowait_cpu(cpu)) {
- ktime_t delta = ktime_sub(now, ts->idle_entrytime);
+ if (ts->idle_active) {
+ ktime_t delta;
+
+ if (ts->idle_active == 2) {
+ ktime_t unused;
+
+ nr_iowait_deltas(cpu, ts->idle_entrytime, now,
+ &unused, &delta);
+ } else {
+ delta = ktime_sub(now, ts->idle_entrytime);
+ }
idle = ktime_add(ts->idle_sleeptime, delta);
} else {
idle = ts->idle_sleeptime;
@@ -510,10 +530,12 @@ u64 get_cpu_iowait_time_us(int cpu, u64 *wall)
do {
seq = read_seqcount_begin(&ts->idle_sleeptime_seq);
-
- if (ts->idle_active && nr_iowait_cpu(cpu) > 0) {
- ktime_t delta = ktime_sub(now, ts->idle_entrytime);
+ if (ts->idle_active == 2) {
+ ktime_t delta, unused;
+
+ nr_iowait_deltas(cpu, ts->idle_entrytime, now,
+ &delta, &unused);
iowait = ktime_add(ts->iowait_sleeptime, delta);
} else {
iowait = ts->iowait_sleeptime;
--
1.7.1
next prev parent reply other threads:[~2014-06-26 9:10 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-26 9:06 [RFC PATCH 0/8] rework iowait accounting Hidetoshi Seto
2014-06-26 9:08 ` [PATCH 1/8] cputime, sched: record last_iowait Hidetoshi Seto
2014-06-26 9:09 ` Hidetoshi Seto [this message]
2014-06-26 9:10 ` [PATCH 3/8] cputime: introduce account_idle_and_iowait Hidetoshi Seto
2014-06-26 9:12 ` [PATCH 4/8] cputime, s390: introduce s390_get_idle_and_iowait Hidetoshi Seto
2014-06-26 9:13 ` [PATCH 5/8] cputime, ia64: update iowait accounting Hidetoshi Seto
2014-06-26 9:14 ` [PATCH 6/8] cputime, ppc: " Hidetoshi Seto
2014-06-26 9:16 ` [PATCH 7/8] cputime: generic iowait accounting for VIRT_CPU_ACCOUNTING Hidetoshi Seto
2014-06-26 9:17 ` [PATCH 8/8] cputime: iowait aware idle tick accounting Hidetoshi Seto
2014-07-07 9:30 ` [RFC PATCH 0/8] rework iowait accounting Peter Zijlstra
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=53ABE351.9000602@jp.fujitsu.com \
--to=seto.hidetoshi@jp.fujitsu.com \
--cc=akpm@linux-foundation.org \
--cc=arjan@linux.intel.com \
--cc=fernando_b1@lab.ntt.co.jp \
--cc=fweisbec@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=oleg@redhat.com \
--cc=penguin-kernel@I-love.SAKURA.ne.jp \
--cc=peterz@infradead.org \
--cc=preeti@linux.vnet.ibm.com \
--cc=tglx@linutronix.de \
--cc=vda.linux@googlemail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.