[Intel-gfx] [RFC] drm/i915: store all mmio bases in intel_engines

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Fri Mar 9 09:53:37 UTC 2018


On 08/03/2018 18:46, Daniele Ceraolo Spurio wrote:
> On 08/03/18 01:31, Tvrtko Ursulin wrote:
>>
>> On 07/03/2018 19:45, Daniele Ceraolo Spurio wrote:
>>> The mmio bases we're currently storing in the intel_engines array are
>>> only valid for a subset of gens, so we need to ignore them and use
>>> different values in some cases. Instead of doing that, we can have a
>>> table of [starting gen, mmio base] pairs for each engine in
>>> intel_engines and select the correct one based on the gen we're running
>>> on in a consistent way.
>>>
>>> Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
>>> Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
>>> ---
>>>   drivers/gpu/drm/i915/intel_engine_cs.c  | 77 
>>> +++++++++++++++++++++------------
>>>   drivers/gpu/drm/i915/intel_ringbuffer.c |  1 -
>>>   2 files changed, 49 insertions(+), 29 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
>>> b/drivers/gpu/drm/i915/intel_engine_cs.c
>>> index 4ba139c27fba..1dd92cac8d67 100644
>>> --- a/drivers/gpu/drm/i915/intel_engine_cs.c
>>> +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
>>> @@ -81,12 +81,16 @@ static const struct engine_class_info 
>>> intel_engine_classes[] = {
>>>       },
>>>   };
>>> +#define MAX_MMIO_BASES 3
>>>   struct engine_info {
>>>       unsigned int hw_id;
>>>       unsigned int uabi_id;
>>>       u8 class;
>>>       u8 instance;
>>> -    u32 mmio_base;
>>> +    struct engine_mmio_base {
>>> +        u32 gen : 8;
>>> +        u32 base : 24;
>>> +    } mmio_bases[MAX_MMIO_BASES];
>>>       unsigned irq_shift;
>>>   };
>>
>> It's not bad, but I am just wondering if it is too complicated versus 
>> simply duplicating the tables.
>>
>> Duplicated tables would certainly be much less code and complexity, 
>> but what about the size of pure data?
>>
>> In this patch sizeof(struct engine_info) grows by MAX_MMIO_BASES * 
>> sizeof(u32), so 12, to the total of 30 if I am not mistaken. Times 
>> NUM_ENGINES equals 240 bytes for intel_engines[] array with this scheme.
>>
> 
> we remove a u32 (the old mmio base) so we only grow 8 per engine, but 
> the compiler rounds up to a multiple of u32 so 28 per engine, for a 
> total of 224.
> 
>> Separate tables per gens would be:
>>
>> sizeof(struct engine_info) is 18 bytes.
>>
>> For < gen6 we'd need 3 engines * 18 = 54
>> < gen11 = 5 engines * 18 = 90
>>  >= gen11 = 8 engines * 18 = 144
>>
>> 54 + 90 + 144 = 288 bytes
>>
>> So a little bit bigger. Hm. Plus we would need to refactor so 
>> intel_engines[] is not indexed by engine->id but is contiguous array 
>> with engine->id in the elements. Code to lookup the compact array 
>> should be simpler than combined new code from this patch, especially 
>> if you add the test as Chris suggested. So separate engine info arrays 
>> would win I think overall - when considering size of text + size of 
>> data + size of source code.
>>
> 
> Not sure. I would exclude the selftest, which is usually not compiled 
> for released kernels, which leads to:

Yes, but we cannot exclude its source since selftests for separate 
tables wouldn't be needed.

> add/remove: 0/0 grow/shrink: 3/1 up/down: 100/-7 (93)
> Function                                     old     new   delta
> intel_engines                                160     224     +64
> __func__                                   13891   13910     +19
> intel_engines_init_mmio                     1247    1264     +17
> intel_init_bsd_ring_buffer                   142     135      -7
> Total: Before=1479626, After=1479719, chg +0.01%
> 
> Total growth is 93, which is less then your estimation for the growth 
> introduced by replicating the table.
> 
>> But on the other hand your solution might be more future proof. So I 
>> don't know. Use the crystal ball to decide? :)
>>
> 
> I think we should expect that the total engine count could grow with 
> future gens. In this case to me adding a new entry to a unified table 
> seems much cleaner (and uses less data) than adding a completely new 
> table each time.

Okay I was off in my estimates. But in general I was coming from the 
angle of thinking that every new mmio base difference in this scheme 
grows the size for all engines. So if just VCS grows one new base, 
impact is multiplied by NUM_ENGINES. But maybe separate tables are also 
not a solution. Perhaps pulling out mmio_base arrays to outside struct 
engine_info in another set of static tables, so they could be null 
terminated would be best of both worlds?

struct engine_mmio_base {
	u32 gen : 8;
	u32 base : 24;
};

static const struct engine_mmio_base vcs0_mmio_bases[] = {
	{ .gen = 11, .base = GEN11_BSD_RING_BASE },
	{ .gen = 6, .base = GEN6_BSD_RING_BASE },
	{ .gen = 4, .base = BSD_RING_BASE },
	{ },
};

And then in intel_engines array, for BSD:

    {
	...
	.mmio_bases = &vcs0_mmio_bases;
	...
    },

This way we limit data growth only to engines which change their mmio 
bases frequently.

Just an idea.

Regards,

Tvrtko


More information about the Intel-gfx mailing list