Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Sebastian Andrzej Siewior and committed by
Thomas Gleixner
30e92153 27622b06

+53 -41
+1 -1
include/linux/padata.h
··· 151 151 * @flags: padata flags. 152 152 */ 153 153 struct padata_instance { 154 - struct notifier_block cpu_notifier; 154 + struct hlist_node node; 155 155 struct workqueue_struct *wq; 156 156 struct parallel_data *pd; 157 157 struct padata_cpumask cpumask;
+52 -40
kernel/padata.c
··· 30 30 #include <linux/slab.h> 31 31 #include <linux/sysfs.h> 32 32 #include <linux/rcupdate.h> 33 + #include <linux/module.h> 33 34 34 35 #define MAX_OBJ_NUM 1000 35 36 ··· 770 769 cpumask_test_cpu(cpu, pinst->cpumask.cbcpu); 771 770 } 772 771 773 - 774 - static int padata_cpu_callback(struct notifier_block *nfb, 775 - unsigned long action, void *hcpu) 772 + static int padata_cpu_online(unsigned int cpu, struct hlist_node *node) 776 773 { 777 - int err; 778 774 struct padata_instance *pinst; 779 - int cpu = (unsigned long)hcpu; 775 + int ret; 780 776 781 - pinst = container_of(nfb, struct padata_instance, cpu_notifier); 777 + pinst = hlist_entry_safe(node, struct padata_instance, node); 778 + if (!pinst_has_cpu(pinst, cpu)) 779 + return 0; 782 780 783 - switch (action) { 784 - case CPU_ONLINE: 785 - case CPU_ONLINE_FROZEN: 786 - case CPU_DOWN_FAILED: 787 - case CPU_DOWN_FAILED_FROZEN: 788 - if (!pinst_has_cpu(pinst, cpu)) 789 - break; 790 - mutex_lock(&pinst->lock); 791 - err = __padata_add_cpu(pinst, cpu); 792 - mutex_unlock(&pinst->lock); 793 - if (err) 794 - return notifier_from_errno(err); 795 - break; 796 - 797 - case CPU_DOWN_PREPARE: 798 - case CPU_DOWN_PREPARE_FROZEN: 799 - case CPU_UP_CANCELED: 800 - case CPU_UP_CANCELED_FROZEN: 801 - if (!pinst_has_cpu(pinst, cpu)) 802 - break; 803 - mutex_lock(&pinst->lock); 804 - err = __padata_remove_cpu(pinst, cpu); 805 - mutex_unlock(&pinst->lock); 806 - if (err) 807 - return notifier_from_errno(err); 808 - break; 809 - } 810 - 811 - return NOTIFY_OK; 781 + mutex_lock(&pinst->lock); 782 + ret = __padata_add_cpu(pinst, cpu); 783 + mutex_unlock(&pinst->lock); 784 + return ret; 812 785 } 786 + 787 + static int padata_cpu_prep_down(unsigned int cpu, struct hlist_node *node) 788 + { 789 + struct padata_instance *pinst; 790 + int ret; 791 + 792 + pinst = hlist_entry_safe(node, struct padata_instance, node); 793 + if (!pinst_has_cpu(pinst, cpu)) 794 + return 0; 795 + 796 + mutex_lock(&pinst->lock); 797 + ret = __padata_remove_cpu(pinst, cpu); 798 + mutex_unlock(&pinst->lock); 799 + return ret; 800 + } 801 + 802 + static enum cpuhp_state hp_online; 813 803 #endif 814 804 815 805 static void __padata_free(struct padata_instance *pinst) 816 806 { 817 807 #ifdef CONFIG_HOTPLUG_CPU 818 - unregister_hotcpu_notifier(&pinst->cpu_notifier); 808 + cpuhp_state_remove_instance_nocalls(hp_online, &pinst->node); 819 809 #endif 820 810 821 811 padata_stop(pinst); ··· 1004 1012 mutex_init(&pinst->lock); 1005 1013 1006 1014 #ifdef CONFIG_HOTPLUG_CPU 1007 - pinst->cpu_notifier.notifier_call = padata_cpu_callback; 1008 - pinst->cpu_notifier.priority = 0; 1009 - register_hotcpu_notifier(&pinst->cpu_notifier); 1015 + cpuhp_state_add_instance_nocalls(hp_online, &pinst->node); 1010 1016 #endif 1011 - 1012 1017 return pinst; 1013 1018 1014 1019 err_free_masks: ··· 1028 1039 kobject_put(&pinst->kobj); 1029 1040 } 1030 1041 EXPORT_SYMBOL(padata_free); 1042 + 1043 + #ifdef CONFIG_HOTPLUG_CPU 1044 + 1045 + static __init int padata_driver_init(void) 1046 + { 1047 + int ret; 1048 + 1049 + ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "padata:online", 1050 + padata_cpu_online, 1051 + padata_cpu_prep_down); 1052 + if (ret < 0) 1053 + return ret; 1054 + hp_online = ret; 1055 + return 0; 1056 + } 1057 + module_init(padata_driver_init); 1058 + 1059 + static __exit void padata_driver_exit(void) 1060 + { 1061 + cpuhp_remove_multi_state(hp_online); 1062 + } 1063 + module_exit(padata_driver_exit); 1064 + #endif