aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-09-06 13:04:49 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-09-19 15:44:30 -0400
commit30e92153b4e6f1cd01e30c34d9ef6f0986f96b0e (patch)
treee2cb18d75dd9e7eed6e0147ad561497a6f5bd2d2
parent27622b061eb4bb4d16b5d61219ac10a792010321 (diff)
padata: Convert to hotplug state machine
Install the callbacks via the state machine. CPU-hotplug multinstance support is used with the nocalls() version. Maybe parts of padata_alloc() could be moved into the online callback so that we could invoke ->startup callback for instance and drop get_online_cpus(). Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: Steffen Klassert <steffen.klassert@secunet.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: linux-crypto@vger.kernel.org Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/20160906170457.32393-14-bigeasy@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--include/linux/padata.h2
-rw-r--r--kernel/padata.c88
2 files changed, 51 insertions, 39 deletions
diff --git a/include/linux/padata.h b/include/linux/padata.h
index 113ee626a4dc..0f9e567d5e15 100644
--- a/include/linux/padata.h
+++ b/include/linux/padata.h
@@ -151,7 +151,7 @@ struct parallel_data {
151 * @flags: padata flags. 151 * @flags: padata flags.
152 */ 152 */
153struct padata_instance { 153struct padata_instance {
154 struct notifier_block cpu_notifier; 154 struct hlist_node node;
155 struct workqueue_struct *wq; 155 struct workqueue_struct *wq;
156 struct parallel_data *pd; 156 struct parallel_data *pd;
157 struct padata_cpumask cpumask; 157 struct padata_cpumask cpumask;
diff --git a/kernel/padata.c b/kernel/padata.c
index 993278895ccc..7848f0566403 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -30,6 +30,7 @@
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/sysfs.h> 31#include <linux/sysfs.h>
32#include <linux/rcupdate.h> 32#include <linux/rcupdate.h>
33#include <linux/module.h>
33 34
34#define MAX_OBJ_NUM 1000 35#define MAX_OBJ_NUM 1000
35 36
@@ -769,52 +770,43 @@ static inline int pinst_has_cpu(struct padata_instance *pinst, int cpu)
769 cpumask_test_cpu(cpu, pinst->cpumask.cbcpu); 770 cpumask_test_cpu(cpu, pinst->cpumask.cbcpu);
770} 771}
771 772
772 773static int padata_cpu_online(unsigned int cpu, struct hlist_node *node)
773static int padata_cpu_callback(struct notifier_block *nfb,
774 unsigned long action, void *hcpu)
775{ 774{
776 int err;
777 struct padata_instance *pinst; 775 struct padata_instance *pinst;
778 int cpu = (unsigned long)hcpu; 776 int ret;
779 777
780 pinst = container_of(nfb, struct padata_instance, cpu_notifier); 778 pinst = hlist_entry_safe(node, struct padata_instance, node);
779 if (!pinst_has_cpu(pinst, cpu))
780 return 0;
781 781
782 switch (action) { 782 mutex_lock(&pinst->lock);
783 case CPU_ONLINE: 783 ret = __padata_add_cpu(pinst, cpu);
784 case CPU_ONLINE_FROZEN: 784 mutex_unlock(&pinst->lock);
785 case CPU_DOWN_FAILED: 785 return ret;
786 case CPU_DOWN_FAILED_FROZEN: 786}
787 if (!pinst_has_cpu(pinst, cpu))
788 break;
789 mutex_lock(&pinst->lock);
790 err = __padata_add_cpu(pinst, cpu);
791 mutex_unlock(&pinst->lock);
792 if (err)
793 return notifier_from_errno(err);
794 break;
795 787
796 case CPU_DOWN_PREPARE: 788static int padata_cpu_prep_down(unsigned int cpu, struct hlist_node *node)
797 case CPU_DOWN_PREPARE_FROZEN: 789{
798 case CPU_UP_CANCELED: 790 struct padata_instance *pinst;
799 case CPU_UP_CANCELED_FROZEN: 791 int ret;
800 if (!pinst_has_cpu(pinst, cpu)) 792
801 break; 793 pinst = hlist_entry_safe(node, struct padata_instance, node);
802 mutex_lock(&pinst->lock); 794 if (!pinst_has_cpu(pinst, cpu))
803 err = __padata_remove_cpu(pinst, cpu); 795 return 0;
804 mutex_unlock(&pinst->lock);
805 if (err)
806 return notifier_from_errno(err);
807 break;
808 }
809 796
810 return NOTIFY_OK; 797 mutex_lock(&pinst->lock);
798 ret = __padata_remove_cpu(pinst, cpu);
799 mutex_unlock(&pinst->lock);
800 return ret;
811} 801}
802
803static enum cpuhp_state hp_online;
812#endif 804#endif
813 805
814static void __padata_free(struct padata_instance *pinst) 806static void __padata_free(struct padata_instance *pinst)
815{ 807{
816#ifdef CONFIG_HOTPLUG_CPU 808#ifdef CONFIG_HOTPLUG_CPU
817 unregister_hotcpu_notifier(&pinst->cpu_notifier); 809 cpuhp_state_remove_instance_nocalls(hp_online, &pinst->node);
818#endif 810#endif
819 811
820 padata_stop(pinst); 812 padata_stop(pinst);
@@ -1012,11 +1004,8 @@ struct padata_instance *padata_alloc(struct workqueue_struct *wq,
1012 mutex_init(&pinst->lock); 1004 mutex_init(&pinst->lock);
1013 1005
1014#ifdef CONFIG_HOTPLUG_CPU 1006#ifdef CONFIG_HOTPLUG_CPU
1015 pinst->cpu_notifier.notifier_call = padata_cpu_callback; 1007 cpuhp_state_add_instance_nocalls(hp_online, &pinst->node);
1016 pinst->cpu_notifier.priority = 0;
1017 register_hotcpu_notifier(&pinst->cpu_notifier);
1018#endif 1008#endif
1019
1020 return pinst; 1009 return pinst;
1021 1010
1022err_free_masks: 1011err_free_masks:
@@ -1039,3 +1028,26 @@ void padata_free(struct padata_instance *pinst)
1039 kobject_put(&pinst->kobj); 1028 kobject_put(&pinst->kobj);
1040} 1029}
1041EXPORT_SYMBOL(padata_free); 1030EXPORT_SYMBOL(padata_free);
1031
1032#ifdef CONFIG_HOTPLUG_CPU
1033
1034static __init int padata_driver_init(void)
1035{
1036 int ret;
1037
1038 ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "padata:online",
1039 padata_cpu_online,
1040 padata_cpu_prep_down);
1041 if (ret < 0)
1042 return ret;
1043 hp_online = ret;
1044 return 0;
1045}
1046module_init(padata_driver_init);
1047
1048static __exit void padata_driver_exit(void)
1049{
1050 cpuhp_remove_multi_state(hp_online);
1051}
1052module_exit(padata_driver_exit);
1053#endif