patch-2.4.0-test6 linux/kernel/softirq.c

Next file: linux/kernel/sys.c
Previous file: linux/kernel/sched.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test5/linux/kernel/softirq.c linux/kernel/softirq.c
@@ -9,6 +9,7 @@
  * Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903)
  */
 
+#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
@@ -38,8 +39,11 @@
    - Bottom halves: globally serialized, grr...
  */
 
+/* No separate irq_stat for s390, it is part of PSA */
+#if !defined(CONFIG_ARCH_S390)
+irq_cpustat_t irq_stat[NR_CPUS];
+#endif	/* CONFIG_ARCH_S390 */
 
-struct softirq_state softirq_state[NR_CPUS];
 static struct softirq_action softirq_vec[32];
 
 asmlinkage void do_softirq()
@@ -53,15 +57,15 @@
 	local_bh_disable();
 
 	local_irq_disable();
-	mask = softirq_state[cpu].mask;
-	active = softirq_state[cpu].active & mask;
+	mask = softirq_mask(cpu);
+	active = softirq_active(cpu) & mask;
 
 	if (active) {
 		struct softirq_action *h;
 
 restart:
 		/* Reset active bitmask before enabling irqs */
-		softirq_state[cpu].active &= ~active;
+		softirq_active(cpu) &= ~active;
 
 		local_irq_enable();
 
@@ -77,7 +81,7 @@
 
 		local_irq_disable();
 
-		active = softirq_state[cpu].active;
+		active = softirq_active(cpu);
 		if ((active &= mask) != 0)
 			goto retry;
 	}
@@ -107,7 +111,7 @@
 	softirq_vec[nr].action = action;
 
 	for (i=0; i<NR_CPUS; i++)
-		softirq_state[i].mask |= (1<<nr);
+		softirq_mask(i) |= (1<<nr);
 	spin_unlock_irqrestore(&softirq_mask_lock, flags);
 }
 
@@ -198,10 +202,15 @@
 
 void tasklet_kill(struct tasklet_struct *t)
 {
+	if (in_interrupt())
+		printk("Attempt to kill tasklet from interrupt\n");
+
 	while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
-		if (in_interrupt())
-			panic("Attempt to kill tasklet from interrupt\n");
-		schedule();
+		current->state = TASK_RUNNING;
+		do {
+			current->policy |= SCHED_YIELD;
+			schedule();
+		} while (test_bit(TASKLET_STATE_SCHED, &t->state));
 	}
 	tasklet_unlock_wait(t);
 	clear_bit(TASKLET_STATE_SCHED, &t->state);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)