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: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180628132206.8329-1-chris@chris-wilson.co.uk
This commit is contained in:
		
							parent
							
								
									a24362ead9
								
							
						
					
					
						commit
						10195b1e44
					
				| @ -30,6 +30,39 @@ | |||||||
| 
 | 
 | ||||||
| #include <drm/drm_gem.h> | #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 | static void | ||||||
| i915_vma_retire(struct i915_gem_active *active, struct i915_request *rq) | 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)); | 	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; | 		return -EBUSY; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!drm_mm_node_allocated(&vma->node)) | 	if (!drm_mm_node_allocated(&vma->node)) | ||||||
| 		return 0; | 		return 0; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user