aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/softirq.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/softirq.c')
-rw-r--r--kernel/softirq.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 14d7758074aa..b5197dcb0dad 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -329,6 +329,19 @@ static inline void invoke_softirq(void)
329 wakeup_softirqd(); 329 wakeup_softirqd();
330} 330}
331 331
332static inline void tick_irq_exit(void)
333{
334#ifdef CONFIG_NO_HZ_COMMON
335 int cpu = smp_processor_id();
336
337 /* Make sure that timer wheel updates are propagated */
338 if ((idle_cpu(cpu) && !need_resched()) || tick_nohz_full_cpu(cpu)) {
339 if (!in_interrupt())
340 tick_nohz_irq_exit();
341 }
342#endif
343}
344
332/* 345/*
333 * Exit an interrupt context. Process softirqs if needed and possible: 346 * Exit an interrupt context. Process softirqs if needed and possible:
334 */ 347 */
@@ -346,11 +359,7 @@ void irq_exit(void)
346 if (!in_interrupt() && local_softirq_pending()) 359 if (!in_interrupt() && local_softirq_pending())
347 invoke_softirq(); 360 invoke_softirq();
348 361
349#ifdef CONFIG_NO_HZ 362 tick_irq_exit();
350 /* Make sure that timer wheel updates are propagated */
351 if (idle_cpu(smp_processor_id()) && !in_interrupt() && !need_resched())
352 tick_nohz_irq_exit();
353#endif
354 rcu_irq_exit(); 363 rcu_irq_exit();
355} 364}
356 365
@@ -620,8 +629,7 @@ static void remote_softirq_receive(void *data)
620 unsigned long flags; 629 unsigned long flags;
621 int softirq; 630 int softirq;
622 631
623 softirq = cp->priv; 632 softirq = *(int *)cp->info;
624
625 local_irq_save(flags); 633 local_irq_save(flags);
626 __local_trigger(cp, softirq); 634 __local_trigger(cp, softirq);
627 local_irq_restore(flags); 635 local_irq_restore(flags);
@@ -631,9 +639,8 @@ static int __try_remote_softirq(struct call_single_data *cp, int cpu, int softir
631{ 639{
632 if (cpu_online(cpu)) { 640 if (cpu_online(cpu)) {
633 cp->func = remote_softirq_receive; 641 cp->func = remote_softirq_receive;
634 cp->info = cp; 642 cp->info = &softirq;
635 cp->flags = 0; 643 cp->flags = 0;
636 cp->priv = softirq;
637 644
638 __smp_call_function_single(cpu, cp, 0); 645 __smp_call_function_single(cpu, cp, 0);
639 return 0; 646 return 0;