drm/i915: Avoid atomic context for error capture
authorBruce Chang <yu.bruce.chang@intel.com>
Wed, 13 Nov 2019 23:11:04 +0000 (15:11 -0800)
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Mon, 18 Nov 2019 14:36:14 +0000 (16:36 +0200)
io_mapping_map_atomic/kmap_atomic are occasionally taken in error capture
(if there is no aperture preallocated for the use of error capture), but
the error capture and compression routines are now run in normal
context:

<3> [113.316247] BUG: sleeping function called from invalid context at mm/page_alloc.c:4653
<3> [113.318190] in_atomic(): 1, irqs_disabled(): 0, pid: 678, name: debugfs_test
<4> [113.319900] no locks held by debugfs_test/678.
<3> [113.321002] Preemption disabled at:
<4> [113.321130] [<ffffffffa02506d4>] i915_error_object_create+0x494/0x610 [i915]
<4> [113.327259] Call Trace:
<4> [113.327871] dump_stack+0x67/0x9b
<4> [113.328683] ___might_sleep+0x167/0x250
<4> [113.329618] __alloc_pages_nodemask+0x26b/0x1110
<4> [113.334614] pool_alloc.constprop.19+0x14/0x60 [i915]
<4> [113.335951] compress_page+0x7c/0x100 [i915]
<4> [113.337110] i915_error_object_create+0x4bd/0x610 [i915]
<4> [113.338515] i915_capture_gpu_state+0x384/0x1680 [i915]

However, it is not a good idea to run the slow compression inside atomic
context, so we choose not to.

Fixes: 895d8ebeaa924 ("drm/i915: error capture with no ggtt slot")
Signed-off-by: Bruce Chang <yu.bruce.chang@intel.com>
Reviewed-by: Brian Welty <brian.welty@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20191113231104.24208-1-yu.bruce.chang@intel.com
(cherry picked from commit 48715f7001742e0d1cb20cffab1a0d75f5f7ad72)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
drivers/gpu/drm/i915/i915_gpu_error.c

index e8b67f5e521df0b7d2dc673363bec71d8c2adac6..3c85cb0ee99f40985b911a7f26944d4bc38fee4f 100644 (file)
@@ -1029,9 +1029,9 @@ i915_error_object_create(struct drm_i915_private *i915,
                for_each_sgt_daddr(dma, iter, vma->pages) {
                        void __iomem *s;
 
-                       s = io_mapping_map_atomic_wc(&mem->iomap, dma);
+                       s = io_mapping_map_wc(&mem->iomap, dma, PAGE_SIZE);
                        ret = compress_page(compress, (void __force *)s, dst);
-                       io_mapping_unmap_atomic(s);
+                       io_mapping_unmap(s);
                        if (ret)
                                break;
                }
@@ -1043,9 +1043,9 @@ i915_error_object_create(struct drm_i915_private *i915,
 
                        drm_clflush_pages(&page, 1);
 
-                       s = kmap_atomic(page);
+                       s = kmap(page);
                        ret = compress_page(compress, s, dst);
-                       kunmap_atomic(s);
+                       kunmap(s);
 
                        drm_clflush_pages(&page, 1);