* [PATCH] steal_account_process_tick() should return jiffies
@ 2016-03-04 22:59 Chris Friesen
2016-03-05 10:27 ` Thomas Gleixner
0 siblings, 1 reply; 8+ messages in thread
From: Chris Friesen @ 2016-03-04 22:59 UTC (permalink / raw)
To: John Stultz, Thomas Gleixner, Daniel Lezcano, Frederic Weisbecker,
lkml
The callers of steal_account_process_tick() expect it to return whether
the last jiffy was stolen or not.
Currently the return value of steal_account_process_tick() is in units
of cputime, which vary between either jiffies or nsecs depending on
CONFIG_VIRT_CPU_ACCOUNTING_GEN.
The fix is to change steal_account_process_tick() to always return
jiffies. If CONFIG_VIRT_CPU_ACCOUNTING_GEN is not enabled then this
is a no-op.
As far as I can tell this bug has been present since commit dee08a72.
Signed-off-by: Chris Friesen <chris.friesen@windriver.com>
---
kernel/sched/cputime.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index b2ab2ff..e724496 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -276,7 +276,7 @@ static __always_inline bool steal_account_process_tick(void)
this_rq()->prev_steal_time += cputime_to_nsecs(steal_ct);
account_steal_time(steal_ct);
- return steal_ct;
+ return cputime_to_jiffies(steal_ct);
}
#endif
return false;
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH] steal_account_process_tick() should return jiffies 2016-03-04 22:59 [PATCH] steal_account_process_tick() should return jiffies Chris Friesen @ 2016-03-05 10:27 ` Thomas Gleixner 2016-03-05 13:19 ` Frederic Weisbecker 0 siblings, 1 reply; 8+ messages in thread From: Thomas Gleixner @ 2016-03-05 10:27 UTC (permalink / raw) To: Chris Friesen Cc: John Stultz, Daniel Lezcano, Frederic Weisbecker, lkml, Peter Zijlstra, Ingo Molnar, Rik van Riel Chris, On Fri, 4 Mar 2016, Chris Friesen wrote: First of all the subject line should contain a subsystem prefix, i.e. "sched/cputime:" > The callers of steal_account_process_tick() expect it to return whether > the last jiffy was stolen or not. > > Currently the return value of steal_account_process_tick() is in units > of cputime, which vary between either jiffies or nsecs depending on > CONFIG_VIRT_CPU_ACCOUNTING_GEN. Sure, but what is the actual problem? The return value is boolean and tells whether there was stolen time accounted or not. > The fix is to change steal_account_process_tick() to always return > jiffies. If CONFIG_VIRT_CPU_ACCOUNTING_GEN is not enabled then this > is a no-op. What does that fix? > As far as I can tell this bug has been present since commit dee08a72. Which bug? > Signed-off-by: Chris Friesen <chris.friesen@windriver.com> > --- > > kernel/sched/cputime.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c > index b2ab2ff..e724496 100644 > --- a/kernel/sched/cputime.c > +++ b/kernel/sched/cputime.c > @@ -276,7 +276,7 @@ static __always_inline bool steal_account_process_tick(void) > this_rq()->prev_steal_time += cputime_to_nsecs(steal_ct); > > account_steal_time(steal_ct); > - return steal_ct; > + return cputime_to_jiffies(steal_ct); So if steal time is close to a jiffie, then cputime_to_jiffies will return 0 and you account a full jiffie to user/system/whatever. Without a proper explanation of the problem and the resulting "bug" I really cannot figure out why we want that change. Thanks, tglx ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] steal_account_process_tick() should return jiffies 2016-03-05 10:27 ` Thomas Gleixner @ 2016-03-05 13:19 ` Frederic Weisbecker 2016-03-06 4:17 ` Chris Friesen 0 siblings, 1 reply; 8+ messages in thread From: Frederic Weisbecker @ 2016-03-05 13:19 UTC (permalink / raw) To: Thomas Gleixner Cc: Chris Friesen, John Stultz, Daniel Lezcano, lkml, Peter Zijlstra, Ingo Molnar, Rik van Riel On Sat, Mar 05, 2016 at 11:27:01AM +0100, Thomas Gleixner wrote: > Chris, > > On Fri, 4 Mar 2016, Chris Friesen wrote: > > First of all the subject line should contain a subsystem prefix, > i.e. "sched/cputime:" > > > The callers of steal_account_process_tick() expect it to return whether > > the last jiffy was stolen or not. > > > > Currently the return value of steal_account_process_tick() is in units > > of cputime, which vary between either jiffies or nsecs depending on > > CONFIG_VIRT_CPU_ACCOUNTING_GEN. > > Sure, but what is the actual problem? The return value is boolean and tells > whether there was stolen time accounted or not. > > > The fix is to change steal_account_process_tick() to always return > > jiffies. If CONFIG_VIRT_CPU_ACCOUNTING_GEN is not enabled then this > > is a no-op. > > What does that fix? > > > As far as I can tell this bug has been present since commit dee08a72. > > Which bug? > > > Signed-off-by: Chris Friesen <chris.friesen@windriver.com> > > --- > > > > kernel/sched/cputime.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c > > index b2ab2ff..e724496 100644 > > --- a/kernel/sched/cputime.c > > +++ b/kernel/sched/cputime.c > > @@ -276,7 +276,7 @@ static __always_inline bool steal_account_process_tick(void) > > this_rq()->prev_steal_time += cputime_to_nsecs(steal_ct); > > > > account_steal_time(steal_ct); > > - return steal_ct; > > + return cputime_to_jiffies(steal_ct); > > So if steal time is close to a jiffie, then cputime_to_jiffies will return 0 > and you account a full jiffie to user/system/whatever. > > Without a proper explanation of the problem and the resulting "bug" I really > cannot figure out why we want that change. Indeed the changelog should better explain the problem. So I think the issue is that if the cputime has nsecs granularity and we have a tiny stolen time to account (lets say a few nanosecs, in fact anything that is below a jiffy), we are not going to account the tick on user/system. But the fix doesn't look right to me because we are still accounting the steal time if it is lower than a jiffy and that steal time will never be substracted to user/system time if it never reach a jiffy. Instead the fix should accumulate the steal time and account it only once it's worth a jiffy and then substract it from system/user time accordingly. Something like that: diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index b2ab2ff..d38e25f 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -262,7 +262,7 @@ static __always_inline bool steal_account_process_tick(void) #ifdef CONFIG_PARAVIRT if (static_key_false(¶virt_steal_enabled)) { u64 steal; - cputime_t steal_ct; + unsigned long steal_jiffies; steal = paravirt_steal_clock(smp_processor_id()); steal -= this_rq()->prev_steal_time; @@ -272,11 +272,11 @@ static __always_inline bool steal_account_process_tick(void) * based on jiffies). Lets cast the result to cputime * granularity and account the rest on the next rounds. */ - steal_ct = nsecs_to_cputime(steal); - this_rq()->prev_steal_time += cputime_to_nsecs(steal_ct); + steal_jiffies = nsecs_to_jiffies(steal); + this_rq()->prev_steal_time += jiffies_to_nsecs(steal_jiffies); account_steal_time(steal_ct); - return steal_ct; + return steal_jiffies; } #endif return false; ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] steal_account_process_tick() should return jiffies 2016-03-05 13:19 ` Frederic Weisbecker @ 2016-03-06 4:17 ` Chris Friesen 2016-03-06 5:18 ` [PATCH v2] sched/cputime: " Chris Friesen 0 siblings, 1 reply; 8+ messages in thread From: Chris Friesen @ 2016-03-06 4:17 UTC (permalink / raw) To: Frederic Weisbecker, Thomas Gleixner Cc: John Stultz, Daniel Lezcano, lkml, Peter Zijlstra, Ingo Molnar, Rik van Riel On 03/05/2016 07:19 AM, Frederic Weisbecker wrote: > On Sat, Mar 05, 2016 at 11:27:01AM +0100, Thomas Gleixner wrote: >> Chris, >> >> On Fri, 4 Mar 2016, Chris Friesen wrote: >> >> First of all the subject line should contain a subsystem prefix, >> i.e. "sched/cputime:" >> >>> The callers of steal_account_process_tick() expect it to return whether >>> the last jiffy was stolen or not. >>> >>> Currently the return value of steal_account_process_tick() is in units >>> of cputime, which vary between either jiffies or nsecs depending on >>> CONFIG_VIRT_CPU_ACCOUNTING_GEN. >> >> Sure, but what is the actual problem? The return value is boolean and tells >> whether there was stolen time accounted or not. > Indeed the changelog should better explain the problem. So I think the issue is that > if the cputime has nsecs granularity and we have a tiny stolen time to account (lets say > a few nanosecs, in fact anything that is below a jiffy), we are not going to account the > tick on user/system. Yes, this is exactly it. Because of this, if CONFIG_VIRT_CPU_ACCOUNTING_GEN is enabled in a guest then the idle/system/user stats in /proc/stat can show odd values, and "top" shows nothing for user/system even if CPU hogs are running. > But the fix doesn't look right to me because we are still accounting the steal time > if it is lower than a jiffy and that steal time will never be substracted to user/system > time if it never reach a jiffy. > > Instead the fix should accumulate the steal time and account it only once it's worth > a jiffy and then substract it from system/user time accordingly. Yes, on reflection you are correct, and the patch looks pretty close, except that account_steal_time() is still expecting units of cputime. I'll send a followup patch. > Something like that: > > diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c > index b2ab2ff..d38e25f 100644 > --- a/kernel/sched/cputime.c > +++ b/kernel/sched/cputime.c > @@ -262,7 +262,7 @@ static __always_inline bool steal_account_process_tick(void) > #ifdef CONFIG_PARAVIRT > if (static_key_false(¶virt_steal_enabled)) { > u64 steal; > - cputime_t steal_ct; > + unsigned long steal_jiffies; > > steal = paravirt_steal_clock(smp_processor_id()); > steal -= this_rq()->prev_steal_time; > @@ -272,11 +272,11 @@ static __always_inline bool steal_account_process_tick(void) > * based on jiffies). Lets cast the result to cputime > * granularity and account the rest on the next rounds. > */ > - steal_ct = nsecs_to_cputime(steal); > - this_rq()->prev_steal_time += cputime_to_nsecs(steal_ct); > + steal_jiffies = nsecs_to_jiffies(steal); > + this_rq()->prev_steal_time += jiffies_to_nsecs(steal_jiffies); > > account_steal_time(steal_ct); > - return steal_ct; > + return steal_jiffies; > } > #endif > return false; > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] sched/cputime: steal_account_process_tick() should return jiffies 2016-03-06 4:17 ` Chris Friesen @ 2016-03-06 5:18 ` Chris Friesen 2016-03-06 10:58 ` Thomas Gleixner ` (2 more replies) 0 siblings, 3 replies; 8+ messages in thread From: Chris Friesen @ 2016-03-06 5:18 UTC (permalink / raw) To: Frederic Weisbecker, Thomas Gleixner Cc: John Stultz, Daniel Lezcano, lkml, Peter Zijlstra, Ingo Molnar, Rik van Riel The callers of steal_account_process_tick() expect it to return whether a jiffy should be considered stolen or not. Currently the return value of steal_account_process_tick() is in units of cputime, which vary between either jiffies or nsecs depending on CONFIG_VIRT_CPU_ACCOUNTING_GEN. If cputime has nsecs granularity and there is a tiny amount of stolen time (a few nsecs, say) then we will consider the entire tick stolen and will not account the tick on user/system/idle, causing /proc/stats to show invalid data. The fix is to change steal_account_process_tick() to accumulate the stolen time and only account it once it's worth a jiffy. (Thanks to Frederic Weisbecker for suggestions to fix a bug in my first version of the patch.) Signed-off-by: Chris Friesen <chris.friesen@windriver.com> --- kernel/sched/cputime.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index b2ab2ff..ab2b5fb 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -262,21 +262,21 @@ static __always_inline bool steal_account_process_tick(void) #ifdef CONFIG_PARAVIRT if (static_key_false(¶virt_steal_enabled)) { u64 steal; - cputime_t steal_ct; + unsigned long steal_jiffies; steal = paravirt_steal_clock(smp_processor_id()); steal -= this_rq()->prev_steal_time; /* - * cputime_t may be less precise than nsecs (eg: if it's - * based on jiffies). Lets cast the result to cputime + * steal is in nsecs but our caller is expecting steal + * time in jiffies. Lets cast the result to jiffies * granularity and account the rest on the next rounds. */ - steal_ct = nsecs_to_cputime(steal); - this_rq()->prev_steal_time += cputime_to_nsecs(steal_ct); + steal_jiffies = nsecs_to_jiffies(steal); + this_rq()->prev_steal_time += jiffies_to_nsecs(steal_jiffies); - account_steal_time(steal_ct); - return steal_ct; + account_steal_time(jiffies_to_cputime(steal_jiffies)); + return steal_jiffies; } #endif return false; ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] sched/cputime: steal_account_process_tick() should return jiffies 2016-03-06 5:18 ` [PATCH v2] sched/cputime: " Chris Friesen @ 2016-03-06 10:58 ` Thomas Gleixner 2016-03-08 12:29 ` Frederic Weisbecker 2016-03-08 13:18 ` [tip:sched/core] sched/cputime: Fix steal_account_process_tick() to always " tip-bot for Chris Friesen 2 siblings, 0 replies; 8+ messages in thread From: Thomas Gleixner @ 2016-03-06 10:58 UTC (permalink / raw) To: Chris Friesen Cc: Frederic Weisbecker, John Stultz, Daniel Lezcano, lkml, Peter Zijlstra, Ingo Molnar, Rik van Riel On Sat, 5 Mar 2016, Chris Friesen wrote: > The callers of steal_account_process_tick() expect it to return > whether a jiffy should be considered stolen or not. > > Currently the return value of steal_account_process_tick() is in > units of cputime, which vary between either jiffies or nsecs > depending on CONFIG_VIRT_CPU_ACCOUNTING_GEN. > > If cputime has nsecs granularity and there is a tiny amount of > stolen time (a few nsecs, say) then we will consider the entire > tick stolen and will not account the tick on user/system/idle, > causing /proc/stats to show invalid data. > > The fix is to change steal_account_process_tick() to accumulate > the stolen time and only account it once it's worth a jiffy. > > (Thanks to Frederic Weisbecker for suggestions to fix a bug in my > first version of the patch.) > > Signed-off-by: Chris Friesen <chris.friesen@windriver.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] sched/cputime: steal_account_process_tick() should return jiffies 2016-03-06 5:18 ` [PATCH v2] sched/cputime: " Chris Friesen 2016-03-06 10:58 ` Thomas Gleixner @ 2016-03-08 12:29 ` Frederic Weisbecker 2016-03-08 13:18 ` [tip:sched/core] sched/cputime: Fix steal_account_process_tick() to always " tip-bot for Chris Friesen 2 siblings, 0 replies; 8+ messages in thread From: Frederic Weisbecker @ 2016-03-08 12:29 UTC (permalink / raw) To: Chris Friesen Cc: Thomas Gleixner, John Stultz, Daniel Lezcano, lkml, Peter Zijlstra, Ingo Molnar, Rik van Riel On Sat, Mar 05, 2016 at 11:18:48PM -0600, Chris Friesen wrote: > The callers of steal_account_process_tick() expect it to return > whether a jiffy should be considered stolen or not. > > Currently the return value of steal_account_process_tick() is in > units of cputime, which vary between either jiffies or nsecs > depending on CONFIG_VIRT_CPU_ACCOUNTING_GEN. > > If cputime has nsecs granularity and there is a tiny amount of > stolen time (a few nsecs, say) then we will consider the entire > tick stolen and will not account the tick on user/system/idle, > causing /proc/stats to show invalid data. > > The fix is to change steal_account_process_tick() to accumulate > the stolen time and only account it once it's worth a jiffy. > > (Thanks to Frederic Weisbecker for suggestions to fix a bug in my > first version of the patch.) > > Signed-off-by: Chris Friesen <chris.friesen@windriver.com> Acked-by: Frederic Weisbecker <fweisbec@gmail.com> Thanks Chris! ^ permalink raw reply [flat|nested] 8+ messages in thread
* [tip:sched/core] sched/cputime: Fix steal_account_process_tick() to always return jiffies 2016-03-06 5:18 ` [PATCH v2] sched/cputime: " Chris Friesen 2016-03-06 10:58 ` Thomas Gleixner 2016-03-08 12:29 ` Frederic Weisbecker @ 2016-03-08 13:18 ` tip-bot for Chris Friesen 2 siblings, 0 replies; 8+ messages in thread From: tip-bot for Chris Friesen @ 2016-03-08 13:18 UTC (permalink / raw) To: linux-tip-commits Cc: cbf123, mingo, stable, linux-kernel, peterz, torvalds, tglx, chris.friesen, hpa, fweisbec Commit-ID: f9c904b7613b8b4c85b10cd6b33ad41b2843fa9d Gitweb: http://git.kernel.org/tip/f9c904b7613b8b4c85b10cd6b33ad41b2843fa9d Author: Chris Friesen <cbf123@mail.usask.ca> AuthorDate: Sat, 5 Mar 2016 23:18:48 -0600 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Tue, 8 Mar 2016 12:24:56 +0100 sched/cputime: Fix steal_account_process_tick() to always return jiffies The callers of steal_account_process_tick() expect it to return whether a jiffy should be considered stolen or not. Currently the return value of steal_account_process_tick() is in units of cputime, which vary between either jiffies or nsecs depending on CONFIG_VIRT_CPU_ACCOUNTING_GEN. If cputime has nsecs granularity and there is a tiny amount of stolen time (a few nsecs, say) then we will consider the entire tick stolen and will not account the tick on user/system/idle, causing /proc/stats to show invalid data. The fix is to change steal_account_process_tick() to accumulate the stolen time and only account it once it's worth a jiffy. (Thanks to Frederic Weisbecker for suggestions to fix a bug in my first version of the patch.) Signed-off-by: Chris Friesen <chris.friesen@windriver.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Cc: <stable@vger.kernel.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/56DBBDB8.40305@mail.usask.ca Signed-off-by: Ingo Molnar <mingo@kernel.org> --- kernel/sched/cputime.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 01d9898..75f98c5 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -262,21 +262,21 @@ static __always_inline bool steal_account_process_tick(void) #ifdef CONFIG_PARAVIRT if (static_key_false(¶virt_steal_enabled)) { u64 steal; - cputime_t steal_ct; + unsigned long steal_jiffies; steal = paravirt_steal_clock(smp_processor_id()); steal -= this_rq()->prev_steal_time; /* - * cputime_t may be less precise than nsecs (eg: if it's - * based on jiffies). Lets cast the result to cputime + * steal is in nsecs but our caller is expecting steal + * time in jiffies. Lets cast the result to jiffies * granularity and account the rest on the next rounds. */ - steal_ct = nsecs_to_cputime(steal); - this_rq()->prev_steal_time += cputime_to_nsecs(steal_ct); + steal_jiffies = nsecs_to_jiffies(steal); + this_rq()->prev_steal_time += jiffies_to_nsecs(steal_jiffies); - account_steal_time(steal_ct); - return steal_ct; + account_steal_time(jiffies_to_cputime(steal_jiffies)); + return steal_jiffies; } #endif return false; ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2016-03-08 13:18 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-03-04 22:59 [PATCH] steal_account_process_tick() should return jiffies Chris Friesen 2016-03-05 10:27 ` Thomas Gleixner 2016-03-05 13:19 ` Frederic Weisbecker 2016-03-06 4:17 ` Chris Friesen 2016-03-06 5:18 ` [PATCH v2] sched/cputime: " Chris Friesen 2016-03-06 10:58 ` Thomas Gleixner 2016-03-08 12:29 ` Frederic Weisbecker 2016-03-08 13:18 ` [tip:sched/core] sched/cputime: Fix steal_account_process_tick() to always " tip-bot for Chris Friesen
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.