Hello Chris and Andrew,

On Tue, May 11, 2010 at 11:52 PM, Chris Wilson <chris at 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 at 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
>
>

Reply via email to