* [PATCH] drm/i915: Record error batch buffers using iomem [not found] <0100511104818.8382a7de.akpm@linux-foundation.org> @ 2010-05-11 18:22 ` Chris Wilson 2010-05-11 15:37 ` Andrew Morton 2010-05-11 19:22 ` Jaswinder Singh Rajput 0 siblings, 2 replies; 4+ messages in thread From: Chris Wilson @ 2010-05-11 18:22 UTC (permalink / raw) To: intel-gfx; +Cc: linux-kernel, dri-devel, Jaswinder Singh Rajput, Andrew Morton Directly read the GTT mapping for the contents of the batch buffers rather than relying on possibly stale CPU caches. Also for completeness scan the flushing/inactive lists for the current buffers - we are collecting error state after all. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> --- drivers/gpu/drm/i915/i915_irq.c | 64 ++++++++++++++++++++++++++++++++++---- 1 files changed, 57 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 87113da..14301a4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -441,9 +441,11 @@ static struct drm_i915_error_object * i915_error_object_create(struct drm_device *dev, struct drm_gem_object *src) { + drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_error_object *dst; struct drm_i915_gem_object *src_priv; int page, page_count; + u32 reloc_offset; if (src == NULL) return NULL; @@ -458,14 +460,23 @@ i915_error_object_create(struct drm_device *dev, if (dst == NULL) return NULL; + reloc_offset = src_priv->gtt_offset; for (page = 0; page < page_count; page++) { - void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); + void __iomem *s; + void *d; + + d = kmalloc(PAGE_SIZE, GFP_ATOMIC); if (d == NULL) goto unwind; - s = kmap_atomic(src_priv->pages[page], KM_USER0); - memcpy(d, s, PAGE_SIZE); - kunmap_atomic(s, KM_USER0); + + s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, + reloc_offset); + memcpy_fromio(d, s, PAGE_SIZE); + io_mapping_unmap_atomic(s); + dst->pages[page] = d; + + reloc_offset += PAGE_SIZE; } dst->page_count = page_count; dst->gtt_offset = src_priv->gtt_offset; @@ -621,18 +632,57 @@ static void i915_capture_error_state(struct drm_device *dev) if (batchbuffer[1] == NULL && error->acthd >= obj_priv->gtt_offset && - error->acthd < obj_priv->gtt_offset + obj->size && - batchbuffer[0] != obj) + error->acthd < obj_priv->gtt_offset + obj->size) batchbuffer[1] = obj; count++; } + /* Scan the other lists for completeness for those bizarre errors. */ + if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { + list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { + struct drm_gem_object *obj = obj_priv->obj; + + if (batchbuffer[0] == NULL && + bbaddr >= obj_priv->gtt_offset && + bbaddr < obj_priv->gtt_offset + obj->size) + batchbuffer[0] = obj; + + if (batchbuffer[1] == NULL && + error->acthd >= obj_priv->gtt_offset && + error->acthd < obj_priv->gtt_offset + obj->size) + batchbuffer[1] = obj; + + if (batchbuffer[0] && batchbuffer[1]) + break; + } + } + if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { + list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { + struct drm_gem_object *obj = obj_priv->obj; + + if (batchbuffer[0] == NULL && + bbaddr >= obj_priv->gtt_offset && + bbaddr < obj_priv->gtt_offset + obj->size) + batchbuffer[0] = obj; + + if (batchbuffer[1] == NULL && + error->acthd >= obj_priv->gtt_offset && + error->acthd < obj_priv->gtt_offset + obj->size) + batchbuffer[1] = obj; + + if (batchbuffer[0] && batchbuffer[1]) + break; + } + } /* We need to copy these to an anonymous buffer as the simplest * method to avoid being overwritten by userpace. */ error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); - error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); + if (batchbuffer[1] != batchbuffer[0]) + error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); + else + error->batchbuffer[1] = NULL; /* Record the ringbuffer */ error->ringbuffer = i915_error_object_create(dev, dev_priv->ring.ring_obj); -- 1.7.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] drm/i915: Record error batch buffers using iomem 2010-05-11 18:22 ` [PATCH] drm/i915: Record error batch buffers using iomem Chris Wilson @ 2010-05-11 15:37 ` Andrew Morton 2010-05-11 18:49 ` Chris Wilson 2010-05-11 19:22 ` Jaswinder Singh Rajput 1 sibling, 1 reply; 4+ messages in thread From: Andrew Morton @ 2010-05-11 15:37 UTC (permalink / raw) To: Chris Wilson Cc: intel-gfx, Jaswinder Singh Rajput, dri-devel, Dave Airlie, linux-kernel On Tue, 11 May 2010 19:22:14 +0100 Chris Wilson <chris@chris-wilson.co.uk> wrote: > + reloc_offset = src_priv->gtt_offset; > for (page = 0; page < page_count; page++) { > - void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); > + void __iomem *s; > + void *d; > + > + d = kmalloc(PAGE_SIZE, GFP_ATOMIC); > if (d == NULL) > goto unwind; > - s = kmap_atomic(src_priv->pages[page], KM_USER0); > - memcpy(d, s, PAGE_SIZE); > - kunmap_atomic(s, KM_USER0); > + > + s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, > + reloc_offset); > + memcpy_fromio(d, s, PAGE_SIZE); > + io_mapping_unmap_atomic(s); As mentioned in the other email, this will still corrupt the KM_USER0 slot, and will generate a debug_kmap_atomic() warning. ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] drm/i915: Record error batch buffers using iomem 2010-05-11 15:37 ` Andrew Morton @ 2010-05-11 18:49 ` Chris Wilson 0 siblings, 0 replies; 4+ messages in thread From: Chris Wilson @ 2010-05-11 18:49 UTC (permalink / raw) To: Andrew Morton Cc: intel-gfx, Jaswinder Singh Rajput, dri-devel, Dave Airlie, linux-kernel On Tue, 11 May 2010 11:37:22 -0400, Andrew Morton <akpm@linux-foundation.org> wrote: > On Tue, 11 May 2010 19:22:14 +0100 Chris Wilson <chris@chris-wilson.co.uk> wrote: > > > + reloc_offset = src_priv->gtt_offset; > > for (page = 0; page < page_count; page++) { > > - void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); > > + void __iomem *s; > > + void *d; > > + > > + d = kmalloc(PAGE_SIZE, GFP_ATOMIC); > > if (d == NULL) > > goto unwind; > > - s = kmap_atomic(src_priv->pages[page], KM_USER0); > > - memcpy(d, s, PAGE_SIZE); > > - kunmap_atomic(s, KM_USER0); > > + > > + s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, > > + reloc_offset); > > + memcpy_fromio(d, s, PAGE_SIZE); > > + io_mapping_unmap_atomic(s); > > As mentioned in the other email, this will still corrupt the KM_USER0 > slot, and will generate a debug_kmap_atomic() warning. How, as kmap_atomic(KM_USER0) is no longer used? -- Chris Wilson, Intel Open Source Technology Centre ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] drm/i915: Record error batch buffers using iomem 2010-05-11 18:22 ` [PATCH] drm/i915: Record error batch buffers using iomem Chris Wilson 2010-05-11 15:37 ` Andrew Morton @ 2010-05-11 19:22 ` Jaswinder Singh Rajput 1 sibling, 0 replies; 4+ messages in thread From: Jaswinder Singh Rajput @ 2010-05-11 19:22 UTC (permalink / raw) To: Chris Wilson; +Cc: intel-gfx, Andrew Morton, dri-devel, linux-kernel Hello Chris and Andrew, On Tue, May 11, 2010 at 11:52 PM, Chris Wilson <chris@chris-wilson.co.uk> wrote: > Directly read the GTT mapping for the contents of the batch buffers > rather than relying on possibly stale CPU caches. Also for completeness > scan the flushing/inactive lists for the current buffers - we are > collecting error state after all. > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Yes, I have tested this patch. I booted 3 times, and this patch fixes the DRM as well as softirq warnings and I am getting Xwindows with this patch. I am still doing more testing. Thanks, -- Jaswinder Singh. > --- > drivers/gpu/drm/i915/i915_irq.c | 64 ++++++++++++++++++++++++++++++++++---- > 1 files changed, 57 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index 87113da..14301a4 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -441,9 +441,11 @@ static struct drm_i915_error_object * > i915_error_object_create(struct drm_device *dev, > struct drm_gem_object *src) > { > + drm_i915_private_t *dev_priv = dev->dev_private; > struct drm_i915_error_object *dst; > struct drm_i915_gem_object *src_priv; > int page, page_count; > + u32 reloc_offset; > > if (src == NULL) > return NULL; > @@ -458,14 +460,23 @@ i915_error_object_create(struct drm_device *dev, > if (dst == NULL) > return NULL; > > + reloc_offset = src_priv->gtt_offset; > for (page = 0; page < page_count; page++) { > - void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); > + void __iomem *s; > + void *d; > + > + d = kmalloc(PAGE_SIZE, GFP_ATOMIC); > if (d == NULL) > goto unwind; > - s = kmap_atomic(src_priv->pages[page], KM_USER0); > - memcpy(d, s, PAGE_SIZE); > - kunmap_atomic(s, KM_USER0); > + > + s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, > + reloc_offset); > + memcpy_fromio(d, s, PAGE_SIZE); > + io_mapping_unmap_atomic(s); > + > dst->pages[page] = d; > + > + reloc_offset += PAGE_SIZE; > } > dst->page_count = page_count; > dst->gtt_offset = src_priv->gtt_offset; > @@ -621,18 +632,57 @@ static void i915_capture_error_state(struct drm_device *dev) > > if (batchbuffer[1] == NULL && > error->acthd >= obj_priv->gtt_offset && > - error->acthd < obj_priv->gtt_offset + obj->size && > - batchbuffer[0] != obj) > + error->acthd < obj_priv->gtt_offset + obj->size) > batchbuffer[1] = obj; > > count++; > } > + /* Scan the other lists for completeness for those bizarre errors. */ > + if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { > + list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { > + struct drm_gem_object *obj = obj_priv->obj; > + > + if (batchbuffer[0] == NULL && > + bbaddr >= obj_priv->gtt_offset && > + bbaddr < obj_priv->gtt_offset + obj->size) > + batchbuffer[0] = obj; > + > + if (batchbuffer[1] == NULL && > + error->acthd >= obj_priv->gtt_offset && > + error->acthd < obj_priv->gtt_offset + obj->size) > + batchbuffer[1] = obj; > + > + if (batchbuffer[0] && batchbuffer[1]) > + break; > + } > + } > + if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { > + list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { > + struct drm_gem_object *obj = obj_priv->obj; > + > + if (batchbuffer[0] == NULL && > + bbaddr >= obj_priv->gtt_offset && > + bbaddr < obj_priv->gtt_offset + obj->size) > + batchbuffer[0] = obj; > + > + if (batchbuffer[1] == NULL && > + error->acthd >= obj_priv->gtt_offset && > + error->acthd < obj_priv->gtt_offset + obj->size) > + batchbuffer[1] = obj; > + > + if (batchbuffer[0] && batchbuffer[1]) > + break; > + } > + } > > /* We need to copy these to an anonymous buffer as the simplest > * method to avoid being overwritten by userpace. > */ > error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); > - error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); > + if (batchbuffer[1] != batchbuffer[0]) > + error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); > + else > + error->batchbuffer[1] = NULL; > > /* Record the ringbuffer */ > error->ringbuffer = i915_error_object_create(dev, dev_priv->ring.ring_obj); > -- > 1.7.1 > > ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-05-11 19:22 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <0100511104818.8382a7de.akpm@linux-foundation.org>
2010-05-11 18:22 ` [PATCH] drm/i915: Record error batch buffers using iomem Chris Wilson
2010-05-11 15:37 ` Andrew Morton
2010-05-11 18:49 ` Chris Wilson
2010-05-11 19:22 ` Jaswinder Singh Rajput
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox