diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_wakeref.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_wakeref.c | 35 | 
1 files changed, 34 insertions, 1 deletions
| diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c index 623a69089386..dea2f63184f8 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.c +++ b/drivers/gpu/drm/i915/intel_wakeref.c @@ -99,7 +99,8 @@ static void __intel_wakeref_put_work(struct work_struct *wrk)  void __intel_wakeref_init(struct intel_wakeref *wf,  			  struct drm_i915_private *i915,  			  const struct intel_wakeref_ops *ops, -			  struct intel_wakeref_lockclass *key) +			  struct intel_wakeref_lockclass *key, +			  const char *name)  {  	wf->i915 = i915;  	wf->ops = ops; @@ -111,6 +112,10 @@ void __intel_wakeref_init(struct intel_wakeref *wf,  	INIT_DELAYED_WORK(&wf->work, __intel_wakeref_put_work);  	lockdep_init_map(&wf->work.work.lockdep_map,  			 "wakeref.work", &key->work, 0); + +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_WAKEREF) +	ref_tracker_dir_init(&wf->debug, INTEL_REFTRACK_DEAD_COUNT, name); +#endif  }  int intel_wakeref_wait_for_idle(struct intel_wakeref *wf) @@ -191,3 +196,31 @@ void intel_wakeref_auto_fini(struct intel_wakeref_auto *wf)  	intel_wakeref_auto(wf, 0);  	INTEL_WAKEREF_BUG_ON(wf->wakeref);  } + +void intel_ref_tracker_show(struct ref_tracker_dir *dir, +			    struct drm_printer *p) +{ +	const size_t buf_size = PAGE_SIZE; +	char *buf, *sb, *se; +	size_t count; + +	buf = kmalloc(buf_size, GFP_NOWAIT); +	if (!buf) +		return; + +	count = ref_tracker_dir_snprint(dir, buf, buf_size); +	if (!count) +		goto free; +	/* printk does not like big buffers, so we split it */ +	for (sb = buf; *sb; sb = se + 1) { +		se = strchrnul(sb, '\n'); +		drm_printf(p, "%.*s", (int)(se - sb + 1), sb); +		if (!*se) +			break; +	} +	if (count >= buf_size) +		drm_printf(p, "\n...dropped %zd extra bytes of leak report.\n", +			   count + 1 - buf_size); +free: +	kfree(buf); +} | 
