diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-12 18:16:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-12 18:16:26 -0400 |
commit | ccb1ec95e924a24906ef01ce6d028a8dc13dc87d (patch) | |
tree | b16a02083ba6843fe3f2513f74a72c95d43ddccb | |
parent | 4a1d7544fee5e601a4e642ce2720689f90428d65 (diff) | |
parent | d48fc63f6f3f485ed5aa9cf019d8e8e3a7d10263 (diff) |
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fixes from Thomas Gleixner:
"The itimer removal one is not strictly a fix, but I really wanted to
avoid a rebase of the urgent ones."
* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
Revert "clocksource: Load the ACPI PM clocksource asynchronously"
clockevents: tTack broadcast device mode change in tick_broadcast_switch_to_oneshot()
itimer: Use printk_once instead of WARN_ONCE
nohz: Fix stale jiffies update in tick_nohz_restart()
tick: Document TICK_ONESHOT config option
proc: stats: Use arch_idle_time for idle and iowait times if available
itimer: Schedule silent NULL pointer fixup in setitimer() for removal
-rw-r--r-- | Documentation/feature-removal-schedule.txt | 8 | ||||
-rw-r--r-- | drivers/clocksource/acpi_pm.c | 24 | ||||
-rw-r--r-- | fs/proc/stat.c | 34 | ||||
-rw-r--r-- | kernel/itimer.c | 8 | ||||
-rw-r--r-- | kernel/time/Kconfig | 4 | ||||
-rw-r--r-- | kernel/time/tick-broadcast.c | 4 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 4 |
7 files changed, 59 insertions, 27 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 709e08e9a222..03ca210406ed 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -531,3 +531,11 @@ Why: There appear to be no production users of the get_robust_list syscall, | |||
531 | of ASLR. It was only ever intended for debugging, so it should be | 531 | of ASLR. It was only ever intended for debugging, so it should be |
532 | removed. | 532 | removed. |
533 | Who: Kees Cook <keescook@chromium.org> | 533 | Who: Kees Cook <keescook@chromium.org> |
534 | |||
535 | ---------------------------- | ||
536 | |||
537 | What: setitimer accepts user NULL pointer (value) | ||
538 | When: 3.6 | ||
539 | Why: setitimer is not returning -EFAULT if user pointer is NULL. This | ||
540 | violates the spec. | ||
541 | Who: Sasikantha Babu <sasikanth.v19@gmail.com> | ||
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 82e882028fcf..6b5cf02c35c8 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/async.h> | ||
27 | #include <asm/io.h> | 26 | #include <asm/io.h> |
28 | 27 | ||
29 | /* | 28 | /* |
@@ -180,15 +179,17 @@ static int verify_pmtmr_rate(void) | |||
180 | /* Number of reads we try to get two different values */ | 179 | /* Number of reads we try to get two different values */ |
181 | #define ACPI_PM_READ_CHECKS 10000 | 180 | #define ACPI_PM_READ_CHECKS 10000 |
182 | 181 | ||
183 | static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie) | 182 | static int __init init_acpi_pm_clocksource(void) |
184 | { | 183 | { |
185 | cycle_t value1, value2; | 184 | cycle_t value1, value2; |
186 | unsigned int i, j = 0; | 185 | unsigned int i, j = 0; |
187 | 186 | ||
187 | if (!pmtmr_ioport) | ||
188 | return -ENODEV; | ||
188 | 189 | ||
189 | /* "verify" this timing source: */ | 190 | /* "verify" this timing source: */ |
190 | for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { | 191 | for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { |
191 | usleep_range(100 * j, 100 * j + 100); | 192 | udelay(100 * j); |
192 | value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm); | 193 | value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm); |
193 | for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { | 194 | for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { |
194 | value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm); | 195 | value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm); |
@@ -202,34 +203,25 @@ static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie | |||
202 | " 0x%#llx, 0x%#llx - aborting.\n", | 203 | " 0x%#llx, 0x%#llx - aborting.\n", |
203 | value1, value2); | 204 | value1, value2); |
204 | pmtmr_ioport = 0; | 205 | pmtmr_ioport = 0; |
205 | return; | 206 | return -EINVAL; |
206 | } | 207 | } |
207 | if (i == ACPI_PM_READ_CHECKS) { | 208 | if (i == ACPI_PM_READ_CHECKS) { |
208 | printk(KERN_INFO "PM-Timer failed consistency check " | 209 | printk(KERN_INFO "PM-Timer failed consistency check " |
209 | " (0x%#llx) - aborting.\n", value1); | 210 | " (0x%#llx) - aborting.\n", value1); |
210 | pmtmr_ioport = 0; | 211 | pmtmr_ioport = 0; |
211 | return; | 212 | return -ENODEV; |
212 | } | 213 | } |
213 | } | 214 | } |
214 | 215 | ||
215 | if (verify_pmtmr_rate() != 0){ | 216 | if (verify_pmtmr_rate() != 0){ |
216 | pmtmr_ioport = 0; | 217 | pmtmr_ioport = 0; |
217 | return; | 218 | return -ENODEV; |
218 | } | 219 | } |
219 | 220 | ||
220 | clocksource_register_hz(&clocksource_acpi_pm, | 221 | return clocksource_register_hz(&clocksource_acpi_pm, |
221 | PMTMR_TICKS_PER_SEC); | 222 | PMTMR_TICKS_PER_SEC); |
222 | } | 223 | } |
223 | 224 | ||
224 | static int __init init_acpi_pm_clocksource(void) | ||
225 | { | ||
226 | if (!pmtmr_ioport) | ||
227 | return -ENODEV; | ||
228 | |||
229 | async_schedule(acpi_pm_clocksource_async, NULL); | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | /* We use fs_initcall because we want the PCI fixups to have run | 225 | /* We use fs_initcall because we want the PCI fixups to have run |
234 | * but we still need to load before device_initcall | 226 | * but we still need to load before device_initcall |
235 | */ | 227 | */ |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 6a0c62d6e442..64c3b3172367 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -18,19 +18,39 @@ | |||
18 | #ifndef arch_irq_stat | 18 | #ifndef arch_irq_stat |
19 | #define arch_irq_stat() 0 | 19 | #define arch_irq_stat() 0 |
20 | #endif | 20 | #endif |
21 | #ifndef arch_idle_time | 21 | |
22 | #define arch_idle_time(cpu) 0 | 22 | #ifdef arch_idle_time |
23 | #endif | 23 | |
24 | static cputime64_t get_idle_time(int cpu) | ||
25 | { | ||
26 | cputime64_t idle; | ||
27 | |||
28 | idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; | ||
29 | if (cpu_online(cpu) && !nr_iowait_cpu(cpu)) | ||
30 | idle += arch_idle_time(cpu); | ||
31 | return idle; | ||
32 | } | ||
33 | |||
34 | static cputime64_t get_iowait_time(int cpu) | ||
35 | { | ||
36 | cputime64_t iowait; | ||
37 | |||
38 | iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT]; | ||
39 | if (cpu_online(cpu) && nr_iowait_cpu(cpu)) | ||
40 | iowait += arch_idle_time(cpu); | ||
41 | return iowait; | ||
42 | } | ||
43 | |||
44 | #else | ||
24 | 45 | ||
25 | static u64 get_idle_time(int cpu) | 46 | static u64 get_idle_time(int cpu) |
26 | { | 47 | { |
27 | u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL); | 48 | u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL); |
28 | 49 | ||
29 | if (idle_time == -1ULL) { | 50 | if (idle_time == -1ULL) |
30 | /* !NO_HZ so we can rely on cpustat.idle */ | 51 | /* !NO_HZ so we can rely on cpustat.idle */ |
31 | idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; | 52 | idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; |
32 | idle += arch_idle_time(cpu); | 53 | else |
33 | } else | ||
34 | idle = usecs_to_cputime64(idle_time); | 54 | idle = usecs_to_cputime64(idle_time); |
35 | 55 | ||
36 | return idle; | 56 | return idle; |
@@ -49,6 +69,8 @@ static u64 get_iowait_time(int cpu) | |||
49 | return iowait; | 69 | return iowait; |
50 | } | 70 | } |
51 | 71 | ||
72 | #endif | ||
73 | |||
52 | static int show_stat(struct seq_file *p, void *v) | 74 | static int show_stat(struct seq_file *p, void *v) |
53 | { | 75 | { |
54 | int i, j; | 76 | int i, j; |
diff --git a/kernel/itimer.c b/kernel/itimer.c index 22000c3db0dd..8d262b467573 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c | |||
@@ -284,8 +284,12 @@ SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value, | |||
284 | if (value) { | 284 | if (value) { |
285 | if(copy_from_user(&set_buffer, value, sizeof(set_buffer))) | 285 | if(copy_from_user(&set_buffer, value, sizeof(set_buffer))) |
286 | return -EFAULT; | 286 | return -EFAULT; |
287 | } else | 287 | } else { |
288 | memset((char *) &set_buffer, 0, sizeof(set_buffer)); | 288 | memset(&set_buffer, 0, sizeof(set_buffer)); |
289 | printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer." | ||
290 | " Misfeature support will be removed\n", | ||
291 | current->comm); | ||
292 | } | ||
289 | 293 | ||
290 | error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL); | 294 | error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL); |
291 | if (error || !ovalue) | 295 | if (error || !ovalue) |
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index 2cf9cc7aa103..a20dc8a3c949 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig | |||
@@ -1,6 +1,10 @@ | |||
1 | # | 1 | # |
2 | # Timer subsystem related configuration options | 2 | # Timer subsystem related configuration options |
3 | # | 3 | # |
4 | |||
5 | # Core internal switch. Selected by NO_HZ / HIGH_RES_TIMERS. This is | ||
6 | # only related to the tick functionality. Oneshot clockevent devices | ||
7 | # are supported independ of this. | ||
4 | config TICK_ONESHOT | 8 | config TICK_ONESHOT |
5 | bool | 9 | bool |
6 | 10 | ||
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index e883f57a3cd3..bf57abdc7bd0 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -575,10 +575,12 @@ void tick_broadcast_switch_to_oneshot(void) | |||
575 | unsigned long flags; | 575 | unsigned long flags; |
576 | 576 | ||
577 | raw_spin_lock_irqsave(&tick_broadcast_lock, flags); | 577 | raw_spin_lock_irqsave(&tick_broadcast_lock, flags); |
578 | |||
579 | tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; | ||
580 | |||
578 | if (cpumask_empty(tick_get_broadcast_mask())) | 581 | if (cpumask_empty(tick_get_broadcast_mask())) |
579 | goto end; | 582 | goto end; |
580 | 583 | ||
581 | tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; | ||
582 | bc = tick_broadcast_device.evtdev; | 584 | bc = tick_broadcast_device.evtdev; |
583 | if (bc) | 585 | if (bc) |
584 | tick_broadcast_setup_oneshot(bc); | 586 | tick_broadcast_setup_oneshot(bc); |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 3526038f2836..6a3a5b9ff561 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -534,9 +534,9 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) | |||
534 | hrtimer_get_expires(&ts->sched_timer), 0)) | 534 | hrtimer_get_expires(&ts->sched_timer), 0)) |
535 | break; | 535 | break; |
536 | } | 536 | } |
537 | /* Update jiffies and reread time */ | 537 | /* Reread time and update jiffies */ |
538 | tick_do_update_jiffies64(now); | ||
539 | now = ktime_get(); | 538 | now = ktime_get(); |
539 | tick_do_update_jiffies64(now); | ||
540 | } | 540 | } |
541 | } | 541 | } |
542 | 542 | ||