Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / kernel / softirq.c
index 8a1e6e1..490fcbb 100644 (file)
@@ -8,6 +8,8 @@
  *     Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903)
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/export.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
@@ -54,7 +56,7 @@ static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp
 
 DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
 
-char *softirq_to_name[NR_SOFTIRQS] = {
+const char * const softirq_to_name[NR_SOFTIRQS] = {
        "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL",
        "TASKLET", "SCHED", "HRTIMER", "RCU"
 };
@@ -136,7 +138,6 @@ void _local_bh_enable(void)
        WARN_ON_ONCE(in_irq());
        __local_bh_enable(SOFTIRQ_DISABLE_OFFSET);
 }
-
 EXPORT_SYMBOL(_local_bh_enable);
 
 void __local_bh_enable_ip(unsigned long ip, unsigned int cnt)
@@ -153,7 +154,7 @@ void __local_bh_enable_ip(unsigned long ip, unsigned int cnt)
        /*
         * Keep preemption disabled until we are done with
         * softirq processing:
-        */
+        */
        preempt_count_sub(cnt - 1);
 
        if (unlikely(!in_interrupt() && local_softirq_pending())) {
@@ -229,6 +230,7 @@ asmlinkage void __do_softirq(void)
        struct softirq_action *h;
        bool in_hardirq;
        __u32 pending;
+       int softirq_bit;
        int cpu;
 
        /*
@@ -253,30 +255,30 @@ restart:
 
        h = softirq_vec;
 
-       do {
-               if (pending & 1) {
-                       unsigned int vec_nr = h - softirq_vec;
-                       int prev_count = preempt_count();
-
-                       kstat_incr_softirqs_this_cpu(vec_nr);
-
-                       trace_softirq_entry(vec_nr);
-                       h->action(h);
-                       trace_softirq_exit(vec_nr);
-                       if (unlikely(prev_count != preempt_count())) {
-                               printk(KERN_ERR "huh, entered softirq %u %s %p"
-                                      "with preempt_count %08x,"
-                                      " exited with %08x?\n", vec_nr,
-                                      softirq_to_name[vec_nr], h->action,
-                                      prev_count, preempt_count());
-                               preempt_count_set(prev_count);
-                       }
+       while ((softirq_bit = ffs(pending))) {
+               unsigned int vec_nr;
+               int prev_count;
 
-                       rcu_bh_qs(cpu);
+               h += softirq_bit - 1;
+
+               vec_nr = h - softirq_vec;
+               prev_count = preempt_count();
+
+               kstat_incr_softirqs_this_cpu(vec_nr);
+
+               trace_softirq_entry(vec_nr);
+               h->action(h);
+               trace_softirq_exit(vec_nr);
+               if (unlikely(prev_count != preempt_count())) {
+                       pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n",
+                              vec_nr, softirq_to_name[vec_nr], h->action,
+                              prev_count, preempt_count());
+                       preempt_count_set(prev_count);
                }
+               rcu_bh_qs(cpu);
                h++;
-               pending >>= 1;
-       } while (pending);
+               pending >>= softirq_bit;
+       }
 
        local_irq_disable();
 
@@ -326,7 +328,7 @@ void irq_enter(void)
                 * here, as softirq will be serviced on return from interrupt.
                 */
                local_bh_disable();
-               tick_check_idle();
+               tick_irq_enter();
                _local_bh_enable();
        }
 
@@ -433,8 +435,7 @@ void open_softirq(int nr, void (*action)(struct softirq_action *))
 /*
  * Tasklets
  */
-struct tasklet_head
-{
+struct tasklet_head {
        struct tasklet_struct *head;
        struct tasklet_struct **tail;
 };
@@ -453,7 +454,6 @@ void __tasklet_schedule(struct tasklet_struct *t)
        raise_softirq_irqoff(TASKLET_SOFTIRQ);
        local_irq_restore(flags);
 }
-
 EXPORT_SYMBOL(__tasklet_schedule);
 
 void __tasklet_hi_schedule(struct tasklet_struct *t)
@@ -467,7 +467,6 @@ void __tasklet_hi_schedule(struct tasklet_struct *t)
        raise_softirq_irqoff(HI_SOFTIRQ);
        local_irq_restore(flags);
 }
-
 EXPORT_SYMBOL(__tasklet_hi_schedule);
 
 void __tasklet_hi_schedule_first(struct tasklet_struct *t)
@@ -478,7 +477,6 @@ void __tasklet_hi_schedule_first(struct tasklet_struct *t)
        __this_cpu_write(tasklet_hi_vec.head, t);
        __raise_softirq_irqoff(HI_SOFTIRQ);
 }
-
 EXPORT_SYMBOL(__tasklet_hi_schedule_first);
 
 static void tasklet_action(struct softirq_action *a)
@@ -498,7 +496,8 @@ static void tasklet_action(struct softirq_action *a)
 
                if (tasklet_trylock(t)) {
                        if (!atomic_read(&t->count)) {
-                               if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
+                               if (!test_and_clear_bit(TASKLET_STATE_SCHED,
+                                                       &t->state))
                                        BUG();
                                t->func(t->data);
                                tasklet_unlock(t);
@@ -533,7 +532,8 @@ static void tasklet_hi_action(struct softirq_action *a)
 
                if (tasklet_trylock(t)) {
                        if (!atomic_read(&t->count)) {
-                               if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
+                               if (!test_and_clear_bit(TASKLET_STATE_SCHED,
+                                                       &t->state))
                                        BUG();
                                t->func(t->data);
                                tasklet_unlock(t);
@@ -551,7 +551,6 @@ static void tasklet_hi_action(struct softirq_action *a)
        }
 }
 
-
 void tasklet_init(struct tasklet_struct *t,
                  void (*func)(unsigned long), unsigned long data)
 {
@@ -561,13 +560,12 @@ void tasklet_init(struct tasklet_struct *t,
        t->func = func;
        t->data = data;
 }
-
 EXPORT_SYMBOL(tasklet_init);
 
 void tasklet_kill(struct tasklet_struct *t)
 {
        if (in_interrupt())
-               printk("Attempt to kill tasklet from interrupt\n");
+               pr_notice("Attempt to kill tasklet from interrupt\n");
 
        while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
                do {
@@ -577,7 +575,6 @@ void tasklet_kill(struct tasklet_struct *t)
        tasklet_unlock_wait(t);
        clear_bit(TASKLET_STATE_SCHED, &t->state);
 }
-
 EXPORT_SYMBOL(tasklet_kill);
 
 /*
@@ -727,9 +724,8 @@ static void takeover_tasklets(unsigned int cpu)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-static int cpu_callback(struct notifier_block *nfb,
-                                 unsigned long action,
-                                 void *hcpu)
+static int cpu_callback(struct notifier_block *nfb, unsigned long action,
+                       void *hcpu)
 {
        switch (action) {
 #ifdef CONFIG_HOTPLUG_CPU