[Intel-gfx] [PATCH 1/3] drm/i915: refactor i915_gem_object_pin_map()

Dave Gordon david.s.gordon at intel.com
Tue May 17 12:59:48 UTC 2016


On 17/05/16 10:22, Tvrtko Ursulin wrote:
>
> On 16/05/16 16:19, Dave Gordon wrote:
>> The recently-added i915_gem_object_pin_map() can be further optimised
>> for "small" objects. To facilitate this, and simplify the error paths
>> before adding the new code, this patch pulls out the "mapping" part of
>> the operation (involving local allocations which must be undone before
>> return) into its own subfunction.
>>
>> The next patch will then insert the new optimisation into the middle of
>> the now-separated subfunction.
>>
>> This reorganisation will probably not affect the generated code, as the
>> compiler will most likely inline it anyway, but it makes the logical
>> structure a bit clearer and easier to modify.
>>
>> v2:
>>      Restructure loop-over-pages & error check (Chris Wilson)
>>
>> v3:
>>      Add page count to debug messages (Chris Wilson)
>>      Convert WARN_ON() to GEM_BUG_ON()
>>
>> Signed-off-by: Dave Gordon <david.s.gordon at intel.com>
>> Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>> Cc: Chris Wilson <chris at chris-wilson.co.uk>
>> ---
>>   drivers/gpu/drm/i915/i915_gem.c | 59
>> ++++++++++++++++++++++++++---------------
>>   1 file changed, 38 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c
>> b/drivers/gpu/drm/i915/i915_gem.c
>> index aff386e..bbec429 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -2398,6 +2398,43 @@ static void
>> i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj)
>>       return 0;
>>   }
>>
>> +/* The 'mapping' part of i915_gem_object_pin_map() below */
>> +static void *i915_gem_object_map(const struct drm_i915_gem_object *obj)
>> +{
>> +    unsigned long n_pages = obj->base.size >> PAGE_SHIFT;
>> +    struct sg_table *sgt = obj->pages;
>> +    struct sg_page_iter sg_iter;
>> +    struct page **pages;
>> +    unsigned long i = 0;
>> +    void *addr = NULL;
>
> Looks like this does not need to be initialized?

OK. BTW the compiler didn't actually generate any code for this :)

>> +
>> +    /* A single page can always be kmapped */
>> +    if (n_pages == 1)
>> +        return kmap(sg_page(sgt->sgl));
>> +
>> +    pages = drm_malloc_gfp(n_pages, sizeof(*pages), GFP_TEMPORARY);
>> +    if (pages == NULL) {
>> +        DRM_DEBUG_DRIVER("Failed to get space for %lu pointers\n",
>> +                 n_pages);
>
> Not terribly important but I think this is too low level functions to
> have debug logging. It will not add a lot of useful information, no call
> stack etc. And the callers are probably handling failures already and
> they would propagate somewhere from where it is already reported.
>
>> +        return NULL;
>> +    }
>> +
>> +    for_each_sg_page(sgt->sgl, &sg_iter, sgt->nents, 0)
>> +        pages[i++] = sg_page_iter_page(&sg_iter);
>> +
>> +    /* Check that we have the expected number of pages */
>> +    GEM_BUG_ON(i != n_pages);
>> +
>> +    addr = vmap(pages, n_pages, 0, PAGE_KERNEL);
>> +    if (addr == NULL)
>> +        DRM_DEBUG_DRIVER("Failed to vmap %lu pages\n", n_pages);
>
> Same here. I mean, the only potential argument could be that this will
> tell the real reason which is otherwise lost in the NULL return code,
> but I am not sure it is worth it since it is so unlikely it would happen.

OK, debugging removed, new version posted.

.Dave.

>> +
>> +    drm_free_large(pages);
>> +
>> +    return addr;
>> +}
>> +
>> +/* get, pin, and map the pages of the object into kernel space */
>>   void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj)
>>   {
>>       int ret;
>> @@ -2411,27 +2448,7 @@ void *i915_gem_object_pin_map(struct
>> drm_i915_gem_object *obj)
>>       i915_gem_object_pin_pages(obj);
>>
>>       if (obj->mapping == NULL) {
>> -        struct page **pages;
>> -
>> -        pages = NULL;
>> -        if (obj->base.size == PAGE_SIZE)
>> -            obj->mapping = kmap(sg_page(obj->pages->sgl));
>> -        else
>> -            pages = drm_malloc_gfp(obj->base.size >> PAGE_SHIFT,
>> -                           sizeof(*pages),
>> -                           GFP_TEMPORARY);
>> -        if (pages != NULL) {
>> -            struct sg_page_iter sg_iter;
>> -            int n;
>> -
>> -            n = 0;
>> -            for_each_sg_page(obj->pages->sgl, &sg_iter,
>> -                     obj->pages->nents, 0)
>> -                pages[n++] = sg_page_iter_page(&sg_iter);
>> -
>> -            obj->mapping = vmap(pages, n, 0, PAGE_KERNEL);
>> -            drm_free_large(pages);
>> -        }
>> +        obj->mapping = i915_gem_object_map(obj);
>>           if (obj->mapping == NULL) {
>>               i915_gem_object_unpin_pages(obj);
>>               return ERR_PTR(-ENOMEM);
>>
>
> Otherwise looks fine to me.
>
> Regards,
> Tvrtko



More information about the Intel-gfx mailing list