Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/external/bsd/drm2/dist/drm/i915 Avoid taking locks durin...



details:   https://anonhg.NetBSD.org/src/rev/a266b67379f7
branches:  trunk
changeset: 815349:a266b67379f7
user:      christos <christos%NetBSD.org@localhost>
date:      Thu May 12 14:50:39 2016 +0000

description:
Avoid taking locks during interrupts and explain why we are doing it this way.

diffstat:

 sys/external/bsd/drm2/dist/drm/i915/i915_gpu_error.c |  33 ++++++++++++++-----
 1 files changed, 24 insertions(+), 9 deletions(-)

diffs (46 lines):

diff -r a1ec9415786f -r a266b67379f7 sys/external/bsd/drm2/dist/drm/i915/i915_gpu_error.c
--- a/sys/external/bsd/drm2/dist/drm/i915/i915_gpu_error.c      Thu May 12 14:25:11 2016 +0000
+++ b/sys/external/bsd/drm2/dist/drm/i915/i915_gpu_error.c      Thu May 12 14:50:39 2016 +0000
@@ -604,18 +604,33 @@
 
                        memcpy_fromio(d, (void __iomem *) offset, PAGE_SIZE);
                } else {
-                       struct page *page;
-                       void *s;
-
-                       page = i915_gem_object_get_page(src, i);
 
-                       drm_clflush_pages(&page, 1);
+                       if (cpu_intr_p() || cpu_softintr_p() ||
+                           (curlwp->l_pflag & LP_INTR) != 0) {
+                               /*
+                                * We can't take locks during interrupts
+                                * and finding the page from uvm requires
+                                * taking a lock. Checking for an interrupt
+                                * context is bogus, but this is the least
+                                * intrusive change. Zero the result, doesn't
+                                * matter much, because this is only used
+                                * for diagnostics.
+                                */
+                               memset(d, 0, PAGE_SIZE);
+                       } else {
+                               struct page *page;
+                               void *s;
 
-                       s = kmap_atomic(page);
-                       memcpy(d, s, PAGE_SIZE);
-                       kunmap_atomic(s);
+                               page = i915_gem_object_get_page(src, i);
+
+                               drm_clflush_pages(&page, 1);
 
-                       drm_clflush_pages(&page, 1);
+                               s = kmap_atomic(page);
+                               memcpy(d, s, PAGE_SIZE);
+                               kunmap_atomic(s);
+
+                               drm_clflush_pages(&page, 1);
+                       }
                }
                local_irq_restore(flags);
 



Home | Main Index | Thread Index | Old Index