[Intel-gfx] [PATCH] drm/i915/gt: Carefully order virtual_submission_tasklet
Tvrtko Ursulin
tvrtko.ursulin at linux.intel.com
Thu Apr 23 15:01:01 UTC 2020
On 23/04/2020 12:53, Chris Wilson wrote:
> During the virtual engine's submission tasklet, we take the request and
> insert into the submission queue on each of our siblings. This seems
> quite simply, and so no problems with ordering. However, the sibling
> execlists' submission tasklets may run concurrently with the virtual
> engine's tasklet, submitting the request to HW before the virtual
> finishes its task of telling all the siblings. If this happens, the
> sibling tasklet may *reorder* the ve->sibling[] array that the virtual
> engine tasklet is processing. This can *only* reorder within the
> elements already processed by the virtual engine, nevertheless the
> race is detected by KCSAN:
>
> [ 185.580014] BUG: KCSAN: data-race in execlists_dequeue [i915] / virtual_submission_tasklet [i915]
> [ 185.580054]
> [ 185.580076] write to 0xffff8881f1919860 of 8 bytes by interrupt on cpu 2:
> [ 185.580553] execlists_dequeue+0x6ad/0x1600 [i915]
> [ 185.581044] __execlists_submission_tasklet+0x48/0x60 [i915]
> [ 185.581517] execlists_submission_tasklet+0xd3/0x170 [i915]
> [ 185.581554] tasklet_action_common.isra.0+0x42/0x90
> [ 185.581585] __do_softirq+0xc8/0x206
> [ 185.581613] run_ksoftirqd+0x15/0x20
> [ 185.581641] smpboot_thread_fn+0x15a/0x270
> [ 185.581669] kthread+0x19a/0x1e0
> [ 185.581695] ret_from_fork+0x1f/0x30
> [ 185.581717]
> [ 185.581736] read to 0xffff8881f1919860 of 8 bytes by interrupt on cpu 0:
> [ 185.582231] virtual_submission_tasklet+0x10e/0x5c0 [i915]
> [ 185.582265] tasklet_action_common.isra.0+0x42/0x90
> [ 185.582291] __do_softirq+0xc8/0x206
> [ 185.582315] run_ksoftirqd+0x15/0x20
> [ 185.582340] smpboot_thread_fn+0x15a/0x270
> [ 185.582368] kthread+0x19a/0x1e0
> [ 185.582395] ret_from_fork+0x1f/0x30
> [ 185.582417]
>
> We can prevent this race by checking for the ve->request after looking
> up the sibling array.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> ---
> drivers/gpu/drm/i915/gt/intel_lrc.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
> index fba774a0abbf..dead24aaf45d 100644
> --- a/drivers/gpu/drm/i915/gt/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
> @@ -5092,12 +5092,15 @@ static void virtual_submission_tasklet(unsigned long data)
> return;
>
> local_irq_disable();
> - for (n = 0; READ_ONCE(ve->request) && n < ve->num_siblings; n++) {
> - struct intel_engine_cs *sibling = ve->siblings[n];
> + for (n = 0; n < ve->num_siblings; n++) {
> + struct intel_engine_cs *sibling = READ_ONCE(ve->siblings[n]);
> struct ve_node * const node = &ve->nodes[sibling->id];
> struct rb_node **parent, *rb;
> bool first;
>
> + if (!READ_ONCE(ve->request))
> + break; /* already handled by a sibling's tasklet */
> +
> if (unlikely(!(mask & sibling->mask))) {
> if (!RB_EMPTY_NODE(&node->rb)) {
> spin_lock(&sibling->active.lock);
>
Useful debugging aid!
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Regards,
Tvrtko
More information about the Intel-gfx
mailing list