All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mats Liljegren <mats.liljegren@enea.com>
To: Kevin Hilman <khilman@linaro.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>,
	Ingo Molnar <mingo@kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Li Zhong <zhong@linux.vnet.ibm.com>,
	Namhyung Kim <namhyung.kim@lge.com>,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
	Paul Gortmaker <paul.gortmaker@windriver.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Sedat Dilek <sedat.dilek@gmail.com>,
	Gleb Natapov <gleb@redhat.com>,
	Marcelo Tosatti <mtosatti@redhat.com>,
	Tony Luck <tony.luck@intel.com>,
	Fenghua Yu <fenghua.yu@intel.com>
Subject: Re: [GIT PULL] cputime: Full dynticks task/cputime accounting v7
Date: Fri, 15 Feb 2013 15:04:29 +0100	[thread overview]
Message-ID: <20130215140429.GA4322@enea.se> (raw)
In-Reply-To: <87k3qa7333.fsf@linaro.org>

Kevin Hilman wrote:
> Frederic Weisbecker <fweisbec@gmail.com> writes:
> 
> > Ingo,
> >
> > Please pull the new full dynticks cputime accounting code that
> > can be found at:
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks.git
> > 	tags/full-dynticks-cputime-for-mingo
> >
> > My last concern is the dependency on CONFIG_64BIT. We rely on cputime_t
> > being u64 for reasonable nanosec granularity implementation. And therefore
> > we need a single instruction fetch to read kernel cpustat for atomicity
> > requirement against concurrent incrementation, which only 64 bit archs
> > can provide.
> 
> Actually, moderately recent 32-bit ARMs can do atomic 64-bit load/stores
> too.   
> 
> Also, is it just kernel_cpustat increments that need protection? or do
> the various reads of the task_struct's cputime fields also need
> protection (hmm, thinking twice, maybe those are already sufficiently
> protected by the vtime_seqlock?)
> 
> > It's probably no big deal to solve this issue. What we need is simply some
> > atomic accessors.
> 
> What about using the atomic64_* accessors?  Those would just use the
> native loads/stores on arches that have them, otherwise
> CONFIG_GENERIC_ATOMIC64 provides some fallbacks.
> 
> To give it a try, below is a quick patch to convert kernel_cpustat to
> atomic64.  I only got as far as compile testing and basic boot testing
> on a 32-bit ARM platform, but let me know if this is the right
> direction.
> 
> > There is just no emergency though as this new option depends on the context
> > tracking subsystem that only x86-64 (and soon ppc64) implements yet. And
> > this set is complex enough already. I think we can deal with that later.
> 
> I've started working on the ARM version of the context_tracker, so
> "later" is coming quickly and I will do what I can to help this along.
> 
> Kevin
> 
> 
> 
> >From 9881fc4b86a63244018a4bdb5a383f3b862a0b8b Mon Sep 17 00:00:00 2001
> From: Kevin Hilman <khilman@linaro.org>
> Date: Thu, 14 Feb 2013 17:46:08 -0800
> Subject: [PATCH] kernel_cpustat: convert to atomic 64-bit accessors
> 
> WIP: only compile tested and basic boot tested on 32-bit ARM platform
> ---
>  fs/proc/stat.c              | 36 ++++++++++++++++++------------------
>  fs/proc/uptime.c            |  2 +-
>  include/linux/kernel_stat.h |  2 +-
>  kernel/sched/cputime.c      | 22 +++++++++++-----------
>  4 files changed, 31 insertions(+), 31 deletions(-)
> 
> diff --git a/fs/proc/stat.c b/fs/proc/stat.c
> index e296572..2a4c723 100644
> --- a/fs/proc/stat.c
> +++ b/fs/proc/stat.c
> @@ -52,7 +52,7 @@ static u64 get_idle_time(int cpu)
>  
>  	if (idle_time == -1ULL)
>  		/* !NO_HZ or cpu offline so we can rely on cpustat.idle */
> -		idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
> +		idle = atomic64_read(&kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]);
>  	else
>  		idle = usecs_to_cputime64(idle_time);
>  
> @@ -68,7 +68,7 @@ static u64 get_iowait_time(int cpu)
>  
>  	if (iowait_time == -1ULL)
>  		/* !NO_HZ or cpu offline so we can rely on cpustat.iowait */
> -		iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT];
> +		iowait = atomic64_read(&kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT]);
>  	else
>  		iowait = usecs_to_cputime64(iowait_time);
>  
> @@ -95,16 +95,16 @@ static int show_stat(struct seq_file *p, void *v)
>  	jif = boottime.tv_sec;
>  
>  	for_each_possible_cpu(i) {
> -		user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
> -		nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE];
> -		system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
> +		user += atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_USER]);
> +		nice += atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_NICE]);
> +		system += atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM]);
>  		idle += get_idle_time(i);
>  		iowait += get_iowait_time(i);
> -		irq += kcpustat_cpu(i).cpustat[CPUTIME_IRQ];
> -		softirq += kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ];
> -		steal += kcpustat_cpu(i).cpustat[CPUTIME_STEAL];
> -		guest += kcpustat_cpu(i).cpustat[CPUTIME_GUEST];
> -		guest_nice += kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE];
> +		irq += atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_IRQ]);
> +		softirq += atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ]);
> +		steal += atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_STEAL]);
> +		guest += atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_GUEST]);
> +		guest_nice += atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE]);
>  		sum += kstat_cpu_irqs_sum(i);
>  		sum += arch_irq_stat_cpu(i);
>  
> @@ -132,16 +132,16 @@ static int show_stat(struct seq_file *p, void *v)
>  
>  	for_each_online_cpu(i) {
>  		/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
> -		user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
> -		nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE];
> -		system = kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
> +		user = atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_USER]);
> +		nice = atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_NICE]);
> +		system = atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM]);
>  		idle = get_idle_time(i);
>  		iowait = get_iowait_time(i);
> -		irq = kcpustat_cpu(i).cpustat[CPUTIME_IRQ];
> -		softirq = kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ];
> -		steal = kcpustat_cpu(i).cpustat[CPUTIME_STEAL];
> -		guest = kcpustat_cpu(i).cpustat[CPUTIME_GUEST];
> -		guest_nice = kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE];
> +		irq = atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_IRQ]);
> +		softirq = atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ]);
> +		steal = atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_STEAL]);
> +		guest = atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_GUEST]);
> +		guest_nice = atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE]);
>  		seq_printf(p, "cpu%d", i);
>  		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(user));
>  		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(nice));
> diff --git a/fs/proc/uptime.c b/fs/proc/uptime.c
> index 9610ac7..10c0f6e 100644
> --- a/fs/proc/uptime.c
> +++ b/fs/proc/uptime.c
> @@ -18,7 +18,7 @@ static int uptime_proc_show(struct seq_file *m, void *v)
>  
>  	idletime = 0;
>  	for_each_possible_cpu(i)
> -		idletime += (__force u64) kcpustat_cpu(i).cpustat[CPUTIME_IDLE];
> +		idletime += atomic64_read(&kcpustat_cpu(i).cpustat[CPUTIME_IDLE]);
>  
>  	do_posix_clock_monotonic_gettime(&uptime);
>  	monotonic_to_bootbased(&uptime);
> diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
> index ed5f6ed..45b9f71 100644
> --- a/include/linux/kernel_stat.h
> +++ b/include/linux/kernel_stat.h
> @@ -32,7 +32,7 @@ enum cpu_usage_stat {
>  };
>  
>  struct kernel_cpustat {
> -	u64 cpustat[NR_STATS];
> +	atomic64_t cpustat[NR_STATS];
>  };
>  
>  struct kernel_stat {
> diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
> index ccff275..c1ac2b2 100644
> --- a/kernel/sched/cputime.c
> +++ b/kernel/sched/cputime.c
> @@ -125,7 +125,7 @@ static inline void task_group_account_field(struct task_struct *p, int index,
>  	 * is the only cgroup, then nothing else should be necessary.
>  	 *
>  	 */
> -	__get_cpu_var(kernel_cpustat).cpustat[index] += tmp;
> +	atomic64_add(tmp, &__get_cpu_var(kernel_cpustat).cpustat[index]);
>  
>  #ifdef CONFIG_CGROUP_CPUACCT
>  	if (unlikely(!cpuacct_subsys.active))
> @@ -176,7 +176,7 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
>  static void account_guest_time(struct task_struct *p, cputime_t cputime,
>  			       cputime_t cputime_scaled)
>  {
> -	u64 *cpustat = kcpustat_this_cpu->cpustat;
> +	atomic64_t *cpustat = kcpustat_this_cpu->cpustat;
>  
>  	/* Add guest time to process. */
>  	p->utime += cputime;
> @@ -186,11 +186,11 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime,
>  
>  	/* Add guest time to cpustat. */
>  	if (TASK_NICE(p) > 0) {
> -		cpustat[CPUTIME_NICE] += (__force u64) cputime;
> -		cpustat[CPUTIME_GUEST_NICE] += (__force u64) cputime;
> +		atomic64_add((__force u64) cputime, &cpustat[CPUTIME_NICE]);
> +		atomic64_add((__force u64) cputime, &cpustat[CPUTIME_GUEST_NICE]);
>  	} else {
> -		cpustat[CPUTIME_USER] += (__force u64) cputime;
> -		cpustat[CPUTIME_GUEST] += (__force u64) cputime;
> +		atomic64_add((__force u64) cputime, &cpustat[CPUTIME_USER]);
> +		atomic64_add((__force u64) cputime, &cpustat[CPUTIME_GUEST]);
>  	}
>  }
>  
> @@ -250,9 +250,9 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
>   */
>  void account_steal_time(cputime_t cputime)
>  {
> -	u64 *cpustat = kcpustat_this_cpu->cpustat;
> +	atomic64_t *cpustat = kcpustat_this_cpu->cpustat;
>  
> -	cpustat[CPUTIME_STEAL] += (__force u64) cputime;
> +	atomic64_add((__force u64) cputime, &cpustat[CPUTIME_STEAL]);
>  }
>  
>  /*
> @@ -261,13 +261,13 @@ void account_steal_time(cputime_t cputime)
>   */
>  void account_idle_time(cputime_t cputime)
>  {
> -	u64 *cpustat = kcpustat_this_cpu->cpustat;
> +	atomic64_t *cpustat = kcpustat_this_cpu->cpustat;
>  	struct rq *rq = this_rq();
>  
>  	if (atomic_read(&rq->nr_iowait) > 0)
> -		cpustat[CPUTIME_IOWAIT] += (__force u64) cputime;
> +		atomic64_add((__force u64) cputime, &cpustat[CPUTIME_IOWAIT]);
>  	else
> -		cpustat[CPUTIME_IDLE] += (__force u64) cputime;
> +		atomic64_add((__force u64) cputime, &cpustat[CPUTIME_IDLE]);
>  }
>  
>  static __always_inline bool steal_account_process_tick(void)
> -- 
> 1.8.1.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

I had to do some changes to get it to compile. You can check my patch below
and see whether I got it all wrong...

/Mats

>From e3da56bdb36a3efb5a9869ded20f346039f381f2 Mon Sep 17 00:00:00 2001
From: Mats Liljegren <mats.liljegren@enea.com>
Date: Fri, 15 Feb 2013 13:46:29 +0100
Subject: [PATCH] Added atomic operators to make it compile

---
 kernel/sched/core.c    |   10 +++++-----
 kernel/sched/cputime.c |    2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 2fad439..5415e85 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -8168,8 +8168,8 @@ static int cpuacct_stats_show(struct cgroup *cgrp, struct cftype *cft,
 
        for_each_online_cpu(cpu) {
                struct kernel_cpustat *kcpustat = per_cpu_ptr(ca->cpustat, cpu);
-               val += kcpustat->cpustat[CPUTIME_USER];
-               val += kcpustat->cpustat[CPUTIME_NICE];
+               val += atomic64_read(&kcpustat->cpustat[CPUTIME_USER]);
+               val += atomic64_read(&kcpustat->cpustat[CPUTIME_NICE]);
        }
        val = cputime64_to_clock_t(val);
        cb->fill(cb, cpuacct_stat_desc[CPUACCT_STAT_USER], val);
@@ -8177,9 +8177,9 @@ static int cpuacct_stats_show(struct cgroup *cgrp, struct cftype *cft,
        val = 0;
        for_each_online_cpu(cpu) {
                struct kernel_cpustat *kcpustat = per_cpu_ptr(ca->cpustat, cpu);
-               val += kcpustat->cpustat[CPUTIME_SYSTEM];
-               val += kcpustat->cpustat[CPUTIME_IRQ];
-               val += kcpustat->cpustat[CPUTIME_SOFTIRQ];
+               val += atomic64_read(&kcpustat->cpustat[CPUTIME_SYSTEM]);
+               val += atomic64_read(&kcpustat->cpustat[CPUTIME_IRQ]);
+               val += atomic64_read(&kcpustat->cpustat[CPUTIME_SOFTIRQ]);
        }
 
        val = cputime64_to_clock_t(val);
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 50de5bf..2bb998b 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -135,7 +135,7 @@ static inline void task_group_account_field(struct task_struct *p, int index,
        ca = task_ca(p);
        while (ca && (ca != &root_cpuacct)) {
                kcpustat = this_cpu_ptr(ca->cpustat);
-               kcpustat->cpustat[index] += tmp;
+               atomic64_add(tmp, &kcpustat->cpustat[index]);
                ca = parent_ca(ca);
        }
        rcu_read_unlock();
-- 
1.7.5.4

  reply	other threads:[~2013-02-15 14:04 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-28 19:03 [GIT PULL] cputime: Full dynticks task/cputime accounting v7 Frederic Weisbecker
2013-01-28 19:03 ` [PATCH 1/8] context_tracking: Export context state for generic vtime Frederic Weisbecker
2013-01-28 19:03 ` [PATCH 2/8] cputime: Librarize per nsecs resolution cputime definitions Frederic Weisbecker
2013-02-14 19:49   ` Kevin Hilman
2013-02-20 16:07     ` Frederic Weisbecker
2013-01-28 19:04 ` [PATCH 3/8] cputime: Move default nsecs_to_cputime() to jiffies based cputime file Frederic Weisbecker
2013-01-28 19:04 ` [PATCH 4/8] cputime: Generic on-demand virtual cputime accounting Frederic Weisbecker
2013-02-08  3:07   ` Stephen Rothwell
2013-02-08  3:07     ` Stephen Rothwell
2013-02-08  3:14     ` Stephen Rothwell
2013-02-08  3:14       ` Stephen Rothwell
2013-02-08  3:19       ` [PATCH] cputime: restore CPU_ACCOUNTING config defaults for PPC64 Stephen Rothwell
2013-02-08  3:19         ` Stephen Rothwell
2013-02-08 15:18         ` [tip:sched/core] cputime: Restore " tip-bot for Stephen Rothwell
2013-02-08 15:18           ` tip-bot for Stephen Rothwell
2013-02-08 14:31       ` [PATCH 4/8] cputime: Generic on-demand virtual cputime accounting Frederic Weisbecker
2013-02-08 14:31         ` Frederic Weisbecker
2013-01-28 19:04 ` [PATCH 5/8] cputime: Allow dynamic switch between tick/virtual based " Frederic Weisbecker
2013-01-28 19:04 ` [PATCH 6/8] cputime: Use accessors to read task cputime stats Frederic Weisbecker
2013-01-28 19:04 ` [PATCH 7/8] kvm: Prepare to add generic guest entry/exit callbacks Frederic Weisbecker
2013-01-28 19:04 ` [PATCH 8/8] cputime: Safely read cputime of full dynticks CPUs Frederic Weisbecker
2013-01-28 21:51   ` Sedat Dilek
2013-01-30 21:57     ` Sedat Dilek
2013-01-31  0:38     ` Frederic Weisbecker
2013-01-31  7:24       ` Sedat Dilek
2013-01-31 10:12         ` Frederic Weisbecker
2013-01-31 10:30           ` Sedat Dilek
2013-01-31 16:29             ` Frederic Weisbecker
2013-01-28 19:18 ` [GIT PULL] cputime: Full dynticks task/cputime accounting v7 Christoph Lameter
2013-01-28 19:21   ` Frederic Weisbecker
2013-01-28 20:14     ` Christoph Lameter
2013-01-29  1:42       ` Frederic Weisbecker
2013-01-29  0:02 ` Steven Rostedt
2013-01-29  1:36   ` Frederic Weisbecker
2013-01-29  2:36   ` Steven Rostedt
2013-01-29  2:39     ` Frederic Weisbecker
2013-01-29  2:44       ` Steven Rostedt
2013-01-29  3:29         ` Frederic Weisbecker
2013-01-29  4:38           ` Steven Rostedt
2013-01-29 15:12             ` Frederic Weisbecker
2013-01-29 16:46               ` Steven Rostedt
2013-01-29 16:55                 ` Frederic Weisbecker
2013-01-29 17:08                   ` Steven Rostedt
2013-01-29 21:26     ` Steven Rostedt
2013-01-29 21:37       ` Frederic Weisbecker
2013-02-15  1:55 ` Kevin Hilman
2013-02-15 14:04   ` Mats Liljegren [this message]
2013-02-15 15:06     ` Kevin Hilman
2013-02-20 15:53     ` Frederic Weisbecker
2013-02-20 17:53       ` Kevin Hilman
2013-02-20 15:44   ` Frederic Weisbecker
2013-02-20 18:48     ` Kevin Hilman

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=20130215140429.GA4322@enea.se \
    --to=mats.liljegren@enea.com \
    --cc=akpm@linux-foundation.org \
    --cc=fenghua.yu@intel.com \
    --cc=fweisbec@gmail.com \
    --cc=gleb@redhat.com \
    --cc=khilman@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=mtosatti@redhat.com \
    --cc=namhyung.kim@lge.com \
    --cc=paul.gortmaker@windriver.com \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=sedat.dilek@gmail.com \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@intel.com \
    --cc=zhong@linux.vnet.ibm.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.