diff options
| author | Satyanarayana K V P <satyanarayana.k.v.p@intel.com> | 2026-02-20 05:55:22 +0000 |
|---|---|---|
| committer | Matthew Brost <matthew.brost@intel.com> | 2026-02-20 10:54:03 -0800 |
| commit | bcd768d787e7bb4e06d77709fa17d5bafec8612e (patch) | |
| tree | a7bcbad841b03652d3980d39c745901749897bc0 /drivers/gpu/drm/xe/xe_bb.c | |
| parent | 16843e6638b743dd0376a1fc0845f2fd34daff98 (diff) | |
| download | linux-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.c | 59 |
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 * |
