[Intel-gfx] [PATCH] drm/i915: Trim the object sg table

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Wed Nov 9 15:07:38 UTC 2016


On 09/11/2016 14:44, Chris Wilson wrote:
> On Wed, Nov 09, 2016 at 02:30:02PM +0000, Tvrtko Ursulin wrote:
>> From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>>
>> At the moment we allocate enough sg table entries assuming we
>> will not be able to do any coallescing. But since in practice
>> we most often can, and more so very effectively, this ends up
>> wasting a lot of memory.
>>
>> A simple and effective way of trimming the over-allocated
>> entries is to copy the table over to a new one allocated to the
>> exact size.
>>
>> Experiment on my freshly logged and idle desktop (KDE) showed
> Experiments
>> that by doing this we can save approximately 1 MiB of RAM, or
>> when running a typical benchmark like gl_manhattan I have
>> even seen a 6 MiB saving.
>
> More complicated techniques such as only copying the last used page and
> freeing the rest are left to the reader.

Yes that would need to go into the core kernel since it needs access to 
static alloc/free functions and performance benefit might be quite small 
for that. Typically I see coalescing working really well so the delta in 
saved allocations and frees would be quite small. Perhaps I need to 
attempt to fragment my memory a lot to see what happens then.

>> v2:
>>  * Update commit message.
>>  * Use temporary sg_table on stack. (Chris Wilson)
>>
>> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>> Cc: Chris Wilson <chris at chris-wilson.co.uk>
>> ---
>>  drivers/gpu/drm/i915/i915_gem.c | 25 +++++++++++++++++++++++++
>>  1 file changed, 25 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
>> index d2ad73d0b5b9..411aae535abe 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -2232,6 +2232,28 @@ static unsigned int swiotlb_max_size(void)
>>  #endif
>>  }
>>
>> +static void i915_sg_trim(struct sg_table *orig_st)
>> +{
>> +	struct sg_table new_st;
>> +	struct scatterlist *sg, *new_sg;
>> +	unsigned int i;
>> +
>> +	if (orig_st->nents == orig_st->orig_nents)
>> +		return;
>> +
>> +	if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL))
>> +		return;
>> +
>> +	new_sg = new_st.sgl;
>> +	for_each_sg(orig_st->sgl, sg, orig_st->nents, i) {
>> +		sg_set_page(new_sg, sg_page(sg), sg->length, 0);
>> +		new_sg = sg_next(new_sg);
>
> Worth a
> 	/* called before being DMA mapped, no need to copy sg->dma_* */
> ?

Hm, or something safer than a comment. Unfortunately entries are not 
zeroed by default to enable a GEM_BUG_ON here. Unless CONFIG_GEM_DEBUG 
could mean GFP_ZERO added to some our allocations. :)

Yeah I think comment is the best option as long as this function is 
static only. Will add.

>
>> +	}
>> +
>> +	sg_free_table(orig_st);
>> +	memcpy(orig_st, &new_st, sizeof(*orig_st));
>
> I would have used *orig_st = new;

It is more readable, agreed.

>
> Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
>            ^ I remembered it this time!
> Took a couple of attempts to spell my name right though.

Thanks! I assume I can keep it for the above little changes.

Regards,

Tvrtko


More information about the Intel-gfx mailing list