From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>,
Thomas Gleixner <tglx@linutronix.de>,
Peter Zijlstra <peterz@infradead.org>,
Clark Williams <clark.williams@gmail.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Li Zefan <lizf@cn.fujitsu.com>, Ingo Molnar <mingo@kernel.org>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
Mike Galbraith <efault@gmx.de>,
Alessio Igor Bogani <abogani@kernel.org>,
Avi Kivity <avi@redhat.com>, Chris Metcalf <cmetcalf@tilera.com>,
Christoph Lameter <cl@linux.com>,
Daniel Lezcano <daniel.lezcano@linaro.org>,
Geoff Levand <geoff@infradead.org>,
Gilad Ben Yossef <gilad@benyossef.com>,
Hakan Akkan <hakanakkan@gmail.com>, Kevin Hilman <khilman@ti.com>,
Max Krasnyansky <maxk@qualcomm.com>,
Stephen Hemminger <shemminger@vyatta.com>,
Sven-Thorsten Dietrich <thebigcorporation@gmail.com>
Subject: [PATCH 13/32] nohz: Generalize tickless cpu time accounting
Date: Mon, 29 Oct 2012 16:27:24 -0400 [thread overview]
Message-ID: <20121029203848.537000286@goodmis.org> (raw)
In-Reply-To: 20121029202711.062749374@goodmis.org
[-- Attachment #1: 0013-nohz-Generalize-tickless-cpu-time-accounting.patch --]
[-- Type: text/plain, Size: 10985 bytes --]
From: Frederic Weisbecker <fweisbec@gmail.com>
When the CPU enters idle, it saves the jiffies stamp into
ts->idle_jiffies, increment this value by one every time
there is a timer interrupt and accounts "jiffies - ts->idle_jiffies"
idle ticks when we exit idle. This way we still account the
idle CPU time even if the tick is stopped.
This patch settles the ground to generalize this for user
and system accounting. ts->idle_jiffies becomes ts->saved_jiffies and
a new member ts->saved_jiffies_whence indicates from which domain
we saved the jiffies: user, system or idle.
This is one more step toward making the tickless infrastructure usable
further idle contexts.
For now this is only used by idle but further patches make use of
it for user and system.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Alessio Igor Bogani <abogani@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Avi Kivity <avi@redhat.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Geoff Levand <geoff@infradead.org>
Cc: Gilad Ben Yossef <gilad@benyossef.com>
Cc: Hakan Akkan <hakanakkan@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Max Krasnyansky <maxk@qualcomm.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Sven-Thorsten Dietrich <thebigcorporation@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
include/linux/kernel_stat.h | 2 ++
include/linux/tick.h | 45 ++++++++++++++++++++--------------
kernel/sched/cputime.c | 22 +++++++++++++++++
kernel/time/tick-sched.c | 57 ++++++++++++++++++++++++++++---------------
kernel/time/timer_list.c | 3 ++-
5 files changed, 90 insertions(+), 39 deletions(-)
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 36d12f0..88a44a3 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -122,7 +122,9 @@ static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu)
extern unsigned long long task_delta_exec(struct task_struct *);
extern void account_user_time(struct task_struct *, cputime_t, cputime_t);
+extern void account_user_ticks(struct task_struct *, unsigned long);
extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t);
+extern void account_system_ticks(struct task_struct *, unsigned long);
extern void account_steal_time(cputime_t);
extern void account_idle_time(cputime_t);
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 9b66fd3..03b6edd 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -27,25 +27,33 @@ enum tick_nohz_mode {
NOHZ_MODE_HIGHRES,
};
+enum tick_saved_jiffies {
+ JIFFIES_SAVED_NONE,
+ JIFFIES_SAVED_IDLE,
+ JIFFIES_SAVED_USER,
+ JIFFIES_SAVED_SYS,
+};
+
/**
* struct tick_sched - sched tick emulation and no idle tick control/stats
- * @sched_timer: hrtimer to schedule the periodic tick in high
- * resolution mode
- * @last_tick: Store the last tick expiry time when the tick
- * timer is modified for nohz sleeps. This is necessary
- * to resume the tick timer operation in the timeline
- * when the CPU returns from nohz sleep.
- * @tick_stopped: Indicator that the idle tick has been stopped
- * @idle_jiffies: jiffies at the entry to idle for idle time accounting
- * @idle_calls: Total number of idle calls
- * @idle_sleeps: Number of idle calls, where the sched tick was stopped
- * @idle_entrytime: Time when the idle call was entered
- * @idle_waketime: Time when the idle was interrupted
- * @idle_exittime: Time when the idle state was left
- * @idle_sleeptime: Sum of the time slept in idle with sched tick stopped
- * @iowait_sleeptime: Sum of the time slept in idle with sched tick stopped, with IO outstanding
- * @sleep_length: Duration of the current idle sleep
- * @do_timer_lst: CPU was the last one doing do_timer before going idle
+ * @sched_timer: hrtimer to schedule the periodic tick in high
+ * resolution mode
+ * @last_tick: Store the last tick expiry time when the tick
+ * timer is modified for nohz sleeps. This is necessary
+ * to resume the tick timer operation in the timeline
+ * when the CPU returns from nohz sleep.
+ * @tick_stopped: Indicator that the idle tick has been stopped
+ * @idle_calls: Total number of idle calls
+ * @idle_sleeps: Number of idle calls, where the sched tick was stopped
+ * @idle_entrytime: Time when the idle call was entered
+ * @idle_waketime: Time when the idle was interrupted
+ * @idle_exittime: Time when the idle state was left
+ * @idle_sleeptime: Sum of the time slept in idle with sched tick stopped
+ * @saved_jiffies: Jiffies snapshot on tick stop for cpu time accounting
+ * @saved_jiffies_whence: Area where we saved @saved_jiffies
+ * @iowait_sleeptime: Sum of the time slept in idle with sched tick stopped, with IO outstanding
+ * @sleep_length: Duration of the current idle sleep
+ * @do_timer_lst: CPU was the last one doing do_timer before going idle
*/
struct tick_sched {
struct hrtimer sched_timer;
@@ -54,7 +62,6 @@ struct tick_sched {
ktime_t last_tick;
int inidle;
int tick_stopped;
- unsigned long idle_jiffies;
unsigned long idle_calls;
unsigned long idle_sleeps;
int idle_active;
@@ -62,6 +69,8 @@ struct tick_sched {
ktime_t idle_waketime;
ktime_t idle_exittime;
ktime_t idle_sleeptime;
+ enum tick_saved_jiffies saved_jiffies_whence;
+ unsigned long saved_jiffies;
ktime_t iowait_sleeptime;
ktime_t sleep_length;
unsigned long last_jiffies;
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 81b763b..b7a4d1a 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -166,6 +166,17 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
acct_update_integrals(p);
}
+void account_user_ticks(struct task_struct *p, unsigned long ticks)
+{
+ cputime_t delta_cputime, delta_scaled;
+
+ if (ticks) {
+ delta_cputime = jiffies_to_cputime(ticks);
+ delta_scaled = cputime_to_scaled(ticks);
+ account_user_time(p, delta_cputime, delta_scaled);
+ }
+}
+
/*
* Account guest cpu time to a process.
* @p: the process that the cpu time gets accounted to
@@ -243,6 +254,17 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
__account_system_time(p, cputime, cputime_scaled, index);
}
+void account_system_ticks(struct task_struct *p, unsigned long ticks)
+{
+ cputime_t delta_cputime, delta_scaled;
+
+ if (ticks) {
+ delta_cputime = jiffies_to_cputime(ticks);
+ delta_scaled = cputime_to_scaled(ticks);
+ account_system_time(p, 0, delta_cputime, delta_scaled);
+ }
+}
+
/*
* Account for involuntary wait time.
* @cputime: the cpu time spent in involuntary wait
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index de7de68..b8f3757 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -466,7 +466,8 @@ static void __tick_nohz_idle_enter(struct tick_sched *ts)
}
if (!was_stopped && ts->tick_stopped) {
- ts->idle_jiffies = ts->last_jiffies;
+ ts->saved_jiffies = ts->last_jiffies;
+ ts->saved_jiffies_whence = JIFFIES_SAVED_IDLE;
nohz_balance_enter_idle(cpu);
calc_load_enter_idle();
}
@@ -647,22 +648,36 @@ void tick_nohz_restart_sched_tick(void)
}
-static void tick_nohz_account_idle_ticks(struct tick_sched *ts)
+static void tick_nohz_account_ticks(struct tick_sched *ts)
{
-#ifndef CONFIG_VIRT_CPU_ACCOUNTING
unsigned long ticks;
/*
- * We stopped the tick in idle. Update process times would miss the
- * time we slept as update_process_times does only a 1 tick
- * accounting. Enforce that this is accounted to idle !
+ * We stopped the tick. Update process times would miss the
+ * time we ran tickless as update_process_times does only a 1 tick
+ * accounting. Enforce that this is accounted to nohz timeslices.
*/
- ticks = jiffies - ts->idle_jiffies;
+ ticks = jiffies - ts->saved_jiffies;
/*
* We might be one off. Do not randomly account a huge number of ticks!
*/
- if (ticks && ticks < LONG_MAX)
- account_idle_ticks(ticks);
-#endif
+ if (ticks && ticks < LONG_MAX) {
+ switch (ts->saved_jiffies_whence) {
+ case JIFFIES_SAVED_IDLE:
+ account_idle_ticks(ticks);
+ break;
+ case JIFFIES_SAVED_USER:
+ account_user_ticks(current, ticks);
+ break;
+ case JIFFIES_SAVED_SYS:
+ account_system_ticks(current, ticks);
+ break;
+ case JIFFIES_SAVED_NONE:
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ }
+ }
+ ts->saved_jiffies_whence = JIFFIES_SAVED_NONE;
}
/**
@@ -694,7 +709,9 @@ void tick_nohz_idle_exit(void)
nohz_balance_enter_idle(cpu);
calc_load_exit_idle();
__tick_nohz_restart_sched_tick(ts, now);
- tick_nohz_account_idle_ticks(ts);
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
+ tick_nohz_account_ticks(ts);
+#endif
}
local_irq_enable();
@@ -742,7 +759,7 @@ static void tick_nohz_handler(struct clock_event_device *dev)
*/
if (ts->tick_stopped) {
touch_softlockup_watchdog();
- ts->idle_jiffies++;
+ ts->saved_jiffies++;
}
update_process_times(user_mode(regs));
@@ -953,17 +970,17 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
if (regs) {
int user = user_mode(regs);
/*
- * When we are idle and the tick is stopped, we have to touch
- * the watchdog as we might not schedule for a really long
- * time. This happens on complete idle SMP systems while
- * waiting on the login prompt. We also increment the "start of
- * idle" jiffy stamp so the idle accounting adjustment we do
- * when we go busy again does not account too much ticks.
+ * When the tick is stopped, we have to touch the watchdog
+ * as we might not schedule for a really long time. This
+ * happens on complete idle SMP systems while waiting on
+ * the login prompt. We also increment the last jiffy stamp
+ * recorded when we stopped the tick so the cpu time accounting
+ * adjustment does not account too much ticks when we flush them.
*/
if (ts->tick_stopped) {
+ /* CHECKME: may be this is only needed in idle */
touch_softlockup_watchdog();
- if (is_idle_task(current))
- ts->idle_jiffies++;
+ ts->saved_jiffies++;
}
update_process_times(user);
profile_tick(CPU_PROFILING);
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index af5a7e9..54705e3 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -169,7 +169,8 @@ static void print_cpu(struct seq_file *m, int cpu, u64 now)
P(nohz_mode);
P_ns(last_tick);
P(tick_stopped);
- P(idle_jiffies);
+ /* CHECKME: Do we want saved_jiffies_whence as well? */
+ P(saved_jiffies);
P(idle_calls);
P(idle_sleeps);
P_ns(idle_entrytime);
--
1.7.10.4
next prev parent reply other threads:[~2012-10-29 20:48 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-29 20:27 [PATCH 00/32] [RFC] nohz/cpuset: Start discussions on nohz CPUs Steven Rostedt
2012-10-29 20:27 ` [PATCH 01/32] nohz: Move nohz load balancer selection into idle logic Steven Rostedt
2012-10-30 8:32 ` Charles Wang
2012-10-30 15:39 ` Steven Rostedt
2012-10-29 20:27 ` [PATCH 02/32] cpuset: Set up interface for nohz flag Steven Rostedt
2012-10-30 17:16 ` Steven Rostedt
2012-10-29 20:27 ` [PATCH 03/32] nohz: Try not to give the timekeeping duty to an adaptive tickless cpu Steven Rostedt
2012-10-30 17:33 ` Steven Rostedt
2012-10-29 20:27 ` [PATCH 04/32] x86: New cpuset nohz irq vector Steven Rostedt
2012-10-30 17:39 ` Steven Rostedt
2012-10-30 23:51 ` Frederic Weisbecker
2012-10-31 0:07 ` Steven Rostedt
2012-10-31 0:45 ` Frederic Weisbecker
2012-10-29 20:27 ` [PATCH 05/32] nohz: Adaptive tick stop and restart on nohz cpuset Steven Rostedt
2012-10-30 18:23 ` Steven Rostedt
2012-10-29 20:27 ` [PATCH 06/32] nohz/cpuset: Dont turn off the tick if rcu needs it Steven Rostedt
2012-10-30 18:30 ` Steven Rostedt
2012-10-29 20:27 ` [PATCH 07/32] nohz/cpuset: Wake up adaptive nohz CPU when a timer gets enqueued Steven Rostedt
2012-10-29 20:27 ` [PATCH 08/32] nohz/cpuset: Dont stop the tick if posix cpu timers are running Steven Rostedt
2012-10-29 20:27 ` [PATCH 09/32] nohz/cpuset: Restart tick when nohz flag is cleared on cpuset Steven Rostedt
2012-10-30 18:55 ` Steven Rostedt
2012-10-29 20:27 ` [PATCH 10/32] nohz/cpuset: Restart the tick if printk needs it Steven Rostedt
2012-10-30 19:01 ` Steven Rostedt
2012-10-30 23:54 ` Frederic Weisbecker
2012-10-29 20:27 ` [PATCH 11/32] rcu: Restart the tick on non-responding adaptive nohz CPUs Steven Rostedt
2012-10-29 20:27 ` [PATCH 12/32] rcu: Restart tick if we enqueue a callback in a nohz/cpuset CPU Steven Rostedt
2012-10-29 20:27 ` Steven Rostedt [this message]
2012-10-29 20:27 ` [PATCH 14/32] nohz/cpuset: Account user and system times in adaptive nohz mode Steven Rostedt
2012-10-29 20:27 ` [PATCH 15/32] nohz/cpuset: New API to flush cputimes on nohz cpusets Steven Rostedt
2012-10-29 20:27 ` [PATCH 16/32] nohz/cpuset: Flush cputime on threads in nohz cpusets when waiting leader Steven Rostedt
2012-10-29 20:27 ` [PATCH 17/32] nohz/cpuset: Flush cputimes on procfs stat file read Steven Rostedt
2012-10-29 20:27 ` [PATCH 18/32] nohz/cpuset: Flush cputimes for getrusage() and times() syscalls Steven Rostedt
2012-10-29 20:27 ` [PATCH 19/32] x86: Syscall hooks for nohz cpusets Steven Rostedt
2012-10-29 20:27 ` [PATCH 20/32] nohz/cpuset: enable addition&removal of cpus while in adaptive nohz mode Steven Rostedt
2012-10-29 20:27 ` [PATCH 21/32] nohz: Dont restart the tick before scheduling to idle Steven Rostedt
2012-10-29 20:27 ` [PATCH 22/32] sched: Comment on rq->clock correctness in ttwu_do_wakeup() in nohz Steven Rostedt
2012-10-29 20:27 ` [PATCH 23/32] sched: Update rq clock on nohz CPU before migrating tasks Steven Rostedt
2012-10-29 20:27 ` [PATCH 24/32] sched: Update rq clock on nohz CPU before setting fair group shares Steven Rostedt
2012-10-29 20:27 ` [PATCH 25/32] sched: Update rq clock on tickless CPUs before calling check_preempt_curr() Steven Rostedt
2012-10-29 20:27 ` [PATCH 26/32] sched: Update rq clock earlier in unthrottle_cfs_rq Steven Rostedt
2012-10-29 20:27 ` [PATCH 27/32] sched: Update clock of nohz busiest rq before balancing Steven Rostedt
2012-10-29 20:27 ` [PATCH 28/32] sched: Update rq clock before idle balancing Steven Rostedt
2012-10-29 20:27 ` [PATCH 29/32] sched: Update nohz rq clock before searching busiest group on load balancing Steven Rostedt
2012-10-29 20:27 ` [PATCH 30/32] rcu: Switch to extended quiescent state in userspace from nohz cpuset Steven Rostedt
2012-10-29 20:27 ` [PATCH 31/32] nohz/cpuset: Disable under some configs Steven Rostedt
2012-10-29 20:27 ` [PATCH 32/32] nohz, not for merge: Add tickless tracing Steven Rostedt
2012-10-30 14:02 ` [PATCH 00/32] [RFC] nohz/cpuset: Start discussions on nohz CPUs Gilad Ben-Yossef
2012-11-02 14:23 ` Christoph Lameter
2012-11-02 14:37 ` Steven Rostedt
2012-11-02 14:50 ` David Nyström
2012-11-02 15:03 ` Christoph Lameter
2012-11-02 15:14 ` Steven Rostedt
2012-11-02 18:35 ` Paul E. McKenney
2012-11-02 20:16 ` Christoph Lameter
2012-11-02 20:41 ` Paul E. McKenney
2012-11-02 20:51 ` Steven Rostedt
2012-11-03 2:08 ` Paul E. McKenney
2012-11-05 15:17 ` Christoph Lameter
2012-11-05 22:41 ` Frederic Weisbecker
2012-11-05 22:32 ` Frederic Weisbecker
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=20121029203848.537000286@goodmis.org \
--to=rostedt@goodmis.org \
--cc=abogani@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=avi@redhat.com \
--cc=cl@linux.com \
--cc=clark.williams@gmail.com \
--cc=cmetcalf@tilera.com \
--cc=daniel.lezcano@linaro.org \
--cc=efault@gmx.de \
--cc=fweisbec@gmail.com \
--cc=geoff@infradead.org \
--cc=gilad@benyossef.com \
--cc=hakanakkan@gmail.com \
--cc=khilman@ti.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lizf@cn.fujitsu.com \
--cc=maxk@qualcomm.com \
--cc=mingo@kernel.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=shemminger@vyatta.com \
--cc=tglx@linutronix.de \
--cc=thebigcorporation@gmail.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.