Hello Chris and Andrew, On Tue, May 11, 2010 at 11:52 PM, Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxxxxx> 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 > > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel