Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / kernel / softirq.c
index 735d870..671f959 100644 (file)
@@ -10,7 +10,7 @@
  *     Remote softirq infrastructure is by Jens Axboe.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -58,7 +58,7 @@ DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
 
 char *softirq_to_name[NR_SOFTIRQS] = {
        "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL",
-       "TASKLET", "SCHED", "HRTIMER",  "RCU"
+       "TASKLET", "SCHED", "HRTIMER", "RCU"
 };
 
 /*
@@ -297,7 +297,7 @@ void irq_enter(void)
        int cpu = smp_processor_id();
 
        rcu_irq_enter();
-       if (idle_cpu(cpu) && !in_interrupt()) {
+       if (is_idle_task(current) && !in_interrupt()) {
                /*
                 * Prevent raise_softirq from needlessly waking up ksoftirqd
                 * here, as softirq will be serviced on return from interrupt.
@@ -310,23 +310,21 @@ void irq_enter(void)
        __irq_enter();
 }
 
-#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
 static inline void invoke_softirq(void)
 {
-       if (!force_irqthreads)
+       if (!force_irqthreads) {
+#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
                __do_softirq();
-       else
-               wakeup_softirqd();
-}
 #else
-static inline void invoke_softirq(void)
-{
-       if (!force_irqthreads)
                do_softirq();
-       else
+#endif
+       } else {
+               __local_bh_disable((unsigned long)__builtin_return_address(0),
+                               SOFTIRQ_OFFSET);
                wakeup_softirqd();
+               __local_bh_enable(SOFTIRQ_OFFSET);
+       }
 }
-#endif
 
 /*
  * Exit an interrupt context. Process softirqs if needed and possible:
@@ -339,13 +337,13 @@ void irq_exit(void)
        if (!in_interrupt() && local_softirq_pending())
                invoke_softirq();
 
-       rcu_irq_exit();
 #ifdef CONFIG_NO_HZ
        /* Make sure that timer wheel updates are propagated */
        if (idle_cpu(smp_processor_id()) && !in_interrupt() && !need_resched())
-               tick_nohz_stop_sched_tick(0);
+               tick_nohz_irq_exit();
 #endif
-       preempt_enable_no_resched();
+       rcu_irq_exit();
+       sched_preempt_enable_no_resched();
 }
 
 /*
@@ -377,6 +375,12 @@ void raise_softirq(unsigned int nr)
        local_irq_restore(flags);
 }
 
+void __raise_softirq_irqoff(unsigned int nr)
+{
+       trace_softirq_raise(nr);
+       or_softirq_pending(1UL << nr);
+}
+
 void open_softirq(int nr, void (*action)(struct softirq_action *))
 {
        softirq_vec[nr].action = action;
@@ -567,7 +571,7 @@ static void __tasklet_hrtimer_trampoline(unsigned long data)
 /**
  * tasklet_hrtimer_init - Init a tasklet/hrtimer combo for softirq callbacks
  * @ttimer:     tasklet_hrtimer which is initialized
- * @function:   hrtimer callback funtion which gets called from softirq context
+ * @function:   hrtimer callback function which gets called from softirq context
  * @which_clock: clock id (CLOCK_MONOTONIC/CLOCK_REALTIME)
  * @mode:       hrtimer mode (HRTIMER_MODE_ABS/HRTIMER_MODE_REL)
  */
@@ -736,9 +740,7 @@ static int run_ksoftirqd(void * __bind_cpu)
        while (!kthread_should_stop()) {
                preempt_disable();
                if (!local_softirq_pending()) {
-                       preempt_enable_no_resched();
-                       schedule();
-                       preempt_disable();
+                       schedule_preempt_disabled();
                }
 
                __set_current_state(TASK_RUNNING);
@@ -753,7 +755,7 @@ static int run_ksoftirqd(void * __bind_cpu)
                        if (local_softirq_pending())
                                __do_softirq();
                        local_irq_enable();
-                       preempt_enable_no_resched();
+                       sched_preempt_enable_no_resched();
                        cond_resched();
                        preempt_disable();
                        rcu_note_context_switch((long)__bind_cpu);