diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2014-11-28 13:23:34 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-12-08 03:42:32 -0500 |
commit | 1ce2180498fd40ed3f6485fc5daadf4b711f305f (patch) | |
tree | 5766a052dba787bb3de5e0af8e9fba0c8f1e52e1 | |
parent | 200e7c0ffb1b174a4aeaa05f7f43a91ac0fddde3 (diff) |
s390/idle: convert open coded idle time seqcount
s390 uses open coded seqcount to synchronize idle time accounting.
Lets consolidate it with the standard API.
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/include/asm/idle.h | 3 | ||||
-rw-r--r-- | arch/s390/kernel/idle.c | 24 |
2 files changed, 13 insertions, 14 deletions
diff --git a/arch/s390/include/asm/idle.h b/arch/s390/include/asm/idle.h index 6af037f574b8..113cd963dbbe 100644 --- a/arch/s390/include/asm/idle.h +++ b/arch/s390/include/asm/idle.h | |||
@@ -9,9 +9,10 @@ | |||
9 | 9 | ||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include <linux/seqlock.h> | ||
12 | 13 | ||
13 | struct s390_idle_data { | 14 | struct s390_idle_data { |
14 | unsigned int sequence; | 15 | seqcount_t seqcount; |
15 | unsigned long long idle_count; | 16 | unsigned long long idle_count; |
16 | unsigned long long idle_time; | 17 | unsigned long long idle_time; |
17 | unsigned long long clock_idle_enter; | 18 | unsigned long long clock_idle_enter; |
diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c index 8814dd9cf644..7a55c29b0b33 100644 --- a/arch/s390/kernel/idle.c +++ b/arch/s390/kernel/idle.c | |||
@@ -38,15 +38,13 @@ void enabled_wait(void) | |||
38 | trace_hardirqs_off(); | 38 | trace_hardirqs_off(); |
39 | 39 | ||
40 | /* Account time spent with enabled wait psw loaded as idle time. */ | 40 | /* Account time spent with enabled wait psw loaded as idle time. */ |
41 | idle->sequence++; | 41 | write_seqcount_begin(&idle->seqcount); |
42 | smp_wmb(); | ||
43 | idle_time = idle->clock_idle_exit - idle->clock_idle_enter; | 42 | idle_time = idle->clock_idle_exit - idle->clock_idle_enter; |
44 | idle->clock_idle_enter = idle->clock_idle_exit = 0ULL; | 43 | idle->clock_idle_enter = idle->clock_idle_exit = 0ULL; |
45 | idle->idle_time += idle_time; | 44 | idle->idle_time += idle_time; |
46 | idle->idle_count++; | 45 | idle->idle_count++; |
47 | account_idle_time(idle_time); | 46 | account_idle_time(idle_time); |
48 | smp_wmb(); | 47 | write_seqcount_end(&idle->seqcount); |
49 | idle->sequence++; | ||
50 | } | 48 | } |
51 | NOKPROBE_SYMBOL(enabled_wait); | 49 | NOKPROBE_SYMBOL(enabled_wait); |
52 | 50 | ||
@@ -55,14 +53,14 @@ static ssize_t show_idle_count(struct device *dev, | |||
55 | { | 53 | { |
56 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); | 54 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); |
57 | unsigned long long idle_count; | 55 | unsigned long long idle_count; |
58 | unsigned int sequence; | 56 | unsigned int seq; |
59 | 57 | ||
60 | do { | 58 | do { |
61 | sequence = ACCESS_ONCE(idle->sequence); | 59 | seq = read_seqcount_begin(&idle->seqcount); |
62 | idle_count = ACCESS_ONCE(idle->idle_count); | 60 | idle_count = ACCESS_ONCE(idle->idle_count); |
63 | if (ACCESS_ONCE(idle->clock_idle_enter)) | 61 | if (ACCESS_ONCE(idle->clock_idle_enter)) |
64 | idle_count++; | 62 | idle_count++; |
65 | } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); | 63 | } while (read_seqcount_retry(&idle->seqcount, seq)); |
66 | return sprintf(buf, "%llu\n", idle_count); | 64 | return sprintf(buf, "%llu\n", idle_count); |
67 | } | 65 | } |
68 | DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL); | 66 | DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL); |
@@ -72,15 +70,15 @@ static ssize_t show_idle_time(struct device *dev, | |||
72 | { | 70 | { |
73 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); | 71 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); |
74 | unsigned long long now, idle_time, idle_enter, idle_exit; | 72 | unsigned long long now, idle_time, idle_enter, idle_exit; |
75 | unsigned int sequence; | 73 | unsigned int seq; |
76 | 74 | ||
77 | do { | 75 | do { |
78 | now = get_tod_clock(); | 76 | now = get_tod_clock(); |
79 | sequence = ACCESS_ONCE(idle->sequence); | 77 | seq = read_seqcount_begin(&idle->seqcount); |
80 | idle_time = ACCESS_ONCE(idle->idle_time); | 78 | idle_time = ACCESS_ONCE(idle->idle_time); |
81 | idle_enter = ACCESS_ONCE(idle->clock_idle_enter); | 79 | idle_enter = ACCESS_ONCE(idle->clock_idle_enter); |
82 | idle_exit = ACCESS_ONCE(idle->clock_idle_exit); | 80 | idle_exit = ACCESS_ONCE(idle->clock_idle_exit); |
83 | } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); | 81 | } while (read_seqcount_retry(&idle->seqcount, seq)); |
84 | idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0; | 82 | idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0; |
85 | return sprintf(buf, "%llu\n", idle_time >> 12); | 83 | return sprintf(buf, "%llu\n", idle_time >> 12); |
86 | } | 84 | } |
@@ -90,14 +88,14 @@ cputime64_t arch_cpu_idle_time(int cpu) | |||
90 | { | 88 | { |
91 | struct s390_idle_data *idle = &per_cpu(s390_idle, cpu); | 89 | struct s390_idle_data *idle = &per_cpu(s390_idle, cpu); |
92 | unsigned long long now, idle_enter, idle_exit; | 90 | unsigned long long now, idle_enter, idle_exit; |
93 | unsigned int sequence; | 91 | unsigned int seq; |
94 | 92 | ||
95 | do { | 93 | do { |
96 | now = get_tod_clock(); | 94 | now = get_tod_clock(); |
97 | sequence = ACCESS_ONCE(idle->sequence); | 95 | seq = read_seqcount_begin(&idle->seqcount); |
98 | idle_enter = ACCESS_ONCE(idle->clock_idle_enter); | 96 | idle_enter = ACCESS_ONCE(idle->clock_idle_enter); |
99 | idle_exit = ACCESS_ONCE(idle->clock_idle_exit); | 97 | idle_exit = ACCESS_ONCE(idle->clock_idle_exit); |
100 | } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); | 98 | } while (read_seqcount_retry(&idle->seqcount, seq)); |
101 | return idle_enter ? ((idle_exit ?: now) - idle_enter) : 0; | 99 | return idle_enter ? ((idle_exit ?: now) - idle_enter) : 0; |
102 | } | 100 | } |
103 | 101 | ||