summaryrefslogtreecommitdiffstats
path: root/kernel/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r--kernel/cpu.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
index f7c063239fa5..37b223e4fc05 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1335,26 +1335,21 @@ static int cpuhp_store_callbacks(enum cpuhp_state state, const char *name,
1335 struct cpuhp_step *sp; 1335 struct cpuhp_step *sp;
1336 int ret = 0; 1336 int ret = 0;
1337 1337
1338 mutex_lock(&cpuhp_state_mutex);
1339
1340 if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) { 1338 if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) {
1341 ret = cpuhp_reserve_state(state); 1339 ret = cpuhp_reserve_state(state);
1342 if (ret < 0) 1340 if (ret < 0)
1343 goto out; 1341 return ret;
1344 state = ret; 1342 state = ret;
1345 } 1343 }
1346 sp = cpuhp_get_step(state); 1344 sp = cpuhp_get_step(state);
1347 if (name && sp->name) { 1345 if (name && sp->name)
1348 ret = -EBUSY; 1346 return -EBUSY;
1349 goto out; 1347
1350 }
1351 sp->startup.single = startup; 1348 sp->startup.single = startup;
1352 sp->teardown.single = teardown; 1349 sp->teardown.single = teardown;
1353 sp->name = name; 1350 sp->name = name;
1354 sp->multi_instance = multi_instance; 1351 sp->multi_instance = multi_instance;
1355 INIT_HLIST_HEAD(&sp->list); 1352 INIT_HLIST_HEAD(&sp->list);
1356out:
1357 mutex_unlock(&cpuhp_state_mutex);
1358 return ret; 1353 return ret;
1359} 1354}
1360 1355
@@ -1428,6 +1423,7 @@ int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node,
1428 return -EINVAL; 1423 return -EINVAL;
1429 1424
1430 get_online_cpus(); 1425 get_online_cpus();
1426 mutex_lock(&cpuhp_state_mutex);
1431 1427
1432 if (!invoke || !sp->startup.multi) 1428 if (!invoke || !sp->startup.multi)
1433 goto add_node; 1429 goto add_node;
@@ -1447,16 +1443,14 @@ int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node,
1447 if (ret) { 1443 if (ret) {
1448 if (sp->teardown.multi) 1444 if (sp->teardown.multi)
1449 cpuhp_rollback_install(cpu, state, node); 1445 cpuhp_rollback_install(cpu, state, node);
1450 goto err; 1446 goto unlock;
1451 } 1447 }
1452 } 1448 }
1453add_node: 1449add_node:
1454 ret = 0; 1450 ret = 0;
1455 mutex_lock(&cpuhp_state_mutex);
1456 hlist_add_head(node, &sp->list); 1451 hlist_add_head(node, &sp->list);
1452unlock:
1457 mutex_unlock(&cpuhp_state_mutex); 1453 mutex_unlock(&cpuhp_state_mutex);
1458
1459err:
1460 put_online_cpus(); 1454 put_online_cpus();
1461 return ret; 1455 return ret;
1462} 1456}
@@ -1491,6 +1485,7 @@ int __cpuhp_setup_state(enum cpuhp_state state,
1491 return -EINVAL; 1485 return -EINVAL;
1492 1486
1493 get_online_cpus(); 1487 get_online_cpus();
1488 mutex_lock(&cpuhp_state_mutex);
1494 1489
1495 ret = cpuhp_store_callbacks(state, name, startup, teardown, 1490 ret = cpuhp_store_callbacks(state, name, startup, teardown,
1496 multi_instance); 1491 multi_instance);
@@ -1524,6 +1519,7 @@ int __cpuhp_setup_state(enum cpuhp_state state,
1524 } 1519 }
1525 } 1520 }
1526out: 1521out:
1522 mutex_unlock(&cpuhp_state_mutex);
1527 put_online_cpus(); 1523 put_online_cpus();
1528 /* 1524 /*
1529 * If the requested state is CPUHP_AP_ONLINE_DYN, return the 1525 * If the requested state is CPUHP_AP_ONLINE_DYN, return the
@@ -1547,6 +1543,8 @@ int __cpuhp_state_remove_instance(enum cpuhp_state state,
1547 return -EINVAL; 1543 return -EINVAL;
1548 1544
1549 get_online_cpus(); 1545 get_online_cpus();
1546 mutex_lock(&cpuhp_state_mutex);
1547
1550 if (!invoke || !cpuhp_get_teardown_cb(state)) 1548 if (!invoke || !cpuhp_get_teardown_cb(state))
1551 goto remove; 1549 goto remove;
1552 /* 1550 /*
@@ -1563,7 +1561,6 @@ int __cpuhp_state_remove_instance(enum cpuhp_state state,
1563 } 1561 }
1564 1562
1565remove: 1563remove:
1566 mutex_lock(&cpuhp_state_mutex);
1567 hlist_del(node); 1564 hlist_del(node);
1568 mutex_unlock(&cpuhp_state_mutex); 1565 mutex_unlock(&cpuhp_state_mutex);
1569 put_online_cpus(); 1566 put_online_cpus();
@@ -1571,6 +1568,7 @@ remove:
1571 return 0; 1568 return 0;
1572} 1569}
1573EXPORT_SYMBOL_GPL(__cpuhp_state_remove_instance); 1570EXPORT_SYMBOL_GPL(__cpuhp_state_remove_instance);
1571
1574/** 1572/**
1575 * __cpuhp_remove_state - Remove the callbacks for an hotplug machine state 1573 * __cpuhp_remove_state - Remove the callbacks for an hotplug machine state
1576 * @state: The state to remove 1574 * @state: The state to remove
@@ -1589,6 +1587,7 @@ void __cpuhp_remove_state(enum cpuhp_state state, bool invoke)
1589 1587
1590 get_online_cpus(); 1588 get_online_cpus();
1591 1589
1590 mutex_lock(&cpuhp_state_mutex);
1592 if (sp->multi_instance) { 1591 if (sp->multi_instance) {
1593 WARN(!hlist_empty(&sp->list), 1592 WARN(!hlist_empty(&sp->list),
1594 "Error: Removing state %d which has instances left.\n", 1593 "Error: Removing state %d which has instances left.\n",
@@ -1613,6 +1612,7 @@ void __cpuhp_remove_state(enum cpuhp_state state, bool invoke)
1613 } 1612 }
1614remove: 1613remove:
1615 cpuhp_store_callbacks(state, NULL, NULL, NULL, false); 1614 cpuhp_store_callbacks(state, NULL, NULL, NULL, false);
1615 mutex_unlock(&cpuhp_state_mutex);
1616 put_online_cpus(); 1616 put_online_cpus();
1617} 1617}
1618EXPORT_SYMBOL(__cpuhp_remove_state); 1618EXPORT_SYMBOL(__cpuhp_remove_state);