From d7fe432f30a40fb570624b101d7476de887b9368 Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
Date: Tue, 28 Jun 2011 15:46:49 +0200
Subject: [PATCH 046/414] softirq-split-out-code.patch

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 kernel/softirq.c | 60 +++++++++++++++++++++++++++-----------------------------
 1 file changed, 29 insertions(+), 31 deletions(-)

diff --git a/kernel/softirq.c b/kernel/softirq.c
index 1799cd91e825..c3226b2a60fc 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -77,6 +77,34 @@ static void wakeup_softirqd(void)
 		wake_up_process(tsk);
 }
 
+static void handle_pending_softirqs(u32 pending, int cpu)
+{
+	struct softirq_action *h = softirq_vec;
+	unsigned int prev_count = preempt_count();
+
+	local_irq_enable();
+	for (; pending; h++, pending >>= 1) {
+		unsigned int vec_nr = h - softirq_vec;
+
+		if (!(pending & 1))
+			continue;
+
+		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, (unsigned int) preempt_count());
+			preempt_count() = prev_count;
+		}
+		rcu_bh_qs(cpu);
+	}
+	local_irq_disable();
+}
+
 /*
  * preempt_count and SOFTIRQ_OFFSET usage:
  * - preempt_count is changed by SOFTIRQ_OFFSET on entering or leaving
@@ -252,7 +280,6 @@ asmlinkage void __do_softirq(void)
 	unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
 	unsigned long old_flags = current->flags;
 	int max_restart = MAX_SOFTIRQ_RESTART;
-	struct softirq_action *h;
 	__u32 pending;
 	int cpu;
 
@@ -274,36 +301,7 @@ restart:
 	/* Reset the pending bitmask before enabling irqs */
 	set_softirq_pending(0);
 
-	local_irq_enable();
-
-	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() = prev_count;
-			}
-
-			rcu_bh_qs(cpu);
-		}
-		h++;
-		pending >>= 1;
-	} while (pending);
-
-	local_irq_disable();
+	handle_pending_softirqs(pending, cpu);
 
 	pending = local_softirq_pending();
 	if (pending) {
-- 
2.10.2

