aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRik van Riel <riel@redhat.com>2014-09-30 15:59:47 -0400
committerIngo Molnar <mingo@kernel.org>2014-10-02 23:46:55 -0400
commit347abad981c1ef815ea5ba861adba6a8c6aa1580 (patch)
treeea18690dcb71d23c29a92a602c1d5373f9360e7a
parent43f4d66637bc752e93a77ff2536474a5a3888442 (diff)
sched, time: Fix build error with 64 bit cputime_t on 32 bit systems
On 32 bit systems cmpxchg cannot handle 64 bit values, so some additional magic is required to allow a 32 bit system with CONFIG_VIRT_CPU_ACCOUNTING_GEN=y enabled to build. Make sure the correct cmpxchg function is used when doing an atomic swap of a cputime_t. Reported-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Rik van Riel <riel@redhat.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: umgwanakikbuti@gmail.com Cc: fweisbec@gmail.com Cc: srao@redhat.com Cc: lwoodman@redhat.com Cc: atheurer@redhat.com Cc: oleg@redhat.com Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Paul Mackerras <paulus@samba.org> Cc: linux390@de.ibm.com Cc: linux-arch@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-s390@vger.kernel.org Link: http://lkml.kernel.org/r/20140930155947.070cdb1f@annuminas.surriel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/powerpc/include/asm/cputime.h2
-rw-r--r--arch/s390/include/asm/cputime.h2
-rw-r--r--include/asm-generic/cputime_jiffies.h2
-rw-r--r--include/asm-generic/cputime_nsecs.h2
-rw-r--r--kernel/sched/cputime.c29
5 files changed, 27 insertions, 10 deletions
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h
index 607559ab271f..6c840ceab820 100644
--- a/arch/powerpc/include/asm/cputime.h
+++ b/arch/powerpc/include/asm/cputime.h
@@ -32,6 +32,8 @@ static inline void setup_cputime_one_jiffy(void) { }
32typedef u64 __nocast cputime_t; 32typedef u64 __nocast cputime_t;
33typedef u64 __nocast cputime64_t; 33typedef u64 __nocast cputime64_t;
34 34
35#define cmpxchg_cputime(ptr, old, new) cmpxchg(ptr, old, new)
36
35#ifdef __KERNEL__ 37#ifdef __KERNEL__
36 38
37/* 39/*
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index f65bd3634519..3001887f94b7 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -18,6 +18,8 @@
18typedef unsigned long long __nocast cputime_t; 18typedef unsigned long long __nocast cputime_t;
19typedef unsigned long long __nocast cputime64_t; 19typedef unsigned long long __nocast cputime64_t;
20 20
21#define cmpxchg_cputime(ptr, old, new) cmpxchg64(ptr, old, new)
22
21static inline unsigned long __div(unsigned long long n, unsigned long base) 23static inline unsigned long __div(unsigned long long n, unsigned long base)
22{ 24{
23#ifndef CONFIG_64BIT 25#ifndef CONFIG_64BIT
diff --git a/include/asm-generic/cputime_jiffies.h b/include/asm-generic/cputime_jiffies.h
index d5cb78f53986..fe386fc6e85e 100644
--- a/include/asm-generic/cputime_jiffies.h
+++ b/include/asm-generic/cputime_jiffies.h
@@ -3,6 +3,8 @@
3 3
4typedef unsigned long __nocast cputime_t; 4typedef unsigned long __nocast cputime_t;
5 5
6#define cmpxchg_cputime(ptr, old, new) cmpxchg(ptr, old, new)
7
6#define cputime_one_jiffy jiffies_to_cputime(1) 8#define cputime_one_jiffy jiffies_to_cputime(1)
7#define cputime_to_jiffies(__ct) (__force unsigned long)(__ct) 9#define cputime_to_jiffies(__ct) (__force unsigned long)(__ct)
8#define cputime_to_scaled(__ct) (__ct) 10#define cputime_to_scaled(__ct) (__ct)
diff --git a/include/asm-generic/cputime_nsecs.h b/include/asm-generic/cputime_nsecs.h
index 4e817606c549..0419485891f2 100644
--- a/include/asm-generic/cputime_nsecs.h
+++ b/include/asm-generic/cputime_nsecs.h
@@ -21,6 +21,8 @@
21typedef u64 __nocast cputime_t; 21typedef u64 __nocast cputime_t;
22typedef u64 __nocast cputime64_t; 22typedef u64 __nocast cputime64_t;
23 23
24#define cmpxchg_cputime(ptr, old, new) cmpxchg64(ptr, old, new)
25
24#define cputime_one_jiffy jiffies_to_cputime(1) 26#define cputime_one_jiffy jiffies_to_cputime(1)
25 27
26#define cputime_div(__ct, divisor) div_u64((__force u64)__ct, divisor) 28#define cputime_div(__ct, divisor) div_u64((__force u64)__ct, divisor)
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 64492dff8a81..8394b1ee600c 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -555,6 +555,23 @@ drop_precision:
555} 555}
556 556
557/* 557/*
558 * Atomically advance counter to the new value. Interrupts, vcpu
559 * scheduling, and scaling inaccuracies can cause cputime_advance
560 * to be occasionally called with a new value smaller than counter.
561 * Let's enforce atomicity.
562 *
563 * Normally a caller will only go through this loop once, or not
564 * at all in case a previous caller updated counter the same jiffy.
565 */
566static void cputime_advance(cputime_t *counter, cputime_t new)
567{
568 cputime_t old;
569
570 while (new > (old = ACCESS_ONCE(*counter)))
571 cmpxchg_cputime(counter, old, new);
572}
573
574/*
558 * Adjust tick based cputime random precision against scheduler 575 * Adjust tick based cputime random precision against scheduler
559 * runtime accounting. 576 * runtime accounting.
560 */ 577 */
@@ -599,16 +616,8 @@ static void cputime_adjust(struct task_cputime *curr,
599 utime = rtime - stime; 616 utime = rtime - stime;
600 } 617 }
601 618
602 /* 619 cputime_advance(&prev->stime, stime);
603 * If the tick based count grows faster than the scheduler one, 620 cputime_advance(&prev->utime, utime);
604 * the result of the scaling may go backward.
605 * Let's enforce monotonicity.
606 * Atomic exchange protects against concurrent cputime_adjust().
607 */
608 while (stime > (rtime = ACCESS_ONCE(prev->stime)))
609 cmpxchg(&prev->stime, rtime, stime);
610 while (utime > (rtime = ACCESS_ONCE(prev->utime)))
611 cmpxchg(&prev->utime, rtime, utime);
612 621
613out: 622out:
614 *ut = prev->utime; 623 *ut = prev->utime;