Intel-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
To: "Thomas Hellström (Intel)" <thomas_os@shipmail.org>,
	intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 14/24] drm/i915: Rework intel_context pinning to do everything outside of pin_mutex
Date: Wed, 19 Aug 2020 12:38:01 +0200	[thread overview]
Message-ID: <0cd04319-150f-4338-7485-66271a6f3066@linux.intel.com> (raw)
In-Reply-To: <c33c3813-efd8-852d-091a-af425d1daa08@shipmail.org>

Op 12-08-2020 om 21:14 schreef Thomas Hellström (Intel):
>
> On 8/10/20 12:30 PM, Maarten Lankhorst wrote:
>> Instead of doing everything inside of pin_mutex, we move all pinning
>> outside. Because i915_active has its own reference counting and
>> pinning is also having the same issues vs mutexes, we make sure
>> everything is pinned first, so the pinning in i915_active only needs
>> to bump refcounts. This allows us to take pin refcounts correctly
>> all the time.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>   drivers/gpu/drm/i915/gt/intel_context.c       | 232 +++++++++++-------
>>   drivers/gpu/drm/i915/gt/intel_context_types.h |   4 +-
>>   drivers/gpu/drm/i915/gt/intel_lrc.c           |  34 ++-
>>   .../gpu/drm/i915/gt/intel_ring_submission.c   |  13 +-
>>   drivers/gpu/drm/i915/gt/mock_engine.c         |  13 +-
>>   5 files changed, 190 insertions(+), 106 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
>> index 52db2bde44a3..efe9a7a89ede 100644
>> --- a/drivers/gpu/drm/i915/gt/intel_context.c
>> +++ b/drivers/gpu/drm/i915/gt/intel_context.c
>> @@ -93,79 +93,6 @@ static void intel_context_active_release(struct intel_context *ce)
>>       i915_active_release(&ce->active);
>>   }
>>   -int __intel_context_do_pin(struct intel_context *ce)
>> -{
>> -    int err;
>> -
>> -    if (unlikely(!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) {
>> -        err = intel_context_alloc_state(ce);
>> -        if (err)
>> -            return err;
>> -    }
>> -
>> -    err = i915_active_acquire(&ce->active);
>> -    if (err)
>> -        return err;
>> -
>> -    if (mutex_lock_interruptible(&ce->pin_mutex)) {
>> -        err = -EINTR;
>> -        goto out_release;
>> -    }
>> -
>> -    if (unlikely(intel_context_is_closed(ce))) {
>> -        err = -ENOENT;
>> -        goto out_unlock;
>> -    }
>> -
>> -    if (likely(!atomic_add_unless(&ce->pin_count, 1, 0))) {
>> -        err = intel_context_active_acquire(ce);
>> -        if (unlikely(err))
>> -            goto out_unlock;
>> -
>> -        err = ce->ops->pin(ce);
>> -        if (unlikely(err))
>> -            goto err_active;
>> -
>> -        CE_TRACE(ce, "pin ring:{start:%08x, head:%04x, tail:%04x}\n",
>> -             i915_ggtt_offset(ce->ring->vma),
>> -             ce->ring->head, ce->ring->tail);
>> -
>> -        smp_mb__before_atomic(); /* flush pin before it is visible */
>> -        atomic_inc(&ce->pin_count);
>> -    }
>> -
>> -    GEM_BUG_ON(!intel_context_is_pinned(ce)); /* no overflow! */
>> -    GEM_BUG_ON(i915_active_is_idle(&ce->active));
>> -    goto out_unlock;
>> -
>> -err_active:
>> -    intel_context_active_release(ce);
>> -out_unlock:
>> -    mutex_unlock(&ce->pin_mutex);
>> -out_release:
>> -    i915_active_release(&ce->active);
>> -    return err;
>> -}
>> -
>> -void intel_context_unpin(struct intel_context *ce)
>> -{
>> -    if (!atomic_dec_and_test(&ce->pin_count))
>> -        return;
>> -
>> -    CE_TRACE(ce, "unpin\n");
>> -    ce->ops->unpin(ce);
>> -
>> -    /*
>> -     * Once released, we may asynchronously drop the active reference.
>> -     * As that may be the only reference keeping the context alive,
>> -     * take an extra now so that it is not freed before we finish
>> -     * dereferencing it.
>> -     */
>> -    intel_context_get(ce);
>> -    intel_context_active_release(ce);
>> -    intel_context_put(ce);
>> -}
>> -
>>   static int __context_pin_state(struct i915_vma *vma)
>>   {
>>       unsigned int bias = i915_ggtt_pin_bias(vma) | PIN_OFFSET_BIAS;
>> @@ -225,6 +152,138 @@ static void __ring_retire(struct intel_ring *ring)
>>       intel_ring_unpin(ring);
>>   }
>>   +static int intel_context_pre_pin(struct intel_context *ce)
>> +{
>> +    int err;
>> +
>> +    CE_TRACE(ce, "active\n");
>> +
>> +    err = __ring_active(ce->ring);
>> +    if (err)
>> +        return err;
>> +
>> +    err = intel_timeline_pin(ce->timeline);
>> +    if (err)
>> +        goto err_ring;
>> +
>> +    if (!ce->state)
>> +        return 0;
>> +
>> +    err = __context_pin_state(ce->state);
>> +    if (err)
>> +        goto err_timeline;
>> +
>> +
>> +    return 0;
>> +
>> +err_timeline:
>> +    intel_timeline_unpin(ce->timeline);
>> +err_ring:
>> +    __ring_retire(ce->ring);
>> +    return err;
>> +}
>> +
>> +static void intel_context_post_unpin(struct intel_context *ce)
>> +{
>> +    if (ce->state)
>> +        __context_unpin_state(ce->state);
>> +
>> +    intel_timeline_unpin(ce->timeline);
>> +    __ring_retire(ce->ring);
>> +}
>> +
>> +int __intel_context_do_pin(struct intel_context *ce)
>> +{
>> +    bool handoff = false;
>> +    void *vaddr;
>> +    int err = 0;
>> +
>> +    if (unlikely(!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) {
>> +        err = intel_context_alloc_state(ce);
>> +        if (err)
>> +            return err;
>> +    }
>> +
>> +    /*
>> +     * We always pin the context/ring/timeline here, to ensure a pin
>> +     * refcount for __intel_context_active(), which prevent a lock
>> +     * inversion of ce->pin_mutex vs dma_resv_lock().
>> +     */
>> +    err = intel_context_pre_pin(ce);
>> +    if (err)
>> +        return err;
>> +
>> +    err = i915_active_acquire(&ce->active);
>> +    if (err)
>> +        goto err_ctx_unpin;
>> +
>> +    err = ce->ops->pre_pin(ce, &vaddr);
>> +    if (err)
>> +        goto err_release;
>> +
>> +    err = mutex_lock_interruptible(&ce->pin_mutex);
>> +    if (err)
>> +        goto err_post_unpin;
>> +
>> +    if (unlikely(intel_context_is_closed(ce))) {
>> +        err = -ENOENT;
>> +        goto err_unlock;
>> +    }
>> +
>> +    if (likely(!atomic_add_unless(&ce->pin_count, 1, 0))) {
>> +        err = intel_context_active_acquire(ce);
>> +        if (unlikely(err))
>> +            goto err_unlock;
>> +
>> +        err = ce->ops->pin(ce, vaddr);
>> +        if (err) {
>> +            intel_context_active_release(ce);
>> +            goto err_unlock;
>> +        }
>> +
>> +        CE_TRACE(ce, "pin ring:{start:%08x, head:%04x, tail:%04x}\n",
>> +             i915_ggtt_offset(ce->ring->vma),
>> +             ce->ring->head, ce->ring->tail);
>> +
>> +        handoff = true;
>> +        smp_mb__before_atomic(); /* flush pin before it is visible */
>> +        atomic_inc(&ce->pin_count);
>> +    }
>> +
>> +    GEM_BUG_ON(!intel_context_is_pinned(ce)); /* no overflow! */
>> +
>> +err_unlock:
>> +    mutex_unlock(&ce->pin_mutex);
>> +err_post_unpin:
>> +    if (!handoff)
>> +        ce->ops->post_unpin(ce);
>> +err_release:
>> +    i915_active_release(&ce->active);
>> +err_ctx_unpin:
>> +    intel_context_post_unpin(ce);
>> +    return err;
>> +}
>> +
>> +void intel_context_unpin(struct intel_context *ce)
>> +{
>> +    if (!atomic_dec_and_test(&ce->pin_count))
>> +        return;
>> +
>> +    CE_TRACE(ce, "unpin\n");
>> +    ce->ops->unpin(ce);
>> +    ce->ops->post_unpin(ce);
>
> What's protecting ops->unpin() here, running concurrently with ops->pin in __intel_context_do_pin()? Do the ops functions have to implement their own locking if needed?
>
> Otherwise LGTM
>
> Reviewed-by: Thomas Hellström <thomas.hellstrom@intel.com>
>
post_unpin can be run concurrently, unpin() for intel_lrc.c is check_redzone(), empty for legacy rings, should be fine. :)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2020-08-19 10:38 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-10 10:30 [Intel-gfx] [PATCH 00/24] drm/i915: Correct the locking hierarchy in gem Maarten Lankhorst
2020-08-10 10:30 ` [Intel-gfx] [PATCH 01/24] Revert "drm/i915/gem: Async GPU relocations only" Maarten Lankhorst
2020-08-11  9:33   ` Daniel Vetter
2020-08-11 12:11   ` Daniel Vetter
2020-08-12  7:56   ` Chris Wilson
2020-08-10 10:30 ` [Intel-gfx] [PATCH 02/24] drm/i915: Revert relocation chaining commits Maarten Lankhorst
2020-08-11 12:41   ` Daniel Vetter
2020-08-10 10:30 ` [Intel-gfx] [PATCH 03/24] Revert "drm/i915/gem: Drop relocation slowpath" Maarten Lankhorst
2020-08-11 13:39   ` Daniel Vetter
2020-08-10 10:30 ` [Intel-gfx] [PATCH 04/24] Revert "drm/i915/gem: Split eb_vma into its own allocation" Maarten Lankhorst
2020-08-11 15:12   ` Daniel Vetter
2020-08-12 21:29   ` Thomas Hellström (Intel)
2020-08-10 10:30 ` [Intel-gfx] [PATCH 05/24] drm/i915: Add an implementation for i915_gem_ww_ctx locking, v2 Maarten Lankhorst
2020-08-10 10:30 ` [Intel-gfx] [PATCH 06/24] drm/i915: Remove locking from i915_gem_object_prepare_read/write Maarten Lankhorst
2020-08-10 17:41   ` Thomas Hellström (Intel)
2020-08-10 10:30 ` [Intel-gfx] [PATCH 07/24] drm/i915: Parse command buffer earlier in eb_relocate(slow) Maarten Lankhorst
2020-08-10 17:44   ` Thomas Hellström (Intel)
2020-08-10 10:30 ` [Intel-gfx] [PATCH 08/24] drm/i915: Use per object locking in execbuf, v12 Maarten Lankhorst
2020-08-12 20:59   ` Thomas Hellström (Intel)
2020-08-10 10:30 ` [Intel-gfx] [PATCH 09/24] drm/i915: make lockdep slightly happier about execbuf Maarten Lankhorst
2020-08-10 12:58   ` Maarten Lankhorst
2020-08-10 14:18   ` [Intel-gfx] [PATCH 1/1] dummy empty commit Maarten Lankhorst
2020-08-10 14:58   ` Maarten Lankhorst
2020-08-11  7:34   ` [Intel-gfx] [PATCH 09/24] drm/i915: make lockdep slightly happier about execbuf Thomas Hellström (Intel)
2020-08-11 11:56     ` Maarten Lankhorst
2020-08-10 10:30 ` [Intel-gfx] [PATCH 10/24] drm/i915: Use ww locking in intel_renderstate Maarten Lankhorst
2020-08-11  7:52   ` Thomas Hellström (Intel)
2020-08-10 10:30 ` [Intel-gfx] [PATCH 11/24] drm/i915: Add ww context handling to context_barrier_task Maarten Lankhorst
2020-08-11  8:09   ` Thomas Hellström (Intel)
2020-08-10 10:30 ` [Intel-gfx] [PATCH 12/24] drm/i915: Nuke arguments to eb_pin_engine Maarten Lankhorst
2020-08-11  8:12   ` Thomas Hellström (Intel)
2020-08-10 10:30 ` [Intel-gfx] [PATCH 13/24] drm/i915: Pin engine before pinning all objects, v5 Maarten Lankhorst
2020-08-12 19:01   ` Thomas Hellström (Intel)
2020-08-10 10:30 ` [Intel-gfx] [PATCH 14/24] drm/i915: Rework intel_context pinning to do everything outside of pin_mutex Maarten Lankhorst
2020-08-12 19:14   ` Thomas Hellström (Intel)
2020-08-19 10:38     ` Maarten Lankhorst [this message]
2020-08-10 10:30 ` [Intel-gfx] [PATCH 15/24] drm/i915: Make sure execbuffer always passes ww state to i915_vma_pin Maarten Lankhorst
2020-08-12 19:32   ` Thomas Hellström (Intel)
2020-08-12 20:28     ` Thomas Hellström (Intel)
2020-08-19 11:54     ` Maarten Lankhorst
2020-08-10 10:30 ` [Intel-gfx] [PATCH 16/24] drm/i915: Convert i915_gem_object/client_blt.c to use ww locking as well, v2 Maarten Lankhorst
2020-08-12 19:39   ` Thomas Hellström (Intel)
2020-08-10 10:30 ` [Intel-gfx] [PATCH 17/24] drm/i915: Kill last user of intel_context_create_request outside of selftests Maarten Lankhorst
2020-08-12 19:41   ` Thomas Hellström (Intel)
2020-08-10 10:30 ` [Intel-gfx] [PATCH 18/24] drm/i915: Convert i915_perf to ww locking as well Maarten Lankhorst
2020-08-12 19:53   ` Thomas Hellström (Intel)
2020-08-19 11:57     ` Maarten Lankhorst
2020-08-10 10:30 ` [Intel-gfx] [PATCH 19/24] drm/i915: Dirty hack to fix selftests locking inversion Maarten Lankhorst
2020-08-12 19:58   ` Thomas Hellström (Intel)
2020-08-10 10:30 ` [Intel-gfx] [PATCH 20/24] drm/i915/selftests: Fix locking inversion in lrc selftest Maarten Lankhorst
2020-08-12 19:59   ` Thomas Hellström (Intel)
2020-08-10 10:31 ` [Intel-gfx] [PATCH 21/24] drm/i915: Use ww pinning for intel_context_create_request() Maarten Lankhorst
2020-08-12 20:02   ` Thomas Hellström (Intel)
2020-08-10 10:31 ` [Intel-gfx] [PATCH 22/24] drm/i915: Move i915_vma_lock in the selftests to avoid lock inversion, v3 Maarten Lankhorst
2020-08-12 20:09   ` Thomas Hellström (Intel)
2020-08-10 10:31 ` [Intel-gfx] [PATCH 23/24] drm/i915: Add ww locking to vm_fault_gtt Maarten Lankhorst
2020-08-12 20:16   ` Thomas Hellström (Intel)
2020-08-10 10:31 ` [Intel-gfx] [PATCH 24/24] drm/i915: Add ww locking to pin_to_display_plane Maarten Lankhorst
2020-08-12 20:31   ` Thomas Hellström (Intel)
2020-08-10 10:48 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Correct the locking hierarchy in gem Patchwork
2020-08-10 10:49 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-08-10 11:03 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2020-08-11  8:10 ` [Intel-gfx] [PATCH 00/24] " Chris Wilson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0cd04319-150f-4338-7485-66271a6f3066@linux.intel.com \
    --to=maarten.lankhorst@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=thomas_os@shipmail.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox