* 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
* [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 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