Add Kconfig.profile options to make XE_BO_DEFRAG_* defines configurable: - DRM_XE_BO_DEFRAG_RECLAIM_BACKOFF_THRESHOLD: Threshold for TTM reclaim backoff - DRM_XE_BO_DEFRAG_NUM_BO_LIMIT_PER_WORK: Maximum BOs to defrag per work run - DRM_XE_BO_DEFRAG_INTERVAL_MS: Default delay before defrag worker runs - DRM_XE_BO_DEFRAG_INTERVAL_MAX_MS: Upper bound for defrag worker interval
Update xe_bo.c to use these Kconfig options as defaults via #ifdef guards, maintaining backward compatibility with hardcoded values when not configured. Additionally, disable defrag completely when XE_BO_DEFRAG_NUM_BO_LIMIT_PER_WORK is set to 0 by returning early from xe_bo_defrag_add() without adding to the defrag list or kicking the worker. Cc: Carlos Santa <[email protected]> Cc: Ryan Neph <[email protected]> Cc: Christian Koenig <[email protected]> Cc: Huang Rui <[email protected]> Cc: Matthew Auld <[email protected]> Cc: Maarten Lankhorst <[email protected]> Cc: Maxime Ripard <[email protected]> Cc: Thomas Zimmermann <[email protected]> Cc: David Airlie <[email protected]> Cc: Simona Vetter <[email protected]> Cc: [email protected] Cc: [email protected] Cc: Thomas Hellström <[email protected]> Assisted-by: GitHub_Copilot:claude-haiku-4.5 Signed-off-by: Matthew Brost <[email protected]> --- drivers/gpu/drm/xe/Kconfig.profile | 35 ++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_bo.c | 22 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/drivers/gpu/drm/xe/Kconfig.profile b/drivers/gpu/drm/xe/Kconfig.profile index e07517d120e0..4de501b3af64 100644 --- a/drivers/gpu/drm/xe/Kconfig.profile +++ b/drivers/gpu/drm/xe/Kconfig.profile @@ -74,3 +74,38 @@ config DRM_XE_ENABLE_SCHEDTIMEOUT_LIMIT to apply to applicable user. For elevated user, all above MIN and MAX values will apply when this configuration is enable to apply limitation. By default limitation is applied. + +config DRM_XE_BO_DEFRAG_RECLAIM_BACKOFF_THRESHOLD + int "BO defrag reclaim backoff threshold" + default 2 + help + Once this many BOs are tracked on the device defrag list (i.e. were + backed with a sub-optimal page order), request that the TTM pool backs + off from aggressive reclaim at the beneficial order during populate, + so that allocations make forward progress instead of stalling. + +config DRM_XE_BO_DEFRAG_NUM_BO_LIMIT_PER_WORK + int "Maximum BOs to defrag per work run" + default 2 + help + Maximum number of BOs the defrag worker will process in a single run + before yielding and rescheduling itself. Set to 0 to disable defrag. + A defrag move synchronously reallocates and re-copies a BO's backing + store, which is not free. If a large number of BOs become eligible at + once, processing them all in one worker run would hold things up for a + long, unbounded stretch. Instead, cap the work done per run and requeue, + spreading the defrag effort out over time. + +config DRM_XE_BO_DEFRAG_INTERVAL_MS + int "Default delay before defrag worker run (ms)" + default 50 + help + Default delay before (re)running the defrag worker, in milliseconds. + +config DRM_XE_BO_DEFRAG_INTERVAL_MAX_MS + int "Upper bound for defrag worker interval (ms)" + default 15000 + help + Upper bound for the (exponentially backed off) defrag worker interval, + in milliseconds, so repeated failures don't push the retry arbitrarily + far out. 15000 ms = 15 seconds. diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index f74fd6f5504a..b8935850f399 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -49,7 +49,11 @@ * aggressive reclaim at the beneficial order during populate, so that * allocations make forward progress instead of stalling. */ +#ifdef CONFIG_DRM_XE_BO_DEFRAG_RECLAIM_BACKOFF_THRESHOLD +#define XE_BO_DEFRAG_RECLAIM_BACKOFF_THRESHOLD CONFIG_DRM_XE_BO_DEFRAG_RECLAIM_BACKOFF_THRESHOLD +#else #define XE_BO_DEFRAG_RECLAIM_BACKOFF_THRESHOLD 2 +#endif /* * Maximum number of BOs the defrag worker will process in a single run before @@ -62,17 +66,31 @@ * concurrent active work (e.g. a large FPS drop). Instead, cap the work done * per run and requeue, spreading the defrag effort out over time so it stays * in the background and yields to userspace progress. + * + * Set to 0 to disable defrag completely. */ +#ifdef CONFIG_DRM_XE_BO_DEFRAG_NUM_BO_LIMIT_PER_WORK +#define XE_BO_DEFRAG_NUM_BO_LIMIT_PER_WORK CONFIG_DRM_XE_BO_DEFRAG_NUM_BO_LIMIT_PER_WORK +#else #define XE_BO_DEFRAG_NUM_BO_LIMIT_PER_WORK 2 +#endif /* Default delay before (re)running the defrag worker, in milliseconds. */ +#ifdef CONFIG_DRM_XE_BO_DEFRAG_INTERVAL_MS +#define XE_BO_DEFRAG_INTERVAL_MS CONFIG_DRM_XE_BO_DEFRAG_INTERVAL_MS +#else #define XE_BO_DEFRAG_INTERVAL_MS 50 +#endif /* * Upper bound for the (exponentially backed off) defrag worker interval, in * milliseconds, so repeated failures don't push the retry arbitrarily far out. */ +#ifdef CONFIG_DRM_XE_BO_DEFRAG_INTERVAL_MAX_MS +#define XE_BO_DEFRAG_INTERVAL_MAX_MS CONFIG_DRM_XE_BO_DEFRAG_INTERVAL_MAX_MS +#else #define XE_BO_DEFRAG_INTERVAL_MAX_MS 15000 /* 15 seconds */ +#endif static void xe_bo_defrag_worker(struct work_struct *w); static void xe_place_from_ttm_type(u32 mem_type, struct ttm_place *place); @@ -1036,6 +1054,10 @@ static void xe_bo_defrag_add(struct xe_bo *bo) struct xe_device *xe = xe_bo_device(bo); bool kick = false; + /* Defrag disabled when limit is 0 */ + if (!XE_BO_DEFRAG_NUM_BO_LIMIT_PER_WORK) + return; + scoped_guard(spinlock, &xe->mem.defrag.lock) { if (list_empty(&bo->defrag_link)) { /* Kick the worker when the list transitions to non-empty. */ -- 2.34.1
