Re: [PATCH v3 22/33] drm/xe: Add Kconfig.profile options for BO defrag configuration
From: Niranjana Vishwanathapura
Date: Sun Nov 08 2026 - 20:31:34 EST
On Fri, Jul 10, 2026 at 07:56:08PM -0700, Matthew Brost wrote:
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_SIZE_LIMIT: Maximum number of bytes 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
Assisted-by: LLM
NIT...Would runtime knobs be useful than these compile time knobs?
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_SIZE_LIMIT is
set less than 2M by returning early from xe_bo_defrag_update() (and
xe_bo_defrag_remove()) so BOs are never added to the defrag list or the
worker kicked; xe_bo_defrag_add() and xe_bo_defrag_schedule() assert the
limit is at least 2M.
Cc: Carlos Santa <carlos.santa@xxxxxxxxx>
Cc: Ryan Neph <ryanneph@xxxxxxxxxx>
Cc: Christian Koenig <christian.koenig@xxxxxxx>
Cc: Huang Rui <ray.huang@xxxxxxx>
Cc: Matthew Auld <matthew.auld@xxxxxxxxx>
Cc: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx>
Cc: Maxime Ripard <mripard@xxxxxxxxxx>
Cc: Thomas Zimmermann <tzimmermann@xxxxxxx>
Cc: David Airlie <airlied@xxxxxxxxx>
Cc: Simona Vetter <simona@xxxxxxxx>
Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx
Cc: linux-kernel@xxxxxxxxxxxxxxx
Cc: Thomas Hellström <thomas.hellstrom@xxxxxxxxxxxxxxx>
Assisted-by: GitHub_Copilot:claude-haiku-4.5
Signed-off-by: Matthew Brost <matthew.brost@xxxxxxxxx>
---
drivers/gpu/drm/xe/Kconfig.profile | 40 ++++++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_bo.c | 26 +++++++++++++++++++
2 files changed, 66 insertions(+)
diff --git a/drivers/gpu/drm/xe/Kconfig.profile b/drivers/gpu/drm/xe/Kconfig.profile
index e07517d120e0..e0aade41f53e 100644
--- a/drivers/gpu/drm/xe/Kconfig.profile
+++ b/drivers/gpu/drm/xe/Kconfig.profile
@@ -74,3 +74,43 @@ 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
+ range 1 1000
Is the value of 1 intended here? As mentioned in patch 16, this will
reinforce the self backoff loop.
NIT...Also the max value of the range here and below seems too higher
than the default value. Not sure if that is intended.
+ 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_SIZE_LIMIT
+ int "Maximum bytes to defrag per work run"
+ default 33554432
+ range 0 1073741824
+ help
+ Maximum number of bytes the defrag worker will process in a single run
+ before yielding and rescheduling itself. Set to less than large page
+ size (2M) 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.
+
The disable mechanism is confusing (0 to 2MB). May be add a separate runtime
knob for enable/disable and change the range here to start from 2MB?
+config DRM_XE_BO_DEFRAG_INTERVAL_MS
+ int "Default delay before defrag worker run (ms)"
+ default 25
+ range 1 1000
+ 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
+ range 100 1000000
The range here overlaps with that of DRM_XE_BO_DEFRAG_INTERVAL_MS and it
accepts value lower than that of DRM_XE_BO_DEFRAG_INTERVAL_MS.
+ 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 073d926ef9ac..0bdd1c920404 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
Looks like The 'ifdef's are redundent here as the config params without any
dependency take the default value and hence will always turn out to be true.
/*
* Maximum number of bytes of newly (re)allocated backing the defrag worker will
@@ -65,17 +69,31 @@
* Only pages a move truly reallocates are charged; pages harvested from the old
* backing are free, so an object larger than the budget is upgraded in
* budget-sized slices across runs.
+ *
+ * Set to 0 to disable defrag completely.
*/
+#ifdef CONFIG_DRM_XE_BO_DEFRAG_SIZE_LIMIT
+#define XE_BO_DEFRAG_SIZE_LIMIT CONFIG_DRM_XE_BO_DEFRAG_SIZE_LIMIT
+#else
#define XE_BO_DEFRAG_SIZE_LIMIT SZ_32M
+#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 25
+#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);
@@ -1126,6 +1144,7 @@ int xe_bo_defrag_init(struct xe_device *xe)
static void xe_bo_defrag_schedule(struct xe_device *xe)
{
+ xe_assert(xe, XE_BO_DEFRAG_SIZE_LIMIT >= SZ_2M);
schedule_delayed_work(&xe->mem.defrag.worker,
msecs_to_jiffies(xe->mem.defrag.interval_ms));
}
@@ -1152,6 +1171,7 @@ static void xe_bo_defrag_add(struct xe_bo *bo)
xe_bo_assert_held(bo);
xe_assert(xe, xe_bo_needs_defrag(bo));
+ xe_assert(xe, XE_BO_DEFRAG_SIZE_LIMIT >= SZ_2M);
xe_bo_defrag_init_early and xe_bo_defrag_init still runs if defrag is
disabled which can be avoided.
Niranjana
scoped_guard(spinlock, &xe->mem.defrag.lock) {
if (list_empty(&bo->defrag_link)) {
@@ -1185,6 +1205,9 @@ static void xe_bo_defrag_remove(struct xe_bo *bo)
{
xe_bo_assert_held(bo);
+ if (XE_BO_DEFRAG_SIZE_LIMIT < SZ_2M)
+ return;
+
if (list_empty(&bo->defrag_link))
return;
@@ -1204,6 +1227,9 @@ static void xe_bo_defrag_update(struct xe_bo *bo)
{
xe_bo_assert_held(bo);
+ if (XE_BO_DEFRAG_SIZE_LIMIT < SZ_2M)
+ return;
+
if (xe_bo_needs_defrag(bo))
xe_bo_defrag_add(bo);
else
--
2.34.1