@@ -558,7 +558,8 @@ static void padata_init_reorder_list(struct parallel_data *pd)
558558}
559559
560560/* Allocate and initialize the internal cpumask dependend resources. */
561- static struct parallel_data * padata_alloc_pd (struct padata_shell * ps )
561+ static struct parallel_data * padata_alloc_pd (struct padata_shell * ps ,
562+ int offlining_cpu )
562563{
563564 struct padata_instance * pinst = ps -> pinst ;
564565 struct parallel_data * pd ;
@@ -584,6 +585,10 @@ static struct parallel_data *padata_alloc_pd(struct padata_shell *ps)
584585
585586 cpumask_and (pd -> cpumask .pcpu , pinst -> cpumask .pcpu , cpu_online_mask );
586587 cpumask_and (pd -> cpumask .cbcpu , pinst -> cpumask .cbcpu , cpu_online_mask );
588+ if (offlining_cpu >= 0 ) {
589+ __cpumask_clear_cpu (offlining_cpu , pd -> cpumask .pcpu );
590+ __cpumask_clear_cpu (offlining_cpu , pd -> cpumask .cbcpu );
591+ }
587592
588593 padata_init_reorder_list (pd );
589594 padata_init_squeues (pd );
@@ -630,11 +635,11 @@ static void __padata_stop(struct padata_instance *pinst)
630635}
631636
632637/* Replace the internal control structure with a new one. */
633- static int padata_replace_one (struct padata_shell * ps )
638+ static int padata_replace_one (struct padata_shell * ps , int offlining_cpu )
634639{
635640 struct parallel_data * pd_new ;
636641
637- pd_new = padata_alloc_pd (ps );
642+ pd_new = padata_alloc_pd (ps , offlining_cpu );
638643 if (!pd_new )
639644 return - ENOMEM ;
640645
@@ -644,15 +649,15 @@ static int padata_replace_one(struct padata_shell *ps)
644649 return 0 ;
645650}
646651
647- static int padata_replace (struct padata_instance * pinst )
652+ static int padata_replace (struct padata_instance * pinst , int offlining_cpu )
648653{
649654 struct padata_shell * ps ;
650655 int err = 0 ;
651656
652657 pinst -> flags |= PADATA_RESET ;
653658
654659 list_for_each_entry (ps , & pinst -> pslist , list ) {
655- err = padata_replace_one (ps );
660+ err = padata_replace_one (ps , offlining_cpu );
656661 if (err )
657662 break ;
658663 }
@@ -669,9 +674,21 @@ static int padata_replace(struct padata_instance *pinst)
669674
670675/* If cpumask contains no active cpu, we mark the instance as invalid. */
671676static bool padata_validate_cpumask (struct padata_instance * pinst ,
672- const struct cpumask * cpumask )
677+ const struct cpumask * cpumask ,
678+ int offlining_cpu )
673679{
674- if (!cpumask_intersects (cpumask , cpu_online_mask )) {
680+ cpumask_copy (pinst -> validate_cpumask , cpu_online_mask );
681+
682+ /*
683+ * @offlining_cpu is still in cpu_online_mask, so remove it here for
684+ * validation. Using a sub-CPUHP_TEARDOWN_CPU hotplug state where
685+ * @offlining_cpu wouldn't be in the online mask doesn't work because
686+ * padata_cpu_offline() can fail but such a state doesn't allow failure.
687+ */
688+ if (offlining_cpu >= 0 )
689+ __cpumask_clear_cpu (offlining_cpu , pinst -> validate_cpumask );
690+
691+ if (!cpumask_intersects (cpumask , pinst -> validate_cpumask )) {
675692 pinst -> flags |= PADATA_INVALID ;
676693 return false;
677694 }
@@ -687,21 +704,21 @@ static int __padata_set_cpumasks(struct padata_instance *pinst,
687704 int valid ;
688705 int err ;
689706
690- valid = padata_validate_cpumask (pinst , pcpumask );
707+ valid = padata_validate_cpumask (pinst , pcpumask , -1 );
691708 if (!valid ) {
692709 __padata_stop (pinst );
693710 goto out_replace ;
694711 }
695712
696- valid = padata_validate_cpumask (pinst , cbcpumask );
713+ valid = padata_validate_cpumask (pinst , cbcpumask , -1 );
697714 if (!valid )
698715 __padata_stop (pinst );
699716
700717out_replace :
701718 cpumask_copy (pinst -> cpumask .pcpu , pcpumask );
702719 cpumask_copy (pinst -> cpumask .cbcpu , cbcpumask );
703720
704- err = padata_setup_cpumasks (pinst ) ?: padata_replace (pinst );
721+ err = padata_setup_cpumasks (pinst ) ?: padata_replace (pinst , -1 );
705722
706723 if (valid )
707724 __padata_start (pinst );
@@ -753,26 +770,6 @@ EXPORT_SYMBOL(padata_set_cpumask);
753770
754771#ifdef CONFIG_HOTPLUG_CPU
755772
756- static int __padata_add_cpu (struct padata_instance * pinst , int cpu )
757- {
758- int err = padata_replace (pinst );
759-
760- if (padata_validate_cpumask (pinst , pinst -> cpumask .pcpu ) &&
761- padata_validate_cpumask (pinst , pinst -> cpumask .cbcpu ))
762- __padata_start (pinst );
763-
764- return err ;
765- }
766-
767- static int __padata_remove_cpu (struct padata_instance * pinst , int cpu )
768- {
769- if (!padata_validate_cpumask (pinst , pinst -> cpumask .pcpu ) ||
770- !padata_validate_cpumask (pinst , pinst -> cpumask .cbcpu ))
771- __padata_stop (pinst );
772-
773- return padata_replace (pinst );
774- }
775-
776773static inline int pinst_has_cpu (struct padata_instance * pinst , int cpu )
777774{
778775 return cpumask_test_cpu (cpu , pinst -> cpumask .pcpu ) ||
@@ -784,27 +781,39 @@ static int padata_cpu_online(unsigned int cpu, struct hlist_node *node)
784781 struct padata_instance * pinst ;
785782 int ret ;
786783
787- pinst = hlist_entry_safe (node , struct padata_instance , cpu_online_node );
784+ pinst = hlist_entry_safe (node , struct padata_instance , cpuhp_node );
788785 if (!pinst_has_cpu (pinst , cpu ))
789786 return 0 ;
790787
791788 mutex_lock (& pinst -> lock );
792- ret = __padata_add_cpu (pinst , cpu );
789+
790+ ret = padata_replace (pinst , -1 );
791+
792+ if (padata_validate_cpumask (pinst , pinst -> cpumask .pcpu , -1 ) &&
793+ padata_validate_cpumask (pinst , pinst -> cpumask .cbcpu , -1 ))
794+ __padata_start (pinst );
795+
793796 mutex_unlock (& pinst -> lock );
794797 return ret ;
795798}
796799
797- static int padata_cpu_dead (unsigned int cpu , struct hlist_node * node )
800+ static int padata_cpu_offline (unsigned int cpu , struct hlist_node * node )
798801{
799802 struct padata_instance * pinst ;
800803 int ret ;
801804
802- pinst = hlist_entry_safe (node , struct padata_instance , cpu_dead_node );
805+ pinst = hlist_entry_safe (node , struct padata_instance , cpuhp_node );
803806 if (!pinst_has_cpu (pinst , cpu ))
804807 return 0 ;
805808
806809 mutex_lock (& pinst -> lock );
807- ret = __padata_remove_cpu (pinst , cpu );
810+
811+ if (!padata_validate_cpumask (pinst , pinst -> cpumask .pcpu , cpu ) ||
812+ !padata_validate_cpumask (pinst , pinst -> cpumask .cbcpu , cpu ))
813+ __padata_stop (pinst );
814+
815+ ret = padata_replace (pinst , cpu );
816+
808817 mutex_unlock (& pinst -> lock );
809818 return ret ;
810819}
@@ -815,15 +824,14 @@ static enum cpuhp_state hp_online;
815824static void __padata_free (struct padata_instance * pinst )
816825{
817826#ifdef CONFIG_HOTPLUG_CPU
818- cpuhp_state_remove_instance_nocalls (CPUHP_PADATA_DEAD ,
819- & pinst -> cpu_dead_node );
820- cpuhp_state_remove_instance_nocalls (hp_online , & pinst -> cpu_online_node );
827+ cpuhp_state_remove_instance_nocalls (hp_online , & pinst -> cpuhp_node );
821828#endif
822829
823830 WARN_ON (!list_empty (& pinst -> pslist ));
824831
825832 free_cpumask_var (pinst -> cpumask .pcpu );
826833 free_cpumask_var (pinst -> cpumask .cbcpu );
834+ free_cpumask_var (pinst -> validate_cpumask );
827835 destroy_workqueue (pinst -> serial_wq );
828836 destroy_workqueue (pinst -> parallel_wq );
829837 kfree (pinst );
@@ -983,18 +991,18 @@ struct padata_instance *padata_alloc(const char *name)
983991
984992 if (!alloc_cpumask_var (& pinst -> cpumask .pcpu , GFP_KERNEL ))
985993 goto err_free_serial_wq ;
986- if (!alloc_cpumask_var (& pinst -> cpumask .cbcpu , GFP_KERNEL )) {
987- free_cpumask_var ( pinst -> cpumask . pcpu ) ;
988- goto err_free_serial_wq ;
989- }
994+ if (!alloc_cpumask_var (& pinst -> cpumask .cbcpu , GFP_KERNEL ))
995+ goto err_free_p_mask ;
996+ if (! alloc_cpumask_var ( & pinst -> validate_cpumask , GFP_KERNEL ))
997+ goto err_free_cb_mask ;
990998
991999 INIT_LIST_HEAD (& pinst -> pslist );
9921000
9931001 cpumask_copy (pinst -> cpumask .pcpu , cpu_possible_mask );
9941002 cpumask_copy (pinst -> cpumask .cbcpu , cpu_possible_mask );
9951003
9961004 if (padata_setup_cpumasks (pinst ))
997- goto err_free_masks ;
1005+ goto err_free_v_mask ;
9981006
9991007 __padata_start (pinst );
10001008
@@ -1003,18 +1011,19 @@ struct padata_instance *padata_alloc(const char *name)
10031011
10041012#ifdef CONFIG_HOTPLUG_CPU
10051013 cpuhp_state_add_instance_nocalls_cpuslocked (hp_online ,
1006- & pinst -> cpu_online_node );
1007- cpuhp_state_add_instance_nocalls_cpuslocked (CPUHP_PADATA_DEAD ,
1008- & pinst -> cpu_dead_node );
1014+ & pinst -> cpuhp_node );
10091015#endif
10101016
10111017 cpus_read_unlock ();
10121018
10131019 return pinst ;
10141020
1015- err_free_masks :
1016- free_cpumask_var (pinst -> cpumask .pcpu );
1021+ err_free_v_mask :
1022+ free_cpumask_var (pinst -> validate_cpumask );
1023+ err_free_cb_mask :
10171024 free_cpumask_var (pinst -> cpumask .cbcpu );
1025+ err_free_p_mask :
1026+ free_cpumask_var (pinst -> cpumask .pcpu );
10181027err_free_serial_wq :
10191028 destroy_workqueue (pinst -> serial_wq );
10201029err_put_cpus :
@@ -1057,7 +1066,7 @@ struct padata_shell *padata_alloc_shell(struct padata_instance *pinst)
10571066 ps -> pinst = pinst ;
10581067
10591068 cpus_read_lock ();
1060- pd = padata_alloc_pd (ps );
1069+ pd = padata_alloc_pd (ps , -1 );
10611070 cpus_read_unlock ();
10621071
10631072 if (!pd )
@@ -1106,32 +1115,25 @@ void __init padata_init(void)
11061115 int ret ;
11071116
11081117 ret = cpuhp_setup_state_multi (CPUHP_AP_ONLINE_DYN , "padata:online" ,
1109- padata_cpu_online , NULL );
1118+ padata_cpu_online , padata_cpu_offline );
11101119 if (ret < 0 )
11111120 goto err ;
11121121 hp_online = ret ;
1113-
1114- ret = cpuhp_setup_state_multi (CPUHP_PADATA_DEAD , "padata:dead" ,
1115- NULL , padata_cpu_dead );
1116- if (ret < 0 )
1117- goto remove_online_state ;
11181122#endif
11191123
11201124 possible_cpus = num_possible_cpus ();
11211125 padata_works = kmalloc_array (possible_cpus , sizeof (struct padata_work ),
11221126 GFP_KERNEL );
11231127 if (!padata_works )
1124- goto remove_dead_state ;
1128+ goto remove_online_state ;
11251129
11261130 for (i = 0 ; i < possible_cpus ; ++ i )
11271131 list_add (& padata_works [i ].pw_list , & padata_free_works );
11281132
11291133 return ;
11301134
1131- remove_dead_state :
1132- #ifdef CONFIG_HOTPLUG_CPU
1133- cpuhp_remove_multi_state (CPUHP_PADATA_DEAD );
11341135remove_online_state :
1136+ #ifdef CONFIG_HOTPLUG_CPU
11351137 cpuhp_remove_multi_state (hp_online );
11361138err :
11371139#endif
0 commit comments