summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/xe/xe_bb.c
diff options
context:
space:
mode:
authorSatyanarayana K V P <satyanarayana.k.v.p@intel.com>2026-02-20 05:55:22 +0000
committerMatthew Brost <matthew.brost@intel.com>2026-02-20 10:54:03 -0800
commitbcd768d787e7bb4e06d77709fa17d5bafec8612e (patch)
treea7bcbad841b03652d3980d39c745901749897bc0 /drivers/gpu/drm/xe/xe_bb.c
parent16843e6638b743dd0376a1fc0845f2fd34daff98 (diff)
downloadlinux-bcd768d787e7bb4e06d77709fa17d5bafec8612e.tar.gz
linux-bcd768d787e7bb4e06d77709fa17d5bafec8612e.zip
drm/xe/vf: Fix fs_reclaim warning with CCS save/restore BB allocation
CCS save/restore batch buffers are attached during BO allocation and detached during BO teardown. The shrinker triggers xe_bo_move(), which is used for both allocation and deletion paths. When BO allocation and shrinking occur concurrently, a circular locking dependency involving fs_reclaim and swap_guard can occur, leading to a deadlock such as: *===============================================================* * WARNING: possible circular locking dependency detected * *---------------------------------------------------------------* * * * CPU0 CPU1 * * ---- ---- * * lock(fs_reclaim); * * lock(&sa_manager->swap_guard); * * lock(fs_reclaim); * * lock(&sa_manager->swap_guard); * * * * *** DEADLOCK *** * *===============================================================* To avoid this, the BB pointer and SA are allocated using xe_bb_alloc() before taking lock and SA is initialized using xe_bb_init() preventing reclaim from being invoked in this context. Fixes: 864690cf4dd62 ("drm/xe/vf: Attach and detach CCS copy commands with BO") Signed-off-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Matthew Auld <matthew.auld@intel.com> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com> Cc: Maarten Lankhorst <dev@lankhorst.se> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Signed-off-by: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/20260220055519.2485681-7-satyanarayana.k.v.p@intel.com
Diffstat (limited to 'drivers/gpu/drm/xe/xe_bb.c')
-rw-r--r--drivers/gpu/drm/xe/xe_bb.c59
1 files changed, 43 insertions, 16 deletions
diff --git a/drivers/gpu/drm/xe/xe_bb.c b/drivers/gpu/drm/xe/xe_bb.c
index 8b678297aaa2..b0aceaec2685 100644
--- a/drivers/gpu/drm/xe/xe_bb.c
+++ b/drivers/gpu/drm/xe/xe_bb.c
@@ -59,16 +59,51 @@ err:
return ERR_PTR(err);
}
-struct xe_bb *xe_bb_ccs_new(struct xe_gt *gt, u32 dwords,
- enum xe_sriov_vf_ccs_rw_ctxs ctx_id)
+/**
+ * xe_bb_alloc() - Allocate a new batch buffer structure
+ * @gt: the &xe_gt
+ *
+ * Allocates and initializes a new xe_bb structure with an associated
+ * uninitialized suballoc object.
+ *
+ * Returns: Batch buffer structure or an ERR_PTR(-ENOMEM).
+ */
+struct xe_bb *xe_bb_alloc(struct xe_gt *gt)
{
struct xe_bb *bb = kmalloc(sizeof(*bb), GFP_KERNEL);
- struct xe_device *xe = gt_to_xe(gt);
- struct xe_sa_manager *bb_pool;
int err;
if (!bb)
return ERR_PTR(-ENOMEM);
+
+ bb->bo = xe_sa_bo_alloc(GFP_KERNEL);
+ if (IS_ERR(bb->bo)) {
+ err = PTR_ERR(bb->bo);
+ goto err;
+ }
+
+ return bb;
+
+err:
+ kfree(bb);
+ return ERR_PTR(err);
+}
+
+/**
+ * xe_bb_init() - Initialize a batch buffer with memory from a sub-allocator pool
+ * @bb: Batch buffer structure to initialize
+ * @bb_pool: Suballoc memory pool to allocate from
+ * @dwords: Number of dwords to be allocated
+ *
+ * Initializes the batch buffer by allocating memory from the specified
+ * suballoc pool.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int xe_bb_init(struct xe_bb *bb, struct xe_sa_manager *bb_pool, u32 dwords)
+{
+ int err;
+
/*
* We need to allocate space for the requested number of dwords &
* one additional MI_BATCH_BUFFER_END dword. Since the whole SA
@@ -76,22 +111,14 @@ struct xe_bb *xe_bb_ccs_new(struct xe_gt *gt, u32 dwords,
* is not over written when the last chunk of SA is allocated for BB.
* So, this extra DW acts as a guard here.
*/
-
- bb_pool = xe->sriov.vf.ccs.contexts[ctx_id].mem.ccs_bb_pool;
- bb->bo = xe_sa_bo_new(bb_pool, 4 * (dwords + 1));
-
- if (IS_ERR(bb->bo)) {
- err = PTR_ERR(bb->bo);
- goto err;
- }
+ err = xe_sa_bo_init(bb_pool, bb->bo, 4 * (dwords + 1));
+ if (err)
+ return err;
bb->cs = xe_sa_bo_cpu_addr(bb->bo);
bb->len = 0;
- return bb;
-err:
- kfree(bb);
- return ERR_PTR(err);
+ return 0;
}
static struct xe_sched_job *