@@ -1432,23 +1432,53 @@ static int cpuhp_cb_check(enum cpuhp_state state)
14321432 return 0 ;
14331433}
14341434
1435- static void cpuhp_store_callbacks (enum cpuhp_state state ,
1436- const char * name ,
1437- int (* startup )(unsigned int cpu ),
1438- int (* teardown )(unsigned int cpu ),
1439- bool multi_instance )
1435+ /*
1436+ * Returns a free for dynamic slot assignment of the Online state. The states
1437+ * are protected by the cpuhp_slot_states mutex and an empty slot is identified
1438+ * by having no name assigned.
1439+ */
1440+ static int cpuhp_reserve_state (enum cpuhp_state state )
1441+ {
1442+ enum cpuhp_state i ;
1443+
1444+ for (i = CPUHP_AP_ONLINE_DYN ; i <= CPUHP_AP_ONLINE_DYN_END ; i ++ ) {
1445+ if (!cpuhp_ap_states [i ].name )
1446+ return i ;
1447+ }
1448+ WARN (1 , "No more dynamic states available for CPU hotplug\n" );
1449+ return - ENOSPC ;
1450+ }
1451+
1452+ static int cpuhp_store_callbacks (enum cpuhp_state state , const char * name ,
1453+ int (* startup )(unsigned int cpu ),
1454+ int (* teardown )(unsigned int cpu ),
1455+ bool multi_instance )
14401456{
14411457 /* (Un)Install the callbacks for further cpu hotplug operations */
14421458 struct cpuhp_step * sp ;
1459+ int ret = 0 ;
14431460
14441461 mutex_lock (& cpuhp_state_mutex );
1462+
1463+ if (state == CPUHP_AP_ONLINE_DYN ) {
1464+ ret = cpuhp_reserve_state (state );
1465+ if (ret < 0 )
1466+ goto out ;
1467+ state = ret ;
1468+ }
14451469 sp = cpuhp_get_step (state );
1470+ if (name && sp -> name ) {
1471+ ret = - EBUSY ;
1472+ goto out ;
1473+ }
14461474 sp -> startup .single = startup ;
14471475 sp -> teardown .single = teardown ;
14481476 sp -> name = name ;
14491477 sp -> multi_instance = multi_instance ;
14501478 INIT_HLIST_HEAD (& sp -> list );
1479+ out :
14511480 mutex_unlock (& cpuhp_state_mutex );
1481+ return ret ;
14521482}
14531483
14541484static void * cpuhp_get_teardown_cb (enum cpuhp_state state )
@@ -1509,29 +1539,6 @@ static void cpuhp_rollback_install(int failedcpu, enum cpuhp_state state,
15091539 }
15101540}
15111541
1512- /*
1513- * Returns a free for dynamic slot assignment of the Online state. The states
1514- * are protected by the cpuhp_slot_states mutex and an empty slot is identified
1515- * by having no name assigned.
1516- */
1517- static int cpuhp_reserve_state (enum cpuhp_state state )
1518- {
1519- enum cpuhp_state i ;
1520-
1521- mutex_lock (& cpuhp_state_mutex );
1522- for (i = CPUHP_AP_ONLINE_DYN ; i <= CPUHP_AP_ONLINE_DYN_END ; i ++ ) {
1523- if (cpuhp_ap_states [i ].name )
1524- continue ;
1525-
1526- cpuhp_ap_states [i ].name = "Reserved" ;
1527- mutex_unlock (& cpuhp_state_mutex );
1528- return i ;
1529- }
1530- mutex_unlock (& cpuhp_state_mutex );
1531- WARN (1 , "No more dynamic states available for CPU hotplug\n" );
1532- return - ENOSPC ;
1533- }
1534-
15351542int __cpuhp_state_add_instance (enum cpuhp_state state , struct hlist_node * node ,
15361543 bool invoke )
15371544{
@@ -1580,11 +1587,13 @@ EXPORT_SYMBOL_GPL(__cpuhp_state_add_instance);
15801587
15811588/**
15821589 * __cpuhp_setup_state - Setup the callbacks for an hotplug machine state
1583- * @state: The state to setup
1584- * @invoke: If true, the startup function is invoked for cpus where
1585- * cpu state >= @state
1586- * @startup: startup callback function
1587- * @teardown: teardown callback function
1590+ * @state: The state to setup
1591+ * @invoke: If true, the startup function is invoked for cpus where
1592+ * cpu state >= @state
1593+ * @startup: startup callback function
1594+ * @teardown: teardown callback function
1595+ * @multi_instance: State is set up for multiple instances which get
1596+ * added afterwards.
15881597 *
15891598 * Returns:
15901599 * On success:
@@ -1599,25 +1608,16 @@ int __cpuhp_setup_state(enum cpuhp_state state,
15991608 bool multi_instance )
16001609{
16011610 int cpu , ret = 0 ;
1602- int dyn_state = 0 ;
16031611
16041612 if (cpuhp_cb_check (state ) || !name )
16051613 return - EINVAL ;
16061614
16071615 get_online_cpus ();
16081616
1609- /* currently assignments for the ONLINE state are possible */
1610- if (state == CPUHP_AP_ONLINE_DYN ) {
1611- dyn_state = 1 ;
1612- ret = cpuhp_reserve_state (state );
1613- if (ret < 0 )
1614- goto out ;
1615- state = ret ;
1616- }
1617-
1618- cpuhp_store_callbacks (state , name , startup , teardown , multi_instance );
1617+ ret = cpuhp_store_callbacks (state , name , startup , teardown ,
1618+ multi_instance );
16191619
1620- if (!invoke || !startup )
1620+ if (ret || !invoke || !startup )
16211621 goto out ;
16221622
16231623 /*
@@ -1641,7 +1641,11 @@ int __cpuhp_setup_state(enum cpuhp_state state,
16411641 }
16421642out :
16431643 put_online_cpus ();
1644- if (!ret && dyn_state )
1644+ /*
1645+ * If the requested state is CPUHP_AP_ONLINE_DYN, return the
1646+ * dynamically allocated state in case of success.
1647+ */
1648+ if (!ret && state == CPUHP_AP_ONLINE_DYN )
16451649 return state ;
16461650 return ret ;
16471651}
0 commit comments