Commit 19ee5e8d authored by Michał Winiarski's avatar Michał Winiarski Committed by Jani Nikula
Browse files

drm/i915/pmu: Avoid using globals for CPU hotplug state



Attempting to bind / unbind module from devices where we have both
integrated and discreete GPU handled by i915 can lead to leaks and
warnings from cpuhp:
Error: Removing state XXX which has instances left.

Let's move the state to i915_pmu.

Fixes: 05488673 ("drm/i915/pmu: Support multiple GPUs")
Signed-off-by: default avatarMichał Winiarski <michal.winiarski@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20200219161822.24592-1-michal.winiarski@intel.com


(cherry picked from commit f5a179d4)
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent eee18939
Loading
Loading
Loading
Loading
+9 −9
Original line number Original line Diff line number Diff line
@@ -1042,7 +1042,7 @@ static void free_event_attributes(struct i915_pmu *pmu)


static int i915_pmu_cpu_online(unsigned int cpu, struct hlist_node *node)
static int i915_pmu_cpu_online(unsigned int cpu, struct hlist_node *node)
{
{
	struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), node);
	struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);


	GEM_BUG_ON(!pmu->base.event_init);
	GEM_BUG_ON(!pmu->base.event_init);


@@ -1055,7 +1055,7 @@ static int i915_pmu_cpu_online(unsigned int cpu, struct hlist_node *node)


static int i915_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
static int i915_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
{
{
	struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), node);
	struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
	unsigned int target;
	unsigned int target;


	GEM_BUG_ON(!pmu->base.event_init);
	GEM_BUG_ON(!pmu->base.event_init);
@@ -1072,8 +1072,6 @@ static int i915_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
	return 0;
	return 0;
}
}


static enum cpuhp_state cpuhp_slot = CPUHP_INVALID;

static int i915_pmu_register_cpuhp_state(struct i915_pmu *pmu)
static int i915_pmu_register_cpuhp_state(struct i915_pmu *pmu)
{
{
	enum cpuhp_state slot;
	enum cpuhp_state slot;
@@ -1087,21 +1085,22 @@ static int i915_pmu_register_cpuhp_state(struct i915_pmu *pmu)
		return ret;
		return ret;


	slot = ret;
	slot = ret;
	ret = cpuhp_state_add_instance(slot, &pmu->node);
	ret = cpuhp_state_add_instance(slot, &pmu->cpuhp.node);
	if (ret) {
	if (ret) {
		cpuhp_remove_multi_state(slot);
		cpuhp_remove_multi_state(slot);
		return ret;
		return ret;
	}
	}


	cpuhp_slot = slot;
	pmu->cpuhp.slot = slot;
	return 0;
	return 0;
}
}


static void i915_pmu_unregister_cpuhp_state(struct i915_pmu *pmu)
static void i915_pmu_unregister_cpuhp_state(struct i915_pmu *pmu)
{
{
	WARN_ON(cpuhp_slot == CPUHP_INVALID);
	WARN_ON(pmu->cpuhp.slot == CPUHP_INVALID);
	WARN_ON(cpuhp_state_remove_instance(cpuhp_slot, &pmu->node));
	WARN_ON(cpuhp_state_remove_instance(pmu->cpuhp.slot, &pmu->cpuhp.node));
	cpuhp_remove_multi_state(cpuhp_slot);
	cpuhp_remove_multi_state(pmu->cpuhp.slot);
	pmu->cpuhp.slot = CPUHP_INVALID;
}
}


static bool is_igp(struct drm_i915_private *i915)
static bool is_igp(struct drm_i915_private *i915)
@@ -1128,6 +1127,7 @@ void i915_pmu_register(struct drm_i915_private *i915)
	spin_lock_init(&pmu->lock);
	spin_lock_init(&pmu->lock);
	hrtimer_init(&pmu->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	hrtimer_init(&pmu->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	pmu->timer.function = i915_sample;
	pmu->timer.function = i915_sample;
	pmu->cpuhp.slot = CPUHP_INVALID;


	if (!is_igp(i915)) {
	if (!is_igp(i915)) {
		pmu->name = kasprintf(GFP_KERNEL,
		pmu->name = kasprintf(GFP_KERNEL,
+5 −2
Original line number Original line Diff line number Diff line
@@ -39,9 +39,12 @@ struct i915_pmu_sample {


struct i915_pmu {
struct i915_pmu {
	/**
	/**
	 * @node: List node for CPU hotplug handling.
	 * @cpuhp: Struct used for CPU hotplug handling.
	 */
	 */
	struct {
		struct hlist_node node;
		struct hlist_node node;
		enum cpuhp_state slot;
	} cpuhp;
	/**
	/**
	 * @base: PMU base.
	 * @base: PMU base.
	 */
	 */