On 5/20/26 12:16, Thomas Hellström wrote: > The xe driver was using the drm_exec retry pointer directly to > restart the locking loop after out-of-memory errors. This is > relying on undocumented behaviour. > > Instead add a drm_exec_retry() macro that can be used in this > situation, and that also warns if the struct drm_exec is > not newly (re-)initialized. > > Use that macro in xe. > > v2: > - Only allow if the drm_exec context is newly initialized. > (Christian) > > Signed-off-by: Thomas Hellström <[email protected]>
BTW I've ran into just another complex use case were we need the retry handling with userqueues. So I'm probably going to use that macro in amdgpu as well but with quite a bit of extended functionality *sigh*. Anyway patch is good like it is for now, so Reviewed-by: Christian König <[email protected]>. Thanks, Christian. > --- > drivers/gpu/drm/drm_exec.c | 3 --- > drivers/gpu/drm/xe/xe_validation.h | 2 +- > include/drm/drm_exec.h | 19 +++++++++++++++++++ > 3 files changed, 20 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c > index 746210f3f6c2..7988f5e7d56a 100644 > --- a/drivers/gpu/drm/drm_exec.c > +++ b/drivers/gpu/drm/drm_exec.c > @@ -48,9 +48,6 @@ > * See struct dma_exec for more details. > */ > > -/* Dummy value used to initially enter the retry loop */ > -#define DRM_EXEC_DUMMY ((void *)~0) > - > /* Unlock all objects and drop references */ > static void drm_exec_unlock_all(struct drm_exec *exec) > { > diff --git a/drivers/gpu/drm/xe/xe_validation.h > b/drivers/gpu/drm/xe/xe_validation.h > index a30e732c4d51..4cd955ce6cd2 100644 > --- a/drivers/gpu/drm/xe/xe_validation.h > +++ b/drivers/gpu/drm/xe/xe_validation.h > @@ -146,7 +146,7 @@ bool xe_validation_should_retry(struct xe_validation_ctx > *ctx, int *ret); > #define xe_validation_retry_on_oom(_ctx, _ret) > \ > do { \ > if (xe_validation_should_retry(_ctx, _ret)) \ > - goto *__drm_exec_retry_ptr; \ > + drm_exec_retry((_ctx)->exec); \ > } while (0) > > /** > diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h > index 18f84faabbb9..99c7e1bb3c5b 100644 > --- a/include/drm/drm_exec.h > +++ b/include/drm/drm_exec.h > @@ -9,6 +9,12 @@ > #define DRM_EXEC_INTERRUPTIBLE_WAIT BIT(0) > #define DRM_EXEC_IGNORE_DUPLICATES BIT(1) > > +/* > + * Dummy value used to initially enter the retry loop. > + * internal use only. > + */ > +#define DRM_EXEC_DUMMY ((void *)~0) > + > struct drm_gem_object; > > /** > @@ -142,6 +148,19 @@ static inline bool drm_exec_is_contended(struct drm_exec > *exec) > return !!exec->contended; > } > > +/** > + * drm_exec_retry() - Unconditionally restart the loop to grab all locks. > + * @exec: drm_exec object > + * > + * Unconditionally retry the loop to lock all objects. For consistency, > + * the exec object needs to be newly initialized. > + */ > +#define drm_exec_retry(_exec) \ > + do { \ > + WARN_ON((_exec)->contended != DRM_EXEC_DUMMY); \ > + goto *__drm_exec_retry_ptr; \ > + } while (0) > + > void drm_exec_init(struct drm_exec *exec, u32 flags, unsigned nr); > void drm_exec_fini(struct drm_exec *exec); > bool drm_exec_cleanup(struct drm_exec *exec);
