| From d4aeee776017b6da6dcd12f453cd82a3c951a0dc Mon Sep 17 00:00:00 2001 |
| From: Chris Wilson <chris@chris-wilson.co.uk> |
| Date: Mon, 14 Mar 2011 15:11:24 +0000 |
| Subject: drm/i915: Disable pagefaults along execbuffer relocation fast path |
| |
| From: Chris Wilson <chris@chris-wilson.co.uk> |
| |
| commit d4aeee776017b6da6dcd12f453cd82a3c951a0dc upstream. |
| |
| Along the fast path for relocation handling, we attempt to copy directly |
| from the user data structures whilst holding our mutex. This causes |
| lockdep to warn about circular lock dependencies if we need to pagefault |
| the user pages. [Since when handling a page fault on a mmapped bo, we |
| need to acquire the struct mutex whilst already holding the mm |
| semaphore, it is then verboten to acquire the mm semaphore when already |
| holding the struct mutex. The likelihood of the user passing in the |
| relocations contained in a GTT mmaped bo is low, but conceivable for |
| extreme pathology.] In order to force the mm to return EFAULT rather |
| than handle the pagefault, we therefore need to disable pagefaults |
| across the relocation fast path. |
| |
| Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> |
| Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/gpu/drm/i915/i915_gem_execbuffer.c | 19 ++++++++++++++++--- |
| 1 file changed, 16 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c |
| +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c |
| @@ -388,6 +388,10 @@ i915_gem_execbuffer_relocate_entry(struc |
| uint32_t __iomem *reloc_entry; |
| void __iomem *reloc_page; |
| |
| + /* We can't wait for rendering with pagefaults disabled */ |
| + if (obj->active && in_atomic()) |
| + return -EFAULT; |
| + |
| ret = i915_gem_object_set_to_gtt_domain(obj, 1); |
| if (ret) |
| return ret; |
| @@ -461,15 +465,24 @@ i915_gem_execbuffer_relocate(struct drm_ |
| struct list_head *objects) |
| { |
| struct drm_i915_gem_object *obj; |
| - int ret; |
| + int ret = 0; |
| |
| + /* This is the fast path and we cannot handle a pagefault whilst |
| + * holding the struct mutex lest the user pass in the relocations |
| + * contained within a mmaped bo. For in such a case we, the page |
| + * fault handler would call i915_gem_fault() and we would try to |
| + * acquire the struct mutex again. Obviously this is bad and so |
| + * lockdep complains vehemently. |
| + */ |
| + pagefault_disable(); |
| list_for_each_entry(obj, objects, exec_list) { |
| ret = i915_gem_execbuffer_relocate_object(obj, eb); |
| if (ret) |
| - return ret; |
| + break; |
| } |
| + pagefault_enable(); |
| |
| - return 0; |
| + return ret; |
| } |
| |
| static int |