Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751213AbcCFFSy (ORCPT ); Sun, 6 Mar 2016 00:18:54 -0500 Received: from smtp-out-so.shaw.ca ([64.59.136.139]:60381 "EHLO smtp-out-so.shaw.ca" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751089AbcCFFSx (ORCPT ); Sun, 6 Mar 2016 00:18:53 -0500 X-Authority-Analysis: v=2.1 cv=Daa30qZW c=1 sm=1 tr=0 a=b4X6fhI4x5MOnsgcuOa5CA==:117 a=b4X6fhI4x5MOnsgcuOa5CA==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=IkcTkHD0fZMA:10 a=t7CeM3EgAAAA:8 a=taYu8qRJNXKctufLHD4A:9 a=QEXdDO2ut3YA:10 Message-ID: <56DBBDB8.40305@mail.usask.ca> Date: Sat, 05 Mar 2016 23:18:48 -0600 From: Chris Friesen User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 MIME-Version: 1.0 To: Frederic Weisbecker , Thomas Gleixner CC: John Stultz , Daniel Lezcano , lkml , Peter Zijlstra , Ingo Molnar , Rik van Riel Subject: [PATCH v2] sched/cputime: steal_account_process_tick() should return jiffies References: <56DA1339.5030601@mail.usask.ca> <20160305131856.GA4441@lerouge> <56DBAF6D.5010503@mail.usask.ca> In-Reply-To: <56DBAF6D.5010503@mail.usask.ca> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-CMAE-Envelope: MS4wfPZnOvQPxM1CZn/a14cJ9CR1Jvl/abvTcCJ7xTppzGj74X4cP1wgkyDhRLgdiSfV/Qy6DXkGVlHPQUqX/jivwk+SDjtWacxebZSopDiGbwhg3snL//N5 YZA/m5Yd7PUY5iv3+wwfRwQp/LI9N9to1WMrkXXvvLX3O4VxgmgQdhmNbi+RZCy1+ENP8nqHibWNH10fPzs68eiwekQk5+iSvZGdUOekIsP1j/yZkHt6ZH9M N+uyCQQ3sAgqhIqqM7xfHg1PvlPqA/fhDK33x9AHQXYdjLrELLrCtpE9cFmGiYZ9K2fwID80egwX07OL39awgOJd7VAsAXKPON+ShV8+T4Mf9ngFGx0VsfVG JKal7Zd5LouhuzPdPwN057QhXQ0x+VDzpsoIefbn3EgAzGHXrmw= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2052 Lines: 56 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 --- 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;