drm/exec, drm/xe: Avoid abusing the drm_exec retry pointer

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 <thomas.hellstrom@linux.intel.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Link: https://patch.msgid.link/20260520101616.41284-4-thomas.hellstrom@linux.intel.com
This commit is contained in:
Thomas Hellström 2026-05-20 12:16:15 +02:00
parent 25331d9d40
commit bba175a2d4
3 changed files with 20 additions and 4 deletions

View File

@ -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)
{

View File

@ -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)
/**

View File

@ -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);