|
@@ -1335,26 +1335,21 @@ static int cpuhp_store_callbacks(enum cpuhp_state state, const char *name,
|
|
|
struct cpuhp_step *sp;
|
|
|
int ret = 0;
|
|
|
|
|
|
- mutex_lock(&cpuhp_state_mutex);
|
|
|
-
|
|
|
if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) {
|
|
|
ret = cpuhp_reserve_state(state);
|
|
|
if (ret < 0)
|
|
|
- goto out;
|
|
|
+ return ret;
|
|
|
state = ret;
|
|
|
}
|
|
|
sp = cpuhp_get_step(state);
|
|
|
- if (name && sp->name) {
|
|
|
- ret = -EBUSY;
|
|
|
- goto out;
|
|
|
- }
|
|
|
+ if (name && sp->name)
|
|
|
+ return -EBUSY;
|
|
|
+
|
|
|
sp->startup.single = startup;
|
|
|
sp->teardown.single = teardown;
|
|
|
sp->name = name;
|
|
|
sp->multi_instance = multi_instance;
|
|
|
INIT_HLIST_HEAD(&sp->list);
|
|
|
-out:
|
|
|
- mutex_unlock(&cpuhp_state_mutex);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -1428,6 +1423,7 @@ int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node,
|
|
|
return -EINVAL;
|
|
|
|
|
|
get_online_cpus();
|
|
|
+ mutex_lock(&cpuhp_state_mutex);
|
|
|
|
|
|
if (!invoke || !sp->startup.multi)
|
|
|
goto add_node;
|
|
@@ -1447,16 +1443,14 @@ int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node,
|
|
|
if (ret) {
|
|
|
if (sp->teardown.multi)
|
|
|
cpuhp_rollback_install(cpu, state, node);
|
|
|
- goto err;
|
|
|
+ goto unlock;
|
|
|
}
|
|
|
}
|
|
|
add_node:
|
|
|
ret = 0;
|
|
|
- mutex_lock(&cpuhp_state_mutex);
|
|
|
hlist_add_head(node, &sp->list);
|
|
|
+unlock:
|
|
|
mutex_unlock(&cpuhp_state_mutex);
|
|
|
-
|
|
|
-err:
|
|
|
put_online_cpus();
|
|
|
return ret;
|
|
|
}
|
|
@@ -1491,6 +1485,7 @@ int __cpuhp_setup_state(enum cpuhp_state state,
|
|
|
return -EINVAL;
|
|
|
|
|
|
get_online_cpus();
|
|
|
+ mutex_lock(&cpuhp_state_mutex);
|
|
|
|
|
|
ret = cpuhp_store_callbacks(state, name, startup, teardown,
|
|
|
multi_instance);
|
|
@@ -1524,6 +1519,7 @@ int __cpuhp_setup_state(enum cpuhp_state state,
|
|
|
}
|
|
|
}
|
|
|
out:
|
|
|
+ mutex_unlock(&cpuhp_state_mutex);
|
|
|
put_online_cpus();
|
|
|
/*
|
|
|
* If the requested state is CPUHP_AP_ONLINE_DYN, return the
|
|
@@ -1547,6 +1543,8 @@ int __cpuhp_state_remove_instance(enum cpuhp_state state,
|
|
|
return -EINVAL;
|
|
|
|
|
|
get_online_cpus();
|
|
|
+ mutex_lock(&cpuhp_state_mutex);
|
|
|
+
|
|
|
if (!invoke || !cpuhp_get_teardown_cb(state))
|
|
|
goto remove;
|
|
|
/*
|
|
@@ -1563,7 +1561,6 @@ int __cpuhp_state_remove_instance(enum cpuhp_state state,
|
|
|
}
|
|
|
|
|
|
remove:
|
|
|
- mutex_lock(&cpuhp_state_mutex);
|
|
|
hlist_del(node);
|
|
|
mutex_unlock(&cpuhp_state_mutex);
|
|
|
put_online_cpus();
|
|
@@ -1571,6 +1568,7 @@ remove:
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(__cpuhp_state_remove_instance);
|
|
|
+
|
|
|
/**
|
|
|
* __cpuhp_remove_state - Remove the callbacks for an hotplug machine state
|
|
|
* @state: The state to remove
|
|
@@ -1589,6 +1587,7 @@ void __cpuhp_remove_state(enum cpuhp_state state, bool invoke)
|
|
|
|
|
|
get_online_cpus();
|
|
|
|
|
|
+ mutex_lock(&cpuhp_state_mutex);
|
|
|
if (sp->multi_instance) {
|
|
|
WARN(!hlist_empty(&sp->list),
|
|
|
"Error: Removing state %d which has instances left.\n",
|
|
@@ -1613,6 +1612,7 @@ void __cpuhp_remove_state(enum cpuhp_state state, bool invoke)
|
|
|
}
|
|
|
remove:
|
|
|
cpuhp_store_callbacks(state, NULL, NULL, NULL, false);
|
|
|
+ mutex_unlock(&cpuhp_state_mutex);
|
|
|
put_online_cpus();
|
|
|
}
|
|
|
EXPORT_SYMBOL(__cpuhp_remove_state);
|