aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-08-18 08:57:21 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-09-06 12:30:22 -0400
commitc4544dbc7a9bce3da6fa2361cd68cadb34e9221f (patch)
tree6bb7fa3a00640539aac7948ee0d26e47f488787b
parent1d7ac6aec947d222042b6d22b3cec109db4fd19e (diff)
kernel/softirq: Convert to hotplug state machine
Install the callbacks via the state machine. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/20160818125731.27256-7-bigeasy@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--include/linux/cpuhotplug.h1
-rw-r--r--kernel/softirq.c27
2 files changed, 7 insertions, 21 deletions
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 854e59a426d4..a421407a317f 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -17,6 +17,7 @@ enum cpuhp_state {
17 CPUHP_VIRT_NET_DEAD, 17 CPUHP_VIRT_NET_DEAD,
18 CPUHP_SLUB_DEAD, 18 CPUHP_SLUB_DEAD,
19 CPUHP_MM_WRITEBACK_DEAD, 19 CPUHP_MM_WRITEBACK_DEAD,
20 CPUHP_SOFTIRQ_DEAD,
20 CPUHP_WORKQUEUE_PREP, 21 CPUHP_WORKQUEUE_PREP,
21 CPUHP_POWER_NUMA_PREPARE, 22 CPUHP_POWER_NUMA_PREPARE,
22 CPUHP_HRTIMERS_PREPARE, 23 CPUHP_HRTIMERS_PREPARE,
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 17caf4b63342..c372114494f5 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -700,7 +700,7 @@ void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu)
700 BUG(); 700 BUG();
701} 701}
702 702
703static void takeover_tasklets(unsigned int cpu) 703static int takeover_tasklets(unsigned int cpu)
704{ 704{
705 /* CPU is dead, so no lock needed. */ 705 /* CPU is dead, so no lock needed. */
706 local_irq_disable(); 706 local_irq_disable();
@@ -723,27 +723,12 @@ static void takeover_tasklets(unsigned int cpu)
723 raise_softirq_irqoff(HI_SOFTIRQ); 723 raise_softirq_irqoff(HI_SOFTIRQ);
724 724
725 local_irq_enable(); 725 local_irq_enable();
726 return 0;
726} 727}
728#else
729#define takeover_tasklets NULL
727#endif /* CONFIG_HOTPLUG_CPU */ 730#endif /* CONFIG_HOTPLUG_CPU */
728 731
729static int cpu_callback(struct notifier_block *nfb, unsigned long action,
730 void *hcpu)
731{
732 switch (action) {
733#ifdef CONFIG_HOTPLUG_CPU
734 case CPU_DEAD:
735 case CPU_DEAD_FROZEN:
736 takeover_tasklets((unsigned long)hcpu);
737 break;
738#endif /* CONFIG_HOTPLUG_CPU */
739 }
740 return NOTIFY_OK;
741}
742
743static struct notifier_block cpu_nfb = {
744 .notifier_call = cpu_callback
745};
746
747static struct smp_hotplug_thread softirq_threads = { 732static struct smp_hotplug_thread softirq_threads = {
748 .store = &ksoftirqd, 733 .store = &ksoftirqd,
749 .thread_should_run = ksoftirqd_should_run, 734 .thread_should_run = ksoftirqd_should_run,
@@ -753,8 +738,8 @@ static struct smp_hotplug_thread softirq_threads = {
753 738
754static __init int spawn_ksoftirqd(void) 739static __init int spawn_ksoftirqd(void)
755{ 740{
756 register_cpu_notifier(&cpu_nfb); 741 cpuhp_setup_state_nocalls(CPUHP_SOFTIRQ_DEAD, "softirq:dead", NULL,
757 742 takeover_tasklets);
758 BUG_ON(smpboot_register_percpu_thread(&softirq_threads)); 743 BUG_ON(smpboot_register_percpu_thread(&softirq_threads));
759 744
760 return 0; 745 return 0;