aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/printk.c22
-rw-r--r--kernel/resource.c51
-rw-r--r--kernel/softirq.c13
-rw-r--r--kernel/time/tick-sched.c2
-rw-r--r--kernel/timer.c1
5 files changed, 73 insertions, 16 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index a430fd04008b..aee891a869a4 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -577,9 +577,6 @@ static int have_callable_console(void)
577 * @fmt: format string 577 * @fmt: format string
578 * 578 *
579 * This is printk(). It can be called from any context. We want it to work. 579 * This is printk(). It can be called from any context. We want it to work.
580 * Be aware of the fact that if oops_in_progress is not set, we might try to
581 * wake klogd up which could deadlock on runqueue lock if printk() is called
582 * from scheduler code.
583 * 580 *
584 * We try to grab the console_sem. If we succeed, it's easy - we log the output and 581 * We try to grab the console_sem. If we succeed, it's easy - we log the output and
585 * call the console drivers. If we fail to get the semaphore we place the output 582 * call the console drivers. If we fail to get the semaphore we place the output
@@ -982,10 +979,25 @@ int is_console_locked(void)
982 return console_locked; 979 return console_locked;
983} 980}
984 981
985void wake_up_klogd(void) 982static DEFINE_PER_CPU(int, printk_pending);
983
984void printk_tick(void)
986{ 985{
987 if (!oops_in_progress && waitqueue_active(&log_wait)) 986 if (__get_cpu_var(printk_pending)) {
987 __get_cpu_var(printk_pending) = 0;
988 wake_up_interruptible(&log_wait); 988 wake_up_interruptible(&log_wait);
989 }
990}
991
992int printk_needs_cpu(int cpu)
993{
994 return per_cpu(printk_pending, cpu);
995}
996
997void wake_up_klogd(void)
998{
999 if (waitqueue_active(&log_wait))
1000 __raw_get_cpu_var(printk_pending) = 1;
989} 1001}
990 1002
991/** 1003/**
diff --git a/kernel/resource.c b/kernel/resource.c
index 414d6fc9131e..7797dae85b50 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -38,10 +38,6 @@ EXPORT_SYMBOL(iomem_resource);
38 38
39static DEFINE_RWLOCK(resource_lock); 39static DEFINE_RWLOCK(resource_lock);
40 40
41#ifdef CONFIG_PROC_FS
42
43enum { MAX_IORES_LEVEL = 5 };
44
45static void *r_next(struct seq_file *m, void *v, loff_t *pos) 41static void *r_next(struct seq_file *m, void *v, loff_t *pos)
46{ 42{
47 struct resource *p = v; 43 struct resource *p = v;
@@ -53,6 +49,10 @@ static void *r_next(struct seq_file *m, void *v, loff_t *pos)
53 return p->sibling; 49 return p->sibling;
54} 50}
55 51
52#ifdef CONFIG_PROC_FS
53
54enum { MAX_IORES_LEVEL = 5 };
55
56static void *r_start(struct seq_file *m, loff_t *pos) 56static void *r_start(struct seq_file *m, loff_t *pos)
57 __acquires(resource_lock) 57 __acquires(resource_lock)
58{ 58{
@@ -549,13 +549,9 @@ static void __init __reserve_region_with_split(struct resource *root,
549 } 549 }
550 550
551 if (!res) { 551 if (!res) {
552 printk(KERN_DEBUG " __reserve_region_with_split: (%s) [%llx, %llx], res: (%s) [%llx, %llx]\n",
553 conflict->name, conflict->start, conflict->end,
554 name, start, end);
555
556 /* failed, split and try again */ 552 /* failed, split and try again */
557 553
558 /* conflict coverred whole area */ 554 /* conflict covered whole area */
559 if (conflict->start <= start && conflict->end >= end) 555 if (conflict->start <= start && conflict->end >= end)
560 return; 556 return;
561 557
@@ -831,3 +827,40 @@ static int __init reserve_setup(char *str)
831} 827}
832 828
833__setup("reserve=", reserve_setup); 829__setup("reserve=", reserve_setup);
830
831/*
832 * Check if the requested addr and size spans more than any slot in the
833 * iomem resource tree.
834 */
835int iomem_map_sanity_check(resource_size_t addr, unsigned long size)
836{
837 struct resource *p = &iomem_resource;
838 int err = 0;
839 loff_t l;
840
841 read_lock(&resource_lock);
842 for (p = p->child; p ; p = r_next(NULL, p, &l)) {
843 /*
844 * We can probably skip the resources without
845 * IORESOURCE_IO attribute?
846 */
847 if (p->start >= addr + size)
848 continue;
849 if (p->end < addr)
850 continue;
851 if (p->start <= addr && (p->end >= addr + size - 1))
852 continue;
853 printk(KERN_WARNING "resource map sanity check conflict: "
854 "0x%llx 0x%llx 0x%llx 0x%llx %s\n",
855 (unsigned long long)addr,
856 (unsigned long long)(addr + size - 1),
857 (unsigned long long)p->start,
858 (unsigned long long)p->end,
859 p->name);
860 err = -1;
861 break;
862 }
863 read_unlock(&resource_lock);
864
865 return err;
866}
diff --git a/kernel/softirq.c b/kernel/softirq.c
index c506f266a6b9..be7a8292f992 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -46,7 +46,7 @@ irq_cpustat_t irq_stat[NR_CPUS] ____cacheline_aligned;
46EXPORT_SYMBOL(irq_stat); 46EXPORT_SYMBOL(irq_stat);
47#endif 47#endif
48 48
49static struct softirq_action softirq_vec[32] __cacheline_aligned_in_smp; 49static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;
50 50
51static DEFINE_PER_CPU(struct task_struct *, ksoftirqd); 51static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
52 52
@@ -205,7 +205,18 @@ restart:
205 205
206 do { 206 do {
207 if (pending & 1) { 207 if (pending & 1) {
208 int prev_count = preempt_count();
209
208 h->action(h); 210 h->action(h);
211
212 if (unlikely(prev_count != preempt_count())) {
213 printk(KERN_ERR "huh, entered softirq %d %p"
214 "with preempt_count %08x,"
215 " exited with %08x?\n", h - softirq_vec,
216 h->action, prev_count, preempt_count());
217 preempt_count() = prev_count;
218 }
219
209 rcu_bh_qsctr_inc(cpu); 220 rcu_bh_qsctr_inc(cpu);
210 } 221 }
211 h++; 222 h++;
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index a4d219398167..b711ffcb106c 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -270,7 +270,7 @@ void tick_nohz_stop_sched_tick(int inidle)
270 next_jiffies = get_next_timer_interrupt(last_jiffies); 270 next_jiffies = get_next_timer_interrupt(last_jiffies);
271 delta_jiffies = next_jiffies - last_jiffies; 271 delta_jiffies = next_jiffies - last_jiffies;
272 272
273 if (rcu_needs_cpu(cpu)) 273 if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu))
274 delta_jiffies = 1; 274 delta_jiffies = 1;
275 /* 275 /*
276 * Do not stop the tick, if we are only one off 276 * Do not stop the tick, if we are only one off
diff --git a/kernel/timer.c b/kernel/timer.c
index 03bc7f1f1593..510fe69351ca 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -978,6 +978,7 @@ void update_process_times(int user_tick)
978 run_local_timers(); 978 run_local_timers();
979 if (rcu_pending(cpu)) 979 if (rcu_pending(cpu))
980 rcu_check_callbacks(cpu, user_tick); 980 rcu_check_callbacks(cpu, user_tick);
981 printk_tick();
981 scheduler_tick(); 982 scheduler_tick();
982 run_posix_cpu_timers(p); 983 run_posix_cpu_timers(p);
983} 984}