[Intel-gfx] [PATCH v3 02/21] drm/i915: introduce intel_memory_region

Matthew Auld matthew.auld at intel.com
Tue Oct 8 11:57:50 UTC 2019


On 08/10/2019 09:59, Chris Wilson wrote:
> Quoting Matthew Auld (2019-10-04 18:04:33)
>> +int
>> +i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
>> +{
>> +       struct intel_memory_region *mem = obj->mm.region;
>> +       struct list_head *blocks = &obj->mm.blocks;
>> +       unsigned int flags = I915_ALLOC_MIN_PAGE_SIZE;
>> +       resource_size_t size = obj->base.size;
>> +       resource_size_t prev_end;
>> +       struct i915_buddy_block *block;
>> +       struct sg_table *st;
>> +       struct scatterlist *sg;
>> +       unsigned int sg_page_sizes;
>> +       unsigned long i;
>> +       int ret;
>> +
>> +       st = kmalloc(sizeof(*st), GFP_KERNEL);
>> +       if (!st)
>> +               return -ENOMEM;
>> +
>> +       if (sg_alloc_table(st, size >> ilog2(mem->mm.chunk_size), GFP_KERNEL)) {
>> +               kfree(st);
>> +               return -ENOMEM;
>> +       }
>> +
>> +       ret = __intel_memory_region_get_pages_buddy(mem, size, flags, blocks);
>> +       if (ret)
>> +               goto err_free_sg;
>> +
>> +       GEM_BUG_ON(list_empty(blocks));
>> +
>> +       sg = st->sgl;
>> +       st->nents = 0;
>> +       sg_page_sizes = 0;
>> +       i = 0;
>> +
>> +       list_for_each_entry(block, blocks, link) {
>> +               u64 block_size, offset;
>> +
>> +               block_size = i915_buddy_block_size(&mem->mm, block);
>> +               offset = i915_buddy_block_offset(block);
>> +
>> +               GEM_BUG_ON(overflows_type(block_size, sg->length));
>> +
>> +               if (!i || offset != prev_end ||
>> +                   add_overflows_t(typeof(sg->length), sg->length, block_size)) {
>> +                       if (i) {
> 
> i is only being here to detect the start.
> prev_end = (resource_size_t)-1;
> Then I don't have to worry about i overflowing, although that seems
> harmless, and as ridiculous as that may be.
> 
>> +                               sg_page_sizes |= sg->length;
>> +                               sg = __sg_next(sg);
>> +                       }
>> +
>> +                       sg_dma_address(sg) = mem->region.start + offset;
>> +                       sg_dma_len(sg) = block_size;
>> +
>> +                       sg->length = block_size;
>> +
>> +                       st->nents++;
>> +               } else {
>> +                       sg->length += block_size;
>> +                       sg_dma_len(sg) += block_size;
>> +               }
>> +
>> +               prev_end = offset + block_size;
>> +               i++;
>> +       };
>> +
>> +       sg_page_sizes |= sg->length;
>> +       sg_mark_end(sg);
>> +       i915_sg_trim(st);
>> +
>> +       __i915_gem_object_set_pages(obj, st, sg_page_sizes);
>> +
>> +       return 0;
>> +
>> +err_free_sg:
>> +       sg_free_table(st);
>> +       kfree(st);
>> +       return ret;
>> +}
> 
>> +struct drm_i915_gem_object *
>> +i915_gem_object_create_region(struct intel_memory_region *mem,
>> +                             resource_size_t size,
>> +                             unsigned int flags)
>> +{
>> +       struct drm_i915_gem_object *obj;
>> +
>> +       if (!mem)
>> +               return ERR_PTR(-ENODEV);
>> +
>> +       size = round_up(size, mem->min_page_size);
>> +
>> +       GEM_BUG_ON(!size);
>> +       GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_MIN_ALIGNMENT));
>> +
> 
> Put the FIXME here from the start
> 
>> +       if (size >> PAGE_SHIFT > INT_MAX)
>> +               return ERR_PTR(-E2BIG);
>> +
>> +       if (overflows_type(size, obj->base.size))
>> +               return ERR_PTR(-E2BIG);
>> +
>> +       return mem->ops->create_object(mem, size, flags);
>> +}
> 
> I'm happy with this. But I would like a discussion on why
> resource_size_t was chosen and for that rationale to be captured in the
> code comments. At the end of the day, we need to bump obj->base.size to
> suit.

No good reason, I guess it just stems from using "struct resource 
region". Maybe for the object_create interface we should just use u64?

On that topic should we also stop using "struct resource" here, since 
that's starting to get confusing, maybe use u64 there also?

> -Chris
> 


More information about the Intel-gfx mailing list