提交 dbf99c1f 编写于 作者: I Imre Deak

drm/i915: Force printing wakeref tacking during pm_cleanup

Make sure we print and drop the wakeref tracking info during pm_cleanup
even if there are wakeref holders (either raw-wakeref or wakelock
holders). Dropping the wakeref tracking means that a late put on the ref
will WARN since the wakeref will be unknown, but that is rightly so,
since the put is late and we want to catch that case.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: NImre Deak <imre.deak@intel.com>
Reviewed-by: NChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20190509173446.31095-3-imre.deak@intel.com
上级 4547c255
......@@ -232,32 +232,61 @@ __print_intel_runtime_pm_wakeref(struct drm_printer *p,
kfree(buf);
}
static noinline void
__untrack_all_wakerefs(struct intel_runtime_pm_debug *debug,
struct intel_runtime_pm_debug *saved)
{
*saved = *debug;
debug->owners = NULL;
debug->count = 0;
debug->last_release = __save_depot_stack();
}
static void
dump_and_free_wakeref_tracking(struct intel_runtime_pm_debug *debug)
{
struct drm_printer p;
if (!debug->count)
return;
p = drm_debug_printer("i915");
__print_intel_runtime_pm_wakeref(&p, debug);
kfree(debug->owners);
}
static noinline void
__intel_wakeref_dec_and_check_tracking(struct drm_i915_private *i915)
{
struct i915_runtime_pm *rpm = &i915->runtime_pm;
struct intel_runtime_pm_debug dbg = {};
struct drm_printer p;
unsigned long flags;
if (atomic_dec_and_lock_irqsave(&rpm->wakeref_count,
&rpm->debug.lock,
flags)) {
dbg = rpm->debug;
if (!atomic_dec_and_lock_irqsave(&rpm->wakeref_count,
&rpm->debug.lock,
flags))
return;
rpm->debug.owners = NULL;
rpm->debug.count = 0;
rpm->debug.last_release = __save_depot_stack();
__untrack_all_wakerefs(&rpm->debug, &dbg);
spin_unlock_irqrestore(&rpm->debug.lock, flags);
spin_unlock_irqrestore(&rpm->debug.lock, flags);
}
if (!dbg.count)
return;
dump_and_free_wakeref_tracking(&dbg);
}
p = drm_debug_printer("i915");
__print_intel_runtime_pm_wakeref(&p, &dbg);
static noinline void
untrack_all_intel_runtime_pm_wakerefs(struct drm_i915_private *i915)
{
struct i915_runtime_pm *rpm = &i915->runtime_pm;
struct intel_runtime_pm_debug dbg = {};
unsigned long flags;
kfree(dbg.owners);
spin_lock_irqsave(&rpm->debug.lock, flags);
__untrack_all_wakerefs(&rpm->debug, &dbg);
spin_unlock_irqrestore(&rpm->debug.lock, flags);
dump_and_free_wakeref_tracking(&dbg);
}
void print_intel_runtime_pm_wakeref(struct drm_i915_private *i915,
......@@ -321,6 +350,11 @@ __intel_wakeref_dec_and_check_tracking(struct drm_i915_private *i915)
atomic_dec(&i915->runtime_pm.wakeref_count);
}
static void
untrack_all_intel_runtime_pm_wakerefs(struct drm_i915_private *i915)
{
}
#endif
static void
......@@ -4838,15 +4872,14 @@ void intel_runtime_pm_disable(struct drm_i915_private *i915)
void intel_runtime_pm_cleanup(struct drm_i915_private *i915)
{
struct i915_runtime_pm *rpm = &i915->runtime_pm;
int count;
int count = atomic_read(&rpm->wakeref_count);
count = atomic_fetch_inc(&rpm->wakeref_count); /* balance untrack */
WARN(count,
"i915 raw-wakerefs=%d wakelocks=%d on cleanup\n",
intel_rpm_raw_wakeref_count(count),
intel_rpm_wakelock_count(count));
intel_runtime_pm_release(i915, false);
untrack_all_intel_runtime_pm_wakerefs(i915);
}
void intel_runtime_pm_init_early(struct drm_i915_private *i915)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册