Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e51f893 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'smp-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull CPU hotplug fix from Thomas Gleixner:
 "A single fix preventing the concurrent execution of the CPU hotplug
  callback install/invocation machinery. Long standing bug caused by a
  massive brain slip of that Gleixner dude, which went unnoticed for
  almost a year"

* 'smp-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  cpu/hotplug: Serialize callback invocations proper
parents 8d940990 dc434e05
Loading
Loading
Loading
Loading
+14 −14
Original line number Diff line number Diff line
@@ -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 @@ int __cpuhp_state_remove_instance(enum cpuhp_state state,
	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);