From: Boris Brezillon <boris.brezillon@collabora.com>
To: "Christian König" <christian.koenig@amd.com>
Cc: arunpravin.paneerselvam@amd.com, felix.kuehling@amd.com,
francois.dugast@intel.com, amd-gfx@lists.freedesktop.org,
luben.tuikov@amd.com, dakr@redhat.com,
dri-devel@lists.freedesktop.org, thomas_os@shipmail.org
Subject: Re: [PATCH 01/13] drm: execution context for GEM buffers v4
Date: Wed, 14 Jun 2023 15:02:52 +0200 [thread overview]
Message-ID: <20230614150252.6ceb42fd@collabora.com> (raw)
In-Reply-To: <299e0ff6-bd0a-fa8d-acda-8b3ce22d6ab6@amd.com>
On Wed, 14 Jun 2023 14:30:53 +0200
Christian König <christian.koenig@amd.com> wrote:
> Am 14.06.23 um 14:23 schrieb Boris Brezillon:
> > Hi Christian,
> >
> > On Thu, 4 May 2023 13:51:47 +0200
> > "Christian König" <ckoenig.leichtzumerken@gmail.com> wrote:
> >
> >> This adds the infrastructure for an execution context for GEM buffers
> >> which is similar to the existing TTMs execbuf util and intended to replace
> >> it in the long term.
> >>
> >> The basic functionality is that we abstracts the necessary loop to lock
> >> many different GEM buffers with automated deadlock and duplicate handling.
> > As many other drivers do already, we are considering using drm_exec()
> > for our resv locking in the PowerVR driver, so we might have more
> > questions/comments in the coming days/weeks, but I already have a
> > couple right now (see below).
> >
> >> v3: drop duplicate tracking, radeon is really the only one needing that
> > I think we'd actually be interested in duplicate tracking. Is there any
> > way we can make it an optional feature through some extra helpers/flags?
> > Doesn't have to be done in this patch series, I'm just wondering if this
> > is something we can share as well.
>
> You can still capture the -EALREADY error and act appropriately in your
> driver.
>
> For radeon it just means ignoring the error code and going ahead, but
> that behavior doesn't seem to be desired in most cases.
>
> Initially I though we need to separately track how many and how often
> BOs are duplicated, but there is simply no use for this.
>
> >
> > [...]
> >
> >> +/**
> >> + * DOC: Overview
> >> + *
> >> + * This component mainly abstracts the retry loop necessary for locking
> >> + * multiple GEM objects while preparing hardware operations (e.g. command
> >> + * submissions, page table updates etc..).
> >> + *
> >> + * If a contention is detected while locking a GEM object the cleanup procedure
> >> + * unlocks all previously locked GEM objects and locks the contended one first
> >> + * before locking any further objects.
> >> + *
> >> + * After an object is locked fences slots can optionally be reserved on the
> >> + * dma_resv object inside the GEM object.
> >> + *
> >> + * A typical usage pattern should look like this::
> >> + *
> >> + * struct drm_gem_object *obj;
> >> + * struct drm_exec exec;
> >> + * unsigned long index;
> >> + * int ret;
> >> + *
> >> + * drm_exec_init(&exec, true);
> >> + * drm_exec_while_not_all_locked(&exec) {
> >> + * ret = drm_exec_prepare_obj(&exec, boA, 1);
> >> + * drm_exec_continue_on_contention(&exec);
> >> + * if (ret)
> >> + * goto error;
> >> + *
> > Have you considered defining a drm_exec_try_prepare_obj_or_retry()
> > combining drm_exec_prepare_obj() and drm_exec_continue_on_contention()?
> >
> > #define drm_exec_try_prepare_obj_or_retry(exec, obj, num_fences) \
> > ({ \
> > int __ret = drm_exec_prepare_obj(exec, bo, num_fences); \
> > if (unlikely(drm_exec_is_contended(exec))) \
> > continue; \
> > __ret; \
> > })
> >
> > This way the following pattern
> >
> > ret = drm_exec_prepare_obj(&exec, boA, 1);
> > drm_exec_continue_on_contention(&exec);
> > if (ret)
> > goto error;
> >
> > can be turned into something more conventional:
> >
> > ret = drm_exec_try_prepare_obj_or_retry(&exec, boA, 1);
> > if (ret)
> > goto error;
>
> Yeah, I was considering that as well. But then abandoned it as to
> complicated.
>
> I really need to find some time to work on that anyway.
>
> >
> > I guess we could even add static checks to make sure
> > drm_exec_try_prepare_obj() is called inside a
> > drm_exec_while_not_all_locked() loop.
>
> Interesting idea, but how would somebody do that?
There are probably better/cleaner ways, but the below diff
seems to catch cases where drm_exec_try_prepare_obj() is
called in a context where break/continue are allowed, but
that's not inside a drm_exec_while_not_all_locked() section.
What's missing though is a way to detect when it's called
from an inner loop.
---
diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
index 7c7481ed088a..1f4e0e1a7783 100644
--- a/include/drm/drm_exec.h
+++ b/include/drm/drm_exec.h
@@ -69,8 +69,10 @@ struct drm_exec {
*
* At the beginning of the loop it is guaranteed that no GEM object is locked.
*/
+#define __in_drm_exec_while_not_all_locked false
#define drm_exec_while_not_all_locked(exec) \
- while (drm_exec_cleanup(exec))
+ for (const bool __in_drm_exec_while_not_all_locked = true; \
+ drm_exec_cleanup(exec); )
/**
* drm_exec_continue_on_contention - continue the loop when we need to cleanup
@@ -83,6 +85,25 @@ struct drm_exec {
if (unlikely(drm_exec_is_contended(exec))) \
continue
+/**
+ * drm_exec_try_prepare_obj - Try prepare an object and retry on contention
+ * @exec: drm_exec object
+ * @obj: GEM object to prepare
+ * @num_fence: number of fence slots to reserve
+ *
+ * Wrapper around drm_exec_prepare_obj() that automatically retries on
+ * contention by going back to the head of the drm_exec_while_not_all_locked()
+ * loop.
+ */
+#define drm_exec_try_prepare_obj(exec, obj, num_fences) \
+ ({ \
+ int __ret = drm_exec_prepare_obj(exec, obj, num_fences); \
+ static_assert(__in_drm_exec_while_not_all_locked == true); \
+ if (unlikely(drm_exec_is_contended(exec))) \
+ continue; \
+ __ret; \
+ })
+
/**
* drm_exec_break_on_contention - break a subordinal loop on contention
* @exec: drm_exec object
next prev parent reply other threads:[~2023-06-14 13:03 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-04 11:51 Common DRM execution context v4 Christian König
2023-05-04 11:51 ` [PATCH 01/13] drm: execution context for GEM buffers v4 Christian König
2023-05-04 14:02 ` Thomas Hellström (Intel)
2023-05-25 20:42 ` Danilo Krummrich
2023-06-14 12:23 ` Boris Brezillon
2023-06-14 12:30 ` Christian König
2023-06-14 13:02 ` Boris Brezillon [this message]
2023-06-17 11:54 ` Boris Brezillon
2023-06-19 8:59 ` Thomas Hellström (Intel)
2023-06-19 9:20 ` Christian König
2023-06-19 9:33 ` Thomas Hellström (Intel)
2023-06-19 9:48 ` Christian König
2023-06-19 11:06 ` Thomas Hellström (Intel)
2023-06-21 13:35 ` Christian König
2023-06-19 10:23 ` Boris Brezillon
2023-06-19 10:12 ` Boris Brezillon
2023-06-19 10:44 ` Christian König
2023-06-19 11:05 ` Boris Brezillon
2023-06-19 12:01 ` Boris Brezillon
2023-06-19 12:29 ` Boris Brezillon
2023-06-20 6:47 ` Boris Brezillon
2023-06-20 7:28 ` Christian König
2023-05-04 11:51 ` [PATCH 02/13] drm: add drm_exec selftests v2 Christian König
2023-05-04 12:07 ` Maíra Canal
2023-05-04 12:52 ` Christian König
2023-05-04 11:51 ` [PATCH 03/13] drm/amdkfd: switch over to using drm_exec v2 Christian König
2023-05-04 11:51 ` [PATCH 04/13] drm/amdgpu: use drm_exec for GEM and CSA handling Christian König
2023-05-04 11:51 ` [PATCH 05/13] drm/amdgpu: use drm_exec for MES testing Christian König
2023-05-04 11:51 ` [PATCH 06/13] drm/amdgpu: use the new drm_exec object for CS v2 Christian König
2023-06-12 13:16 ` Tatsuyuki Ishi
2023-06-20 4:07 ` Tatsuyuki Ishi
2023-06-20 4:14 ` Tatsuyuki Ishi
2023-06-20 8:13 ` Christian König
2023-06-20 8:12 ` Christian König
2023-06-20 8:16 ` Tatsuyuki Ishi
2023-06-20 9:04 ` Tatsuyuki Ishi
2023-06-20 8:28 ` Boris Brezillon
2023-06-20 8:44 ` Christian König
2023-06-20 9:09 ` Boris Brezillon
2023-06-20 9:14 ` Christian König
2023-06-20 9:20 ` Boris Brezillon
2023-05-04 11:51 ` [PATCH 07/13] drm/radeon: switch over to drm_exec Christian König
2023-05-04 11:51 ` [PATCH 08/13] drm/qxl: switch to using drm_exec Christian König
2023-06-20 9:13 ` Thomas Zimmermann
2023-06-20 9:15 ` Christian König
2023-05-04 11:51 ` [PATCH 09/13] drm/lima: " Christian König
2023-05-04 11:51 ` [PATCH 10/13] drm/virtgpu: " Christian König
2023-05-04 11:51 ` [PATCH 11/13] drm/panfrost: " Christian König
2023-05-04 11:51 ` [PATCH 12/13] drm/v3d: " Christian König
2023-05-04 11:51 ` [PATCH 13/13] drm: remove drm_gem_(un)lock_reservations Christian König
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=20230614150252.6ceb42fd@collabora.com \
--to=boris.brezillon@collabora.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=arunpravin.paneerselvam@amd.com \
--cc=christian.koenig@amd.com \
--cc=dakr@redhat.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=felix.kuehling@amd.com \
--cc=francois.dugast@intel.com \
--cc=luben.tuikov@amd.com \
--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