diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2016-09-06 13:04:49 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-19 15:44:30 -0400 |
commit | 30e92153b4e6f1cd01e30c34d9ef6f0986f96b0e (patch) | |
tree | e2cb18d75dd9e7eed6e0147ad561497a6f5bd2d2 | |
parent | 27622b061eb4bb4d16b5d61219ac10a792010321 (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.h | 2 | ||||
-rw-r--r-- | kernel/padata.c | 88 |
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 | */ |
153 | struct padata_instance { | 153 | struct 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 | 773 | static int padata_cpu_online(unsigned int cpu, struct hlist_node *node) | |
773 | static 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: | 788 | static 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 | |||
803 | static enum cpuhp_state hp_online; | ||
812 | #endif | 804 | #endif |
813 | 805 | ||
814 | static void __padata_free(struct padata_instance *pinst) | 806 | static 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 | ||
1022 | err_free_masks: | 1011 | err_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 | } |
1041 | EXPORT_SYMBOL(padata_free); | 1030 | EXPORT_SYMBOL(padata_free); |
1031 | |||
1032 | #ifdef CONFIG_HOTPLUG_CPU | ||
1033 | |||
1034 | static __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 | } | ||
1046 | module_init(padata_driver_init); | ||
1047 | |||
1048 | static __exit void padata_driver_exit(void) | ||
1049 | { | ||
1050 | cpuhp_remove_multi_state(hp_online); | ||
1051 | } | ||
1052 | module_exit(padata_driver_exit); | ||
1053 | #endif | ||