Currently i915 pmu driver gets registered with linux perf subsystem with its callback functions implemented, it is using spin_lock for synchronization where ever is needed. linux perf subsystem in some instance is using raw_spin_locks for synchronization and calls the i915 pmu callback functions with raw_spin_lock held.
The issue is When PREEMPT_RT is configured in kernel config the normal spin_lock behaves as mutex lock and when these are called with raw_spin_lock held race condition can occur.So in the path of the raw_spin_lock held convert spin_lock into raw_spin_lock where ever is needed. Signed-off-by: Ravi Kumar Vodapalli <[email protected]> --- drivers/gpu/drm/i915/i915_pmu.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c index 5bc696bfbb0f..d760ec44a98c 100644 --- a/drivers/gpu/drm/i915/i915_pmu.c +++ b/drivers/gpu/drm/i915/i915_pmu.c @@ -230,7 +230,7 @@ static u64 get_rc6(struct intel_gt *gt) intel_gt_pm_put_async(gt, wakeref); } - spin_lock_irqsave(&pmu->lock, flags); + raw_spin_lock_irqsave(&pmu->lock, flags); if (wakeref) { store_sample(pmu, gt_id, __I915_SAMPLE_RC6, val); @@ -251,7 +251,7 @@ static u64 get_rc6(struct intel_gt *gt) else store_sample(pmu, gt_id, __I915_SAMPLE_RC6_LAST_REPORTED, val); - spin_unlock_irqrestore(&pmu->lock, flags); + raw_spin_unlock_irqrestore(&pmu->lock, flags); return val; } @@ -302,7 +302,7 @@ void i915_pmu_gt_parked(struct intel_gt *gt) if (!pmu->registered) return; - spin_lock_irq(&pmu->lock); + raw_spin_lock_irq(&pmu->lock); park_rc6(gt); @@ -314,7 +314,7 @@ void i915_pmu_gt_parked(struct intel_gt *gt) if (pmu->unparked == 0) pmu->timer_enabled = false; - spin_unlock_irq(&pmu->lock); + raw_spin_unlock_irq(&pmu->lock); } void i915_pmu_gt_unparked(struct intel_gt *gt) @@ -324,7 +324,7 @@ void i915_pmu_gt_unparked(struct intel_gt *gt) if (!pmu->registered) return; - spin_lock_irq(&pmu->lock); + raw_spin_lock_irq(&pmu->lock); /* * Re-enable sampling timer when GPU goes active. @@ -334,7 +334,7 @@ void i915_pmu_gt_unparked(struct intel_gt *gt) pmu->unparked |= BIT(gt->info.id); - spin_unlock_irq(&pmu->lock); + raw_spin_unlock_irq(&pmu->lock); } static void @@ -740,7 +740,7 @@ static void i915_pmu_enable(struct perf_event *event) if (bit == -1) goto update; - spin_lock_irqsave(&pmu->lock, flags); + raw_spin_lock_irqsave(&pmu->lock, flags); /* * Update the bitmask of enabled events and increment @@ -782,7 +782,7 @@ static void i915_pmu_enable(struct perf_event *event) engine->pmu.enable_count[sample]++; } - spin_unlock_irqrestore(&pmu->lock, flags); + raw_spin_unlock_irqrestore(&pmu->lock, flags); update: /* @@ -803,7 +803,7 @@ static void i915_pmu_disable(struct perf_event *event) if (bit == -1) return; - spin_lock_irqsave(&pmu->lock, flags); + raw_spin_lock_irqsave(&pmu->lock, flags); if (is_engine_event(event)) { u8 sample = engine_event_sample(event); @@ -836,7 +836,7 @@ static void i915_pmu_disable(struct perf_event *event) pmu->timer_enabled &= pmu_needs_timer(pmu); } - spin_unlock_irqrestore(&pmu->lock, flags); + raw_spin_unlock_irqrestore(&pmu->lock, flags); } static void i915_pmu_event_start(struct perf_event *event, int flags) @@ -1154,7 +1154,7 @@ void i915_pmu_register(struct drm_i915_private *i915) }; int ret = -ENOMEM; - spin_lock_init(&pmu->lock); + raw_spin_lock_init(&pmu->lock); hrtimer_setup(&pmu->timer, i915_sample, CLOCK_MONOTONIC, HRTIMER_MODE_REL); init_rc6(pmu); -- 2.34.1
