Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10195b1e authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Show vma allocator stack when in doubt



At the moment, gem_exec_gttfill fails with a sporadic EBUSY due to us
wanting to unbind a pinned batch. Let's dump who first bound that vma to
see if that helps us identify who still unexpectedly has it pinned.

v2: We cannot allocate inside the printer (as it may be on an fs-reclaim
path), so hope for the best and build the string on the stack
v3: stack depth of 16 routinely overflows a 512 character string, limit
it to 12 to avoid unsightly truncation.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180628132206.8329-1-chris@chris-wilson.co.uk
parent a24362ea
Loading
Loading
Loading
Loading
+37 −2
Original line number Diff line number Diff line
@@ -30,6 +30,39 @@

#include <drm/drm_gem.h>

#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && IS_ENABLED(CONFIG_DRM_DEBUG_MM)

#include <linux/stackdepot.h>

static void vma_print_allocator(struct i915_vma *vma, const char *reason)
{
	unsigned long entries[12];
	struct stack_trace trace = {
		.entries = entries,
		.max_entries = ARRAY_SIZE(entries),
	};
	char buf[512];

	if (!vma->node.stack) {
		DRM_DEBUG_DRIVER("vma.node [%08llx + %08llx] %s: unknown owner\n",
				 vma->node.start, vma->node.size, reason);
		return;
	}

	depot_fetch_stack(vma->node.stack, &trace);
	snprint_stack_trace(buf, sizeof(buf), &trace, 0);
	DRM_DEBUG_DRIVER("vma.node [%08llx + %08llx] %s: inserted at %s\n",
			 vma->node.start, vma->node.size, reason, buf);
}

#else

static void vma_print_allocator(struct i915_vma *vma, const char *reason)
{
}

#endif

static void
i915_vma_retire(struct i915_gem_active *active, struct i915_request *rq)
{
@@ -875,8 +908,10 @@ int i915_vma_unbind(struct i915_vma *vma)
	}
	GEM_BUG_ON(i915_vma_is_active(vma));

	if (i915_vma_is_pinned(vma))
	if (i915_vma_is_pinned(vma)) {
		vma_print_allocator(vma, "is pinned");
		return -EBUSY;
	}

	if (!drm_mm_node_allocated(&vma->node))
		return 0;