diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/hrtimer.c | 15 | ||||
-rw-r--r-- | kernel/irq/proc.c | 10 | ||||
-rw-r--r-- | kernel/power/Kconfig | 2 | ||||
-rw-r--r-- | kernel/signal.c | 10 | ||||
-rw-r--r-- | kernel/sysctl.c | 10 | ||||
-rw-r--r-- | kernel/time/ntp.c | 59 | ||||
-rw-r--r-- | kernel/time/tick-broadcast.c | 35 | ||||
-rw-r--r-- | kernel/time/tick-common.c | 16 | ||||
-rw-r--r-- | kernel/time/tick-oneshot.c | 15 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 7 |
10 files changed, 158 insertions, 21 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 72d034258b..eb1ddebd2c 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -558,7 +558,8 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, | |||
558 | */ | 558 | */ |
559 | static int hrtimer_switch_to_hres(void) | 559 | static int hrtimer_switch_to_hres(void) |
560 | { | 560 | { |
561 | struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases); | 561 | int cpu = smp_processor_id(); |
562 | struct hrtimer_cpu_base *base = &per_cpu(hrtimer_bases, cpu); | ||
562 | unsigned long flags; | 563 | unsigned long flags; |
563 | 564 | ||
564 | if (base->hres_active) | 565 | if (base->hres_active) |
@@ -568,6 +569,8 @@ static int hrtimer_switch_to_hres(void) | |||
568 | 569 | ||
569 | if (tick_init_highres()) { | 570 | if (tick_init_highres()) { |
570 | local_irq_restore(flags); | 571 | local_irq_restore(flags); |
572 | printk(KERN_WARNING "Could not switch to high resolution " | ||
573 | "mode on CPU %d\n", cpu); | ||
571 | return 0; | 574 | return 0; |
572 | } | 575 | } |
573 | base->hres_active = 1; | 576 | base->hres_active = 1; |
@@ -683,6 +686,7 @@ static void enqueue_hrtimer(struct hrtimer *timer, | |||
683 | struct rb_node **link = &base->active.rb_node; | 686 | struct rb_node **link = &base->active.rb_node; |
684 | struct rb_node *parent = NULL; | 687 | struct rb_node *parent = NULL; |
685 | struct hrtimer *entry; | 688 | struct hrtimer *entry; |
689 | int leftmost = 1; | ||
686 | 690 | ||
687 | /* | 691 | /* |
688 | * Find the right place in the rbtree: | 692 | * Find the right place in the rbtree: |
@@ -694,18 +698,19 @@ static void enqueue_hrtimer(struct hrtimer *timer, | |||
694 | * We dont care about collisions. Nodes with | 698 | * We dont care about collisions. Nodes with |
695 | * the same expiry time stay together. | 699 | * the same expiry time stay together. |
696 | */ | 700 | */ |
697 | if (timer->expires.tv64 < entry->expires.tv64) | 701 | if (timer->expires.tv64 < entry->expires.tv64) { |
698 | link = &(*link)->rb_left; | 702 | link = &(*link)->rb_left; |
699 | else | 703 | } else { |
700 | link = &(*link)->rb_right; | 704 | link = &(*link)->rb_right; |
705 | leftmost = 0; | ||
706 | } | ||
701 | } | 707 | } |
702 | 708 | ||
703 | /* | 709 | /* |
704 | * Insert the timer to the rbtree and check whether it | 710 | * Insert the timer to the rbtree and check whether it |
705 | * replaces the first pending timer | 711 | * replaces the first pending timer |
706 | */ | 712 | */ |
707 | if (!base->first || timer->expires.tv64 < | 713 | if (leftmost) { |
708 | rb_entry(base->first, struct hrtimer, node)->expires.tv64) { | ||
709 | /* | 714 | /* |
710 | * Reprogram the clock event device. When the timer is already | 715 | * Reprogram the clock event device. When the timer is already |
711 | * expired hrtimer_enqueue_reprogram has either called the | 716 | * expired hrtimer_enqueue_reprogram has either called the |
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index b4f1674fca..50b81b9804 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
@@ -19,7 +19,15 @@ static struct proc_dir_entry *root_irq_dir; | |||
19 | static int irq_affinity_read_proc(char *page, char **start, off_t off, | 19 | static int irq_affinity_read_proc(char *page, char **start, off_t off, |
20 | int count, int *eof, void *data) | 20 | int count, int *eof, void *data) |
21 | { | 21 | { |
22 | int len = cpumask_scnprintf(page, count, irq_desc[(long)data].affinity); | 22 | struct irq_desc *desc = irq_desc + (long)data; |
23 | cpumask_t *mask = &desc->affinity; | ||
24 | int len; | ||
25 | |||
26 | #ifdef CONFIG_GENERIC_PENDING_IRQ | ||
27 | if (desc->status & IRQ_MOVE_PENDING) | ||
28 | mask = &desc->pending_mask; | ||
29 | #endif | ||
30 | len = cpumask_scnprintf(page, count, *mask); | ||
23 | 31 | ||
24 | if (count - len < 2) | 32 | if (count - len < 2) |
25 | return -EINVAL; | 33 | return -EINVAL; |
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 7358609e47..c1a106d87d 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig | |||
@@ -57,7 +57,7 @@ config DISABLE_CONSOLE_SUSPEND | |||
57 | 57 | ||
58 | config PM_TRACE | 58 | config PM_TRACE |
59 | bool "Suspend/resume event tracing" | 59 | bool "Suspend/resume event tracing" |
60 | depends on PM_DEBUG && X86_32 && EXPERIMENTAL | 60 | depends on PM_DEBUG && X86 && EXPERIMENTAL |
61 | default n | 61 | default n |
62 | ---help--- | 62 | ---help--- |
63 | This enables some cheesy code to save the last PM event point in the | 63 | This enables some cheesy code to save the last PM event point in the |
diff --git a/kernel/signal.c b/kernel/signal.c index 39d122753b..ef8156a6aa 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -255,6 +255,16 @@ flush_signal_handlers(struct task_struct *t, int force_default) | |||
255 | } | 255 | } |
256 | } | 256 | } |
257 | 257 | ||
258 | int unhandled_signal(struct task_struct *tsk, int sig) | ||
259 | { | ||
260 | if (is_init(tsk)) | ||
261 | return 1; | ||
262 | if (tsk->ptrace & PT_PTRACED) | ||
263 | return 0; | ||
264 | return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) || | ||
265 | (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL); | ||
266 | } | ||
267 | |||
258 | 268 | ||
259 | /* Notify the system that a driver wants to block all signals for this | 269 | /* Notify the system that a driver wants to block all signals for this |
260 | * process, and wants to be notified if any signals at all were to be | 270 | * process, and wants to be notified if any signals at all were to be |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 222299844a..ddebf3f2af 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -1203,6 +1203,16 @@ static ctl_table fs_table[] = { | |||
1203 | }; | 1203 | }; |
1204 | 1204 | ||
1205 | static ctl_table debug_table[] = { | 1205 | static ctl_table debug_table[] = { |
1206 | #ifdef CONFIG_X86 | ||
1207 | { | ||
1208 | .ctl_name = CTL_UNNUMBERED, | ||
1209 | .procname = "exception-trace", | ||
1210 | .data = &show_unhandled_signals, | ||
1211 | .maxlen = sizeof(int), | ||
1212 | .mode = 0644, | ||
1213 | .proc_handler = proc_dointvec | ||
1214 | }, | ||
1215 | #endif | ||
1206 | { .ctl_name = 0 } | 1216 | { .ctl_name = 0 } |
1207 | }; | 1217 | }; |
1208 | 1218 | ||
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index b5e352597c..cd91237dbf 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <linux/time.h> | 12 | #include <linux/time.h> |
13 | #include <linux/timer.h> | ||
13 | #include <linux/timex.h> | 14 | #include <linux/timex.h> |
14 | #include <linux/jiffies.h> | 15 | #include <linux/jiffies.h> |
15 | #include <linux/hrtimer.h> | 16 | #include <linux/hrtimer.h> |
@@ -175,12 +176,64 @@ u64 current_tick_length(void) | |||
175 | return tick_length; | 176 | return tick_length; |
176 | } | 177 | } |
177 | 178 | ||
179 | #ifdef CONFIG_GENERIC_CMOS_UPDATE | ||
178 | 180 | ||
179 | void __attribute__ ((weak)) notify_arch_cmos_timer(void) | 181 | /* Disable the cmos update - used by virtualization and embedded */ |
182 | int no_sync_cmos_clock __read_mostly; | ||
183 | |||
184 | static void sync_cmos_clock(unsigned long dummy); | ||
185 | |||
186 | static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0); | ||
187 | |||
188 | static void sync_cmos_clock(unsigned long dummy) | ||
189 | { | ||
190 | struct timespec now, next; | ||
191 | int fail = 1; | ||
192 | |||
193 | /* | ||
194 | * If we have an externally synchronized Linux clock, then update | ||
195 | * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be | ||
196 | * called as close as possible to 500 ms before the new second starts. | ||
197 | * This code is run on a timer. If the clock is set, that timer | ||
198 | * may not expire at the correct time. Thus, we adjust... | ||
199 | */ | ||
200 | if (!ntp_synced()) | ||
201 | /* | ||
202 | * Not synced, exit, do not restart a timer (if one is | ||
203 | * running, let it run out). | ||
204 | */ | ||
205 | return; | ||
206 | |||
207 | getnstimeofday(&now); | ||
208 | if (abs(xtime.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) | ||
209 | fail = update_persistent_clock(now); | ||
210 | |||
211 | next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec; | ||
212 | if (next.tv_nsec <= 0) | ||
213 | next.tv_nsec += NSEC_PER_SEC; | ||
214 | |||
215 | if (!fail) | ||
216 | next.tv_sec = 659; | ||
217 | else | ||
218 | next.tv_sec = 0; | ||
219 | |||
220 | if (next.tv_nsec >= NSEC_PER_SEC) { | ||
221 | next.tv_sec++; | ||
222 | next.tv_nsec -= NSEC_PER_SEC; | ||
223 | } | ||
224 | mod_timer(&sync_cmos_timer, jiffies + timespec_to_jiffies(&next)); | ||
225 | } | ||
226 | |||
227 | static void notify_cmos_timer(void) | ||
180 | { | 228 | { |
181 | return; | 229 | if (no_sync_cmos_clock) |
230 | mod_timer(&sync_cmos_timer, jiffies + 1); | ||
182 | } | 231 | } |
183 | 232 | ||
233 | #else | ||
234 | static inline void notify_cmos_timer(void) { } | ||
235 | #endif | ||
236 | |||
184 | /* adjtimex mainly allows reading (and writing, if superuser) of | 237 | /* adjtimex mainly allows reading (and writing, if superuser) of |
185 | * kernel time-keeping variables. used by xntpd. | 238 | * kernel time-keeping variables. used by xntpd. |
186 | */ | 239 | */ |
@@ -345,6 +398,6 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0) | |||
345 | txc->stbcnt = 0; | 398 | txc->stbcnt = 0; |
346 | write_sequnlock_irq(&xtime_lock); | 399 | write_sequnlock_irq(&xtime_lock); |
347 | do_gettimeofday(&txc->time); | 400 | do_gettimeofday(&txc->time); |
348 | notify_arch_cmos_timer(); | 401 | notify_cmos_timer(); |
349 | return(result); | 402 | return(result); |
350 | } | 403 | } |
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 8001d37071..db8e0f3d40 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -31,6 +31,12 @@ struct tick_device tick_broadcast_device; | |||
31 | static cpumask_t tick_broadcast_mask; | 31 | static cpumask_t tick_broadcast_mask; |
32 | static DEFINE_SPINLOCK(tick_broadcast_lock); | 32 | static DEFINE_SPINLOCK(tick_broadcast_lock); |
33 | 33 | ||
34 | #ifdef CONFIG_TICK_ONESHOT | ||
35 | static void tick_broadcast_clear_oneshot(int cpu); | ||
36 | #else | ||
37 | static inline void tick_broadcast_clear_oneshot(int cpu) { } | ||
38 | #endif | ||
39 | |||
34 | /* | 40 | /* |
35 | * Debugging: see timer_list.c | 41 | * Debugging: see timer_list.c |
36 | */ | 42 | */ |
@@ -49,7 +55,7 @@ cpumask_t *tick_get_broadcast_mask(void) | |||
49 | */ | 55 | */ |
50 | static void tick_broadcast_start_periodic(struct clock_event_device *bc) | 56 | static void tick_broadcast_start_periodic(struct clock_event_device *bc) |
51 | { | 57 | { |
52 | if (bc && bc->mode == CLOCK_EVT_MODE_SHUTDOWN) | 58 | if (bc) |
53 | tick_setup_periodic(bc, 1); | 59 | tick_setup_periodic(bc, 1); |
54 | } | 60 | } |
55 | 61 | ||
@@ -99,8 +105,19 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) | |||
99 | cpu_set(cpu, tick_broadcast_mask); | 105 | cpu_set(cpu, tick_broadcast_mask); |
100 | tick_broadcast_start_periodic(tick_broadcast_device.evtdev); | 106 | tick_broadcast_start_periodic(tick_broadcast_device.evtdev); |
101 | ret = 1; | 107 | ret = 1; |
102 | } | 108 | } else { |
109 | /* | ||
110 | * When the new device is not affected by the stop | ||
111 | * feature and the cpu is marked in the broadcast mask | ||
112 | * then clear the broadcast bit. | ||
113 | */ | ||
114 | if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) { | ||
115 | int cpu = smp_processor_id(); | ||
103 | 116 | ||
117 | cpu_clear(cpu, tick_broadcast_mask); | ||
118 | tick_broadcast_clear_oneshot(cpu); | ||
119 | } | ||
120 | } | ||
104 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 121 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
105 | return ret; | 122 | return ret; |
106 | } | 123 | } |
@@ -299,7 +316,7 @@ void tick_suspend_broadcast(void) | |||
299 | spin_lock_irqsave(&tick_broadcast_lock, flags); | 316 | spin_lock_irqsave(&tick_broadcast_lock, flags); |
300 | 317 | ||
301 | bc = tick_broadcast_device.evtdev; | 318 | bc = tick_broadcast_device.evtdev; |
302 | if (bc && tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) | 319 | if (bc) |
303 | clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); | 320 | clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); |
304 | 321 | ||
305 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 322 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
@@ -316,6 +333,8 @@ int tick_resume_broadcast(void) | |||
316 | bc = tick_broadcast_device.evtdev; | 333 | bc = tick_broadcast_device.evtdev; |
317 | 334 | ||
318 | if (bc) { | 335 | if (bc) { |
336 | clockevents_set_mode(bc, CLOCK_EVT_MODE_RESUME); | ||
337 | |||
319 | switch (tick_broadcast_device.mode) { | 338 | switch (tick_broadcast_device.mode) { |
320 | case TICKDEV_MODE_PERIODIC: | 339 | case TICKDEV_MODE_PERIODIC: |
321 | if(!cpus_empty(tick_broadcast_mask)) | 340 | if(!cpus_empty(tick_broadcast_mask)) |
@@ -485,6 +504,16 @@ out: | |||
485 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 504 | spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
486 | } | 505 | } |
487 | 506 | ||
507 | /* | ||
508 | * Reset the one shot broadcast for a cpu | ||
509 | * | ||
510 | * Called with tick_broadcast_lock held | ||
511 | */ | ||
512 | static void tick_broadcast_clear_oneshot(int cpu) | ||
513 | { | ||
514 | cpu_clear(cpu, tick_broadcast_oneshot_mask); | ||
515 | } | ||
516 | |||
488 | /** | 517 | /** |
489 | * tick_broadcast_setup_highres - setup the broadcast device for highres | 518 | * tick_broadcast_setup_highres - setup the broadcast device for highres |
490 | */ | 519 | */ |
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index a96ec9ab34..77a21abc87 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c | |||
@@ -318,12 +318,17 @@ static void tick_resume(void) | |||
318 | { | 318 | { |
319 | struct tick_device *td = &__get_cpu_var(tick_cpu_device); | 319 | struct tick_device *td = &__get_cpu_var(tick_cpu_device); |
320 | unsigned long flags; | 320 | unsigned long flags; |
321 | int broadcast = tick_resume_broadcast(); | ||
321 | 322 | ||
322 | spin_lock_irqsave(&tick_device_lock, flags); | 323 | spin_lock_irqsave(&tick_device_lock, flags); |
323 | if (td->mode == TICKDEV_MODE_PERIODIC) | 324 | clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_RESUME); |
324 | tick_setup_periodic(td->evtdev, 0); | 325 | |
325 | else | 326 | if (!broadcast) { |
326 | tick_resume_oneshot(); | 327 | if (td->mode == TICKDEV_MODE_PERIODIC) |
328 | tick_setup_periodic(td->evtdev, 0); | ||
329 | else | ||
330 | tick_resume_oneshot(); | ||
331 | } | ||
327 | spin_unlock_irqrestore(&tick_device_lock, flags); | 332 | spin_unlock_irqrestore(&tick_device_lock, flags); |
328 | } | 333 | } |
329 | 334 | ||
@@ -360,8 +365,7 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason, | |||
360 | break; | 365 | break; |
361 | 366 | ||
362 | case CLOCK_EVT_NOTIFY_RESUME: | 367 | case CLOCK_EVT_NOTIFY_RESUME: |
363 | if (!tick_resume_broadcast()) | 368 | tick_resume(); |
364 | tick_resume(); | ||
365 | break; | 369 | break; |
366 | 370 | ||
367 | default: | 371 | default: |
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c index f6997ab0c3..0258d3115d 100644 --- a/kernel/time/tick-oneshot.c +++ b/kernel/time/tick-oneshot.c | |||
@@ -73,8 +73,21 @@ int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *)) | |||
73 | struct clock_event_device *dev = td->evtdev; | 73 | struct clock_event_device *dev = td->evtdev; |
74 | 74 | ||
75 | if (!dev || !(dev->features & CLOCK_EVT_FEAT_ONESHOT) || | 75 | if (!dev || !(dev->features & CLOCK_EVT_FEAT_ONESHOT) || |
76 | !tick_device_is_functional(dev)) | 76 | !tick_device_is_functional(dev)) { |
77 | |||
78 | printk(KERN_INFO "Clockevents: " | ||
79 | "could not switch to one-shot mode:"); | ||
80 | if (!dev) { | ||
81 | printk(" no tick device\n"); | ||
82 | } else { | ||
83 | if (!tick_device_is_functional(dev)) | ||
84 | printk(" %s is not functional.\n", dev->name); | ||
85 | else | ||
86 | printk(" %s does not support one-shot mode.\n", | ||
87 | dev->name); | ||
88 | } | ||
77 | return -EINVAL; | 89 | return -EINVAL; |
90 | } | ||
78 | 91 | ||
79 | td->mode = TICKDEV_MODE_ONESHOT; | 92 | td->mode = TICKDEV_MODE_ONESHOT; |
80 | dev->event_handler = handler; | 93 | dev->event_handler = handler; |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 52db9e3c52..b416995b97 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -546,6 +546,7 @@ void tick_setup_sched_timer(void) | |||
546 | { | 546 | { |
547 | struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); | 547 | struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); |
548 | ktime_t now = ktime_get(); | 548 | ktime_t now = ktime_get(); |
549 | u64 offset; | ||
549 | 550 | ||
550 | /* | 551 | /* |
551 | * Emulate tick processing via per-CPU hrtimers: | 552 | * Emulate tick processing via per-CPU hrtimers: |
@@ -554,8 +555,12 @@ void tick_setup_sched_timer(void) | |||
554 | ts->sched_timer.function = tick_sched_timer; | 555 | ts->sched_timer.function = tick_sched_timer; |
555 | ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ; | 556 | ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ; |
556 | 557 | ||
557 | /* Get the next period */ | 558 | /* Get the next period (per cpu) */ |
558 | ts->sched_timer.expires = tick_init_jiffy_update(); | 559 | ts->sched_timer.expires = tick_init_jiffy_update(); |
560 | offset = ktime_to_ns(tick_period) >> 1; | ||
561 | do_div(offset, NR_CPUS); | ||
562 | offset *= smp_processor_id(); | ||
563 | ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset); | ||
559 | 564 | ||
560 | for (;;) { | 565 | for (;;) { |
561 | hrtimer_forward(&ts->sched_timer, now, tick_period); | 566 | hrtimer_forward(&ts->sched_timer, now, tick_period); |