X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fsoftirq.c;h=336f92d64e2ec04bb56d7146a4fc1e1eeb1141f5;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=582a1e8091bc651fcf714b3a6aeb7732ce9244f5;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/kernel/softirq.c b/kernel/softirq.c index 582a1e809..336f92d64 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /* @@ -84,7 +85,7 @@ asmlinkage void __do_softirq(void) cpu = smp_processor_id(); restart: /* Reset the pending bitmask before enabling irqs */ - local_softirq_pending() = 0; + set_softirq_pending(0); local_irq_enable(); @@ -355,8 +356,12 @@ static int ksoftirqd(void * __bind_cpu) set_current_state(TASK_INTERRUPTIBLE); while (!kthread_should_stop()) { - if (!local_softirq_pending()) + preempt_disable(); + if (!local_softirq_pending()) { + preempt_enable_no_resched(); schedule(); + preempt_disable(); + } __set_current_state(TASK_RUNNING); @@ -364,14 +369,14 @@ static int ksoftirqd(void * __bind_cpu) /* Preempt disable stops cpu going offline. If already offline, we'll be on wrong CPU: don't process */ - preempt_disable(); if (cpu_is_offline((long)__bind_cpu)) goto wait_to_die; do_softirq(); - preempt_enable(); + preempt_enable_no_resched(); cond_resched(); + preempt_disable(); } - + preempt_enable(); set_current_state(TASK_INTERRUPTIBLE); } __set_current_state(TASK_RUNNING); @@ -441,7 +446,7 @@ static void takeover_tasklets(unsigned int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ -static int __devinit cpu_callback(struct notifier_block *nfb, +static int cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -466,7 +471,8 @@ static int __devinit cpu_callback(struct notifier_block *nfb, #ifdef CONFIG_HOTPLUG_CPU case CPU_UP_CANCELED: /* Unbind so it can run. Fall thru. */ - kthread_bind(per_cpu(ksoftirqd, hotcpu), smp_processor_id()); + kthread_bind(per_cpu(ksoftirqd, hotcpu), + any_online_cpu(cpu_online_map)); case CPU_DEAD: p = per_cpu(ksoftirqd, hotcpu); per_cpu(ksoftirqd, hotcpu) = NULL; @@ -478,7 +484,7 @@ static int __devinit cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __devinitdata cpu_nfb = { +static struct notifier_block cpu_nfb = { .notifier_call = cpu_callback }; @@ -490,3 +496,22 @@ __init int spawn_ksoftirqd(void) register_cpu_notifier(&cpu_nfb); return 0; } + +#ifdef CONFIG_SMP +/* + * Call a function on all processors + */ +int on_each_cpu(void (*func) (void *info), void *info, int retry, int wait) +{ + int ret = 0; + + preempt_disable(); + ret = smp_call_function(func, info, retry, wait); + local_irq_disable(); + func(info); + local_irq_enable(); + preempt_enable(); + return ret; +} +EXPORT_SYMBOL(on_each_cpu); +#endif