aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/hrtimer.c15
-rw-r--r--kernel/irq/proc.c10
-rw-r--r--kernel/power/Kconfig2
-rw-r--r--kernel/signal.c10
-rw-r--r--kernel/sysctl.c10
-rw-r--r--kernel/time/ntp.c59
-rw-r--r--kernel/time/tick-broadcast.c35
-rw-r--r--kernel/time/tick-common.c16
-rw-r--r--kernel/time/tick-oneshot.c15
-rw-r--r--kernel/time/tick-sched.c7
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 */
559static int hrtimer_switch_to_hres(void) 559static 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;
19static int irq_affinity_read_proc(char *page, char **start, off_t off, 19static 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
58config PM_TRACE 58config 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
258int 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
1205static ctl_table debug_table[] = { 1205static 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
179void __attribute__ ((weak)) notify_arch_cmos_timer(void) 181/* Disable the cmos update - used by virtualization and embedded */
182int no_sync_cmos_clock __read_mostly;
183
184static void sync_cmos_clock(unsigned long dummy);
185
186static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
187
188static 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
227static 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
234static 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;
31static cpumask_t tick_broadcast_mask; 31static cpumask_t tick_broadcast_mask;
32static DEFINE_SPINLOCK(tick_broadcast_lock); 32static DEFINE_SPINLOCK(tick_broadcast_lock);
33 33
34#ifdef CONFIG_TICK_ONESHOT
35static void tick_broadcast_clear_oneshot(int cpu);
36#else
37static 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 */
50static void tick_broadcast_start_periodic(struct clock_event_device *bc) 56static 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 */
512static 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);