[PATCH] drm/i915: Record error batch buffers using iomem

Jaswinder Singh Rajput jaswinderlinux at gmail.com
Tue May 11 12:38:23 PDT 2010


Hello Chris and Andrew,

I did further testing and noticed that this patch fixes the boot
errors and warnings and I get the XWindows.

But XWindows freezes after some time.

Thanks,
--
Jaswinder Singh.

On Wed, May 12, 2010 at 12:52 AM, Jaswinder Singh Rajput
<jaswinderlinux at gmail.com> wrote:
> 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
>>
>>
>


More information about the dri-devel mailing list