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

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
...@@ -1042,7 +1042,7 @@ static void free_event_attributes(struct i915_pmu *pmu) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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,
......
...@@ -39,9 +39,12 @@ struct i915_pmu_sample { ...@@ -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 hlist_node node; struct {
struct hlist_node node;
enum cpuhp_state slot;
} cpuhp;
/** /**
* @base: PMU base. * @base: PMU base.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment