From: Boris Brezillon <boris.brezillon@collabora.com>
To: "Christian König" <ckoenig.leichtzumerken@gmail.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 14:23:39 +0200 [thread overview]
Message-ID: <20230614142339.04df5111@collabora.com> (raw)
In-Reply-To: <20230504115159.2245-2-christian.koenig@amd.com>
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.
[...]
> +/**
> + * 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;
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.
> + * ret = drm_exec_prepare_obj(&exec, boB, 1);
> + * drm_exec_continue_on_contention(&exec);
> + * if (ret)
> + * goto error;
> + * }
> + *
> + * drm_exec_for_each_locked_object(&exec, index, obj) {
> + * dma_resv_add_fence(obj->resv, fence, DMA_RESV_USAGE_READ);
> + * ...
> + * }
> + * drm_exec_fini(&exec);
> + *
> + * See struct dma_exec for more details.
> + */
[...]
> +/**
> + * drm_exec_prepare_array - helper to prepare an array of objects
> + * @exec: the drm_exec object with the state
> + * @objects: array of GEM object to prepare
> + * @num_objects: number of GEM objects in the array
> + * @num_fences: number of fences to reserve on each GEM object
> + *
> + * Prepares all GEM objects in an array, handles contention but aports on first
> + * error otherwise. Reserves @num_fences on each GEM object after locking it.
> + *
> + * Returns: -EALREADY when object is already locked, -ENOMEM when memory
> + * allocation failed and zero for success.
> + */
> +int drm_exec_prepare_array(struct drm_exec *exec,
> + struct drm_gem_object **objects,
> + unsigned int num_objects,
> + unsigned int num_fences)
> +{
> + int ret;
> +
> + drm_exec_while_not_all_locked(exec) {
> + for (unsigned int i = 0; i < num_objects; ++i) {
> + ret = drm_exec_prepare_obj(exec, objects[i],
> + num_fences);
> + drm_exec_break_on_contention(exec);
I had a hard time understanding what the intent was here: we do want the
locking to keep going on contention (reset and retry), but we need to
break out of the inner loop for this to happen, which is what this
drm_exec_break_on_contention() is doing. My misunderstanding was coming
from the fact I was expecting drm_exec_break_on_contention() to stop
the process of preparing objects. Maybe it's just me, but I think it'd
be less confusing if we were getting rid of
drm_exec_{break,continue}_on_contention and have the loop slightly
adjusted:
unsigned int obj_ptr = 0;
drm_exec_while_not_all_locked(exec) {
int ret;
/* We acquired/prepared all objects, we can leave the loop now. */
if (obj_ptr == num_objects)
break;
ret = drm_exec_try_prepare_obj_or_retry(exec, objects[obj_ptr++],
num_fences);
if (ret)
return ret;
}
return 0;
Of course, this is just my personal view on this, and none of these
comments should be considered as blockers, but I thought I'd share
my concerns anyway.
Thanks again for your work!
Regards,
Boris
next prev parent reply other threads:[~2023-06-14 12:24 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 [this message]
2023-06-14 12:30 ` Christian König
2023-06-14 13:02 ` Boris Brezillon
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=20230614142339.04df5111@collabora.com \
--to=boris.brezillon@collabora.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=arunpravin.paneerselvam@amd.com \
--cc=ckoenig.leichtzumerken@gmail.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