aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTvrtko Ursulin <tvrtko.ursulin@intel.com>2018-03-14 04:05:35 -0400
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>2018-03-16 08:35:41 -0400
commit22de4e7a531b623962e62ee6d3a39a7e51bdf90e (patch)
treed3370de2ed2ad0c5369c9ba887ea237c78403f4b
parent73e2232aa3253d77935112bfc218700f6a2f1000 (diff)
drm/i915/pmu: Work around compiler warnings on some kernel configs
Arnd Bergman reports: """ The conditional spinlock confuses gcc into thinking the 'flags' value might contain uninitialized data: drivers/gpu/drm/i915/i915_pmu.c: In function '__i915_pmu_event_read': arch/x86/include/asm/paravirt_types.h:573:3: error: 'flags' may be used uninitialized in this function [-Werror=maybe-uninitialized] The code is correct, but it's easy to see how the compiler gets confused here. This avoids the problem by pulling the lock outside of the function into its only caller. """ On deeper look it seems this is caused by paravirt spinlocks implementation when CONFIG_PARAVIRT_DEBUG is set, which by being complicated, manages to convince gcc locked parameter can be changed externally (impossible). Work around it by removing the conditional locking parameters altogether. (It was never the most elegant code anyway.) Slight penalty we now pay is an additional irqsave spin lock/unlock cycle on the event enable path. But since enable is not a fast path, that is preferrable to the alternative solution which was doing MMIO under irqsave spinlock. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reported-by: Arnd Bergmann <arnd@arndb.de> Fixes: 1fe699e30113 ("drm/i915/pmu: Fix sleep under atomic in RC6 readout") Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Imre Deak <imre.deak@intel.com> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: David Airlie <airlied@linux.ie> Cc: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20180314080535.17490-1-tvrtko.ursulin@linux.intel.com (cherry picked from commit ad055fb8e010e4ff37f66aeed1d380329bddce67) Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_pmu.c32
1 files changed, 13 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index 964467b03e4d..d8feb9053e0c 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -433,7 +433,7 @@ static u64 __get_rc6(struct drm_i915_private *i915)
433 return val; 433 return val;
434} 434}
435 435
436static u64 get_rc6(struct drm_i915_private *i915, bool locked) 436static u64 get_rc6(struct drm_i915_private *i915)
437{ 437{
438#if IS_ENABLED(CONFIG_PM) 438#if IS_ENABLED(CONFIG_PM)
439 unsigned long flags; 439 unsigned long flags;
@@ -449,8 +449,7 @@ static u64 get_rc6(struct drm_i915_private *i915, bool locked)
449 * previously. 449 * previously.
450 */ 450 */
451 451
452 if (!locked) 452 spin_lock_irqsave(&i915->pmu.lock, flags);
453 spin_lock_irqsave(&i915->pmu.lock, flags);
454 453
455 if (val >= i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) { 454 if (val >= i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) {
456 i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = 0; 455 i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = 0;
@@ -459,12 +458,10 @@ static u64 get_rc6(struct drm_i915_private *i915, bool locked)
459 val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur; 458 val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur;
460 } 459 }
461 460
462 if (!locked) 461 spin_unlock_irqrestore(&i915->pmu.lock, flags);
463 spin_unlock_irqrestore(&i915->pmu.lock, flags);
464 } else { 462 } else {
465 struct pci_dev *pdev = i915->drm.pdev; 463 struct pci_dev *pdev = i915->drm.pdev;
466 struct device *kdev = &pdev->dev; 464 struct device *kdev = &pdev->dev;
467 unsigned long flags2;
468 465
469 /* 466 /*
470 * We are runtime suspended. 467 * We are runtime suspended.
@@ -473,10 +470,8 @@ static u64 get_rc6(struct drm_i915_private *i915, bool locked)
473 * on top of the last known real value, as the approximated RC6 470 * on top of the last known real value, as the approximated RC6
474 * counter value. 471 * counter value.
475 */ 472 */
476 if (!locked) 473 spin_lock_irqsave(&i915->pmu.lock, flags);
477 spin_lock_irqsave(&i915->pmu.lock, flags); 474 spin_lock(&kdev->power.lock);
478
479 spin_lock_irqsave(&kdev->power.lock, flags2);
480 475
481 if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) 476 if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
482 i915->pmu.suspended_jiffies_last = 477 i915->pmu.suspended_jiffies_last =
@@ -486,14 +481,13 @@ static u64 get_rc6(struct drm_i915_private *i915, bool locked)
486 i915->pmu.suspended_jiffies_last; 481 i915->pmu.suspended_jiffies_last;
487 val += jiffies - kdev->power.accounting_timestamp; 482 val += jiffies - kdev->power.accounting_timestamp;
488 483
489 spin_unlock_irqrestore(&kdev->power.lock, flags2); 484 spin_unlock(&kdev->power.lock);
490 485
491 val = jiffies_to_nsecs(val); 486 val = jiffies_to_nsecs(val);
492 val += i915->pmu.sample[__I915_SAMPLE_RC6].cur; 487 val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
493 i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val; 488 i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
494 489
495 if (!locked) 490 spin_unlock_irqrestore(&i915->pmu.lock, flags);
496 spin_unlock_irqrestore(&i915->pmu.lock, flags);
497 } 491 }
498 492
499 return val; 493 return val;
@@ -502,7 +496,7 @@ static u64 get_rc6(struct drm_i915_private *i915, bool locked)
502#endif 496#endif
503} 497}
504 498
505static u64 __i915_pmu_event_read(struct perf_event *event, bool locked) 499static u64 __i915_pmu_event_read(struct perf_event *event)
506{ 500{
507 struct drm_i915_private *i915 = 501 struct drm_i915_private *i915 =
508 container_of(event->pmu, typeof(*i915), pmu.base); 502 container_of(event->pmu, typeof(*i915), pmu.base);
@@ -540,7 +534,7 @@ static u64 __i915_pmu_event_read(struct perf_event *event, bool locked)
540 val = count_interrupts(i915); 534 val = count_interrupts(i915);
541 break; 535 break;
542 case I915_PMU_RC6_RESIDENCY: 536 case I915_PMU_RC6_RESIDENCY:
543 val = get_rc6(i915, locked); 537 val = get_rc6(i915);
544 break; 538 break;
545 } 539 }
546 } 540 }
@@ -555,7 +549,7 @@ static void i915_pmu_event_read(struct perf_event *event)
555 549
556again: 550again:
557 prev = local64_read(&hwc->prev_count); 551 prev = local64_read(&hwc->prev_count);
558 new = __i915_pmu_event_read(event, false); 552 new = __i915_pmu_event_read(event);
559 553
560 if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev) 554 if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev)
561 goto again; 555 goto again;
@@ -605,14 +599,14 @@ static void i915_pmu_enable(struct perf_event *event)
605 engine->pmu.enable_count[sample]++; 599 engine->pmu.enable_count[sample]++;
606 } 600 }
607 601
602 spin_unlock_irqrestore(&i915->pmu.lock, flags);
603
608 /* 604 /*
609 * Store the current counter value so we can report the correct delta 605 * Store the current counter value so we can report the correct delta
610 * for all listeners. Even when the event was already enabled and has 606 * for all listeners. Even when the event was already enabled and has
611 * an existing non-zero value. 607 * an existing non-zero value.
612 */ 608 */
613 local64_set(&event->hw.prev_count, __i915_pmu_event_read(event, true)); 609 local64_set(&event->hw.prev_count, __i915_pmu_event_read(event));
614
615 spin_unlock_irqrestore(&i915->pmu.lock, flags);
616} 610}
617 611
618static void i915_pmu_disable(struct perf_event *event) 612static void i915_pmu_disable(struct perf_event *event)