Skip to content

Commit e442677

Browse files
committed
Merge tag 'drm-xe-fixes-2026-07-17' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-fixes
Driver Changes: - Fix BO prefetch with CONSULT_MEM_ADVISE_PREF_LOCK (Himal) - Hold a dma-buf reference for imported BOs (Nitin) - Fix writable override for CRI (Alexander) - Fix VF CCS attach/detach race with in-flight BO moves (Matthew Brost) - Fix WOPCM size for LNL+ (Daniele) - Reset current_op in xe_pt_update_ops_init (Zongyao Bai) - Keep scheduler timeline name alive (Arvind) - Hold device ref until queue teardown completes (Arvind) - Disable display in admin only PF mode (Satyanarayana) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Hellstrom <thomas.hellstrom@linux.intel.com> Link: https://patch.msgid.link/aln1tRUXZJ_qzD65@fedora
2 parents 4f7b10f + 130910b commit e442677

20 files changed

Lines changed: 223 additions & 69 deletions

drivers/gpu/drm/xe/xe_bo.c

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,21 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
11021102
xe_pm_runtime_get_noresume(xe);
11031103
}
11041104

1105+
/*
1106+
* Attach CCS BBs before submitting the copy job below so a VF
1107+
* migration racing the copy sees valid, up to date attach state.
1108+
*/
1109+
if (IS_VF_CCS_READY(xe) &&
1110+
((move_lacks_source && new_mem->mem_type == XE_PL_TT) ||
1111+
(old_mem_type == XE_PL_SYSTEM && new_mem->mem_type == XE_PL_TT)) &&
1112+
handle_system_ccs) {
1113+
ret = xe_sriov_vf_ccs_attach_bo(bo, new_mem);
1114+
if (ret) {
1115+
xe_pm_runtime_put(xe);
1116+
goto out;
1117+
}
1118+
}
1119+
11051120
if (move_lacks_source) {
11061121
u32 flags = 0;
11071122

@@ -1139,22 +1154,19 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
11391154
ttm_bo_move_null(ttm_bo, new_mem);
11401155
}
11411156

1142-
dma_fence_put(fence);
1143-
xe_pm_runtime_put(xe);
1144-
11451157
/*
1146-
* CCS meta data is migrated from TT -> SMEM. So, let us detach the
1147-
* BBs from BO as it is no longer needed.
1158+
* Detach must wait for the copy above to complete: a VF migration
1159+
* racing an in-flight copy must still see valid CCS BBs, so don't
1160+
* tear them down until the copy fence has signaled.
11481161
*/
11491162
if (IS_VF_CCS_READY(xe) && old_mem_type == XE_PL_TT &&
1150-
new_mem->mem_type == XE_PL_SYSTEM)
1163+
new_mem->mem_type == XE_PL_SYSTEM) {
1164+
dma_fence_wait(fence, false);
11511165
xe_sriov_vf_ccs_detach_bo(bo);
1166+
}
11521167

1153-
if (IS_VF_CCS_READY(xe) &&
1154-
((move_lacks_source && new_mem->mem_type == XE_PL_TT) ||
1155-
(old_mem_type == XE_PL_SYSTEM && new_mem->mem_type == XE_PL_TT)) &&
1156-
handle_system_ccs)
1157-
ret = xe_sriov_vf_ccs_attach_bo(bo);
1168+
dma_fence_put(fence);
1169+
xe_pm_runtime_put(xe);
11581170

11591171
out:
11601172
if ((!ttm_bo->resource || ttm_bo->resource->mem_type == XE_PL_SYSTEM) &&
@@ -1349,7 +1361,7 @@ int xe_bo_notifier_prepare_pinned(struct xe_bo *bo)
13491361
backup = xe_bo_init_locked(xe, NULL, NULL, bo->ttm.base.resv, NULL, xe_bo_size(bo),
13501362
DRM_XE_GEM_CPU_CACHING_WB, ttm_bo_type_kernel,
13511363
XE_BO_FLAG_SYSTEM | XE_BO_FLAG_NEEDS_CPU_ACCESS |
1352-
XE_BO_FLAG_PINNED, &exec);
1364+
XE_BO_FLAG_PINNED, NULL, &exec);
13531365
if (IS_ERR(backup)) {
13541366
drm_exec_retry_on_contention(&exec);
13551367
ret = PTR_ERR(backup);
@@ -1490,7 +1502,7 @@ int xe_bo_evict_pinned(struct xe_bo *bo)
14901502
xe_bo_size(bo),
14911503
DRM_XE_GEM_CPU_CACHING_WB, ttm_bo_type_kernel,
14921504
XE_BO_FLAG_SYSTEM | XE_BO_FLAG_NEEDS_CPU_ACCESS |
1493-
XE_BO_FLAG_PINNED, &exec);
1505+
XE_BO_FLAG_PINNED, NULL, &exec);
14941506
if (IS_ERR(backup)) {
14951507
drm_exec_retry_on_contention(&exec);
14961508
ret = PTR_ERR(backup);
@@ -1826,6 +1838,8 @@ static void xe_ttm_bo_destroy(struct ttm_buffer_object *ttm_bo)
18261838

18271839
if (bo->ttm.base.import_attach)
18281840
drm_prime_gem_destroy(&bo->ttm.base, NULL);
1841+
if (bo->dma_buf)
1842+
dma_buf_put(bo->dma_buf);
18291843
drm_gem_object_release(&bo->ttm.base);
18301844

18311845
xe_assert(xe, list_empty(&ttm_bo->base.gpuva.list));
@@ -2283,6 +2297,8 @@ void xe_bo_free(struct xe_bo *bo)
22832297
* @cpu_caching: The cpu caching used for system memory backing store.
22842298
* @type: The TTM buffer object type.
22852299
* @flags: XE_BO_FLAG_ flags.
2300+
* @dma_buf: The dma-buf to reference for the BO lifetime (imported BOs),
2301+
* or NULL.
22862302
* @exec: The drm_exec transaction to use for exhaustive eviction.
22872303
*
22882304
* Initialize or create an xe buffer object. On failure, any allocated buffer
@@ -2294,7 +2310,8 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
22942310
struct xe_tile *tile, struct dma_resv *resv,
22952311
struct ttm_lru_bulk_move *bulk, size_t size,
22962312
u16 cpu_caching, enum ttm_bo_type type,
2297-
u32 flags, struct drm_exec *exec)
2313+
u32 flags, struct dma_buf *dma_buf,
2314+
struct drm_exec *exec)
22982315
{
22992316
struct ttm_operation_ctx ctx = {
23002317
.interruptible = true,
@@ -2383,6 +2400,17 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
23832400
placement = (type == ttm_bo_type_sg ||
23842401
bo->flags & XE_BO_FLAG_DEFER_BACKING) ? &sys_placement :
23852402
&bo->placement;
2403+
2404+
/*
2405+
* For imported BOs, keep the exporter dma-buf alive for the BO
2406+
* lifetime. Taken before ttm_bo_init_reserved() to also cover a
2407+
* creation failure there. Released in xe_ttm_bo_destroy().
2408+
*/
2409+
if (dma_buf) {
2410+
get_dma_buf(dma_buf);
2411+
bo->dma_buf = dma_buf;
2412+
}
2413+
23862414
err = ttm_bo_init_reserved(&xe->ttm, &bo->ttm, type,
23872415
placement, alignment,
23882416
&ctx, NULL, resv, xe_ttm_bo_destroy);
@@ -2500,7 +2528,7 @@ __xe_bo_create_locked(struct xe_device *xe,
25002528
vm && !xe_vm_in_fault_mode(vm) &&
25012529
flags & XE_BO_FLAG_USER ?
25022530
&vm->lru_bulk_move : NULL, size,
2503-
cpu_caching, type, flags, exec);
2531+
cpu_caching, type, flags, NULL, exec);
25042532
if (IS_ERR(bo))
25052533
return bo;
25062534

drivers/gpu/drm/xe/xe_bo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ struct xe_bo *xe_bo_init_locked(struct xe_device *xe, struct xe_bo *bo,
118118
struct xe_tile *tile, struct dma_resv *resv,
119119
struct ttm_lru_bulk_move *bulk, size_t size,
120120
u16 cpu_caching, enum ttm_bo_type type,
121-
u32 flags, struct drm_exec *exec);
121+
u32 flags, struct dma_buf *dma_buf,
122+
struct drm_exec *exec);
122123
struct xe_bo *xe_bo_create_locked(struct xe_device *xe, struct xe_tile *tile,
123124
struct xe_vm *vm, size_t size,
124125
enum ttm_bo_type type, u32 flags,

drivers/gpu/drm/xe/xe_bo_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ struct xe_bo {
3636
struct xe_bo *backup_obj;
3737
/** @parent_obj: Ref to parent bo if this a backup_obj */
3838
struct xe_bo *parent_obj;
39+
/** @dma_buf: Imported dma-buf ref to keep its resv alive. */
40+
struct dma_buf *dma_buf;
3941
/** @flags: flags for this buffer object */
4042
u32 flags;
4143
/** @vm: VM this BO is attached to, for extobj this will be NULL */

drivers/gpu/drm/xe/xe_device.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,6 @@ static const struct drm_ioctl_desc xe_ioctls_admin_only[] = {
426426

427427
static const struct drm_driver admin_only_driver = {
428428
.driver_features =
429-
XE_DISPLAY_DRIVER_FEATURES |
430429
DRIVER_GEM | DRIVER_RENDER | DRIVER_GEM_GPUVA,
431430
.open = xe_file_open,
432431
.postclose = xe_file_close,
@@ -438,7 +437,6 @@ static const struct drm_driver admin_only_driver = {
438437
.major = DRIVER_MAJOR,
439438
.minor = DRIVER_MINOR,
440439
.patchlevel = DRIVER_PATCHLEVEL,
441-
XE_DISPLAY_DRIVER_OPS,
442440
};
443441

444442
/**
@@ -580,7 +578,7 @@ int xe_device_init_early(struct xe_device *xe)
580578
WQ_MEM_RECLAIM);
581579
xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0);
582580
xe->unordered_wq = alloc_workqueue("xe-unordered-wq", WQ_PERCPU, 0);
583-
xe->destroy_wq = alloc_workqueue("xe-destroy-wq", WQ_PERCPU, 0);
581+
xe->destroy_wq = alloc_workqueue("xe-destroy-wq", WQ_PERCPU | WQ_MEM_RECLAIM, 0);
584582
if (!xe->ordered_wq || !xe->unordered_wq ||
585583
!xe->preempt_fence_wq || !xe->destroy_wq) {
586584
/*

drivers/gpu/drm/xe/xe_device_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ struct xe_device {
355355
/** @unordered_wq: used to serialize unordered work */
356356
struct workqueue_struct *unordered_wq;
357357

358-
/** @destroy_wq: used to serialize user destroy work, like queue */
358+
/** @destroy_wq: used to serialize SVM pagemap destroy work */
359359
struct workqueue_struct *destroy_wq;
360360

361361
/** @tiles: device tiles */

drivers/gpu/drm/xe/xe_dma_buf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ xe_dma_buf_create_obj(struct drm_device *dev, struct dma_buf *dma_buf)
302302

303303
bo = xe_bo_init_locked(xe, NULL, NULL, resv, NULL, dma_buf->size,
304304
0, /* Will require 1way or 2way for vm_bind */
305-
ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, &exec);
305+
ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, dma_buf, &exec);
306306
drm_exec_retry_on_contention(&exec);
307307
if (IS_ERR(bo)) {
308308
ret = PTR_ERR(bo);

drivers/gpu/drm/xe/xe_guc_exec_queue_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/workqueue.h>
1111

1212
#include "xe_gpu_scheduler_types.h"
13+
#include "xe_hw_fence_types.h"
1314

1415
struct dma_fence;
1516
struct xe_exec_queue;
@@ -24,6 +25,10 @@ struct xe_guc_exec_queue {
2425
struct rcu_head rcu;
2526
/** @sched: GPU scheduler for this xe_exec_queue */
2627
struct xe_gpu_scheduler sched;
28+
/**
29+
* @name: Scheduler timeline name, kept with @sched until RCU free.
30+
*/
31+
char name[MAX_FENCE_NAME_LEN];
2732
/** @entity: Scheduler entity for this xe_exec_queue */
2833
struct xe_sched_entity entity;
2934
/**

drivers/gpu/drm/xe/xe_guc_submit.c

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/circ_buf.h>
1111
#include <linux/dma-fence-array.h>
1212

13+
#include <drm/drm_drv.h>
1314
#include <drm/drm_managed.h>
1415

1516
#include "abi/guc_actions_abi.h"
@@ -37,6 +38,7 @@
3738
#include "xe_macros.h"
3839
#include "xe_map.h"
3940
#include "xe_mocs.h"
41+
#include "xe_module.h"
4042
#include "xe_pm.h"
4143
#include "xe_ring_ops_types.h"
4244
#include "xe_sched_job.h"
@@ -232,17 +234,9 @@ static bool exec_queue_killed_or_banned_or_wedged(struct xe_exec_queue *q)
232234
static void guc_submit_sw_fini(struct drm_device *drm, void *arg)
233235
{
234236
struct xe_guc *guc = arg;
235-
struct xe_device *xe = guc_to_xe(guc);
236237
struct xe_gt *gt = guc_to_gt(guc);
237-
int ret;
238-
239-
ret = wait_event_timeout(guc->submission_state.fini_wq,
240-
xa_empty(&guc->submission_state.exec_queue_lookup),
241-
HZ * 5);
242238

243-
drain_workqueue(xe->destroy_wq);
244-
245-
xe_gt_assert(gt, ret);
239+
xe_gt_assert(gt, xa_empty(&guc->submission_state.exec_queue_lookup));
246240

247241
xa_destroy(&guc->submission_state.exec_queue_lookup);
248242
}
@@ -319,8 +313,6 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids)
319313

320314
xa_init(&guc->submission_state.exec_queue_lookup);
321315

322-
init_waitqueue_head(&guc->submission_state.fini_wq);
323-
324316
primelockdep(guc);
325317

326318
guc->submission_state.initialized = true;
@@ -411,9 +403,6 @@ static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q,
411403
xe_guc_id_mgr_release_locked(&guc->submission_state.idm,
412404
q->guc->id, q->width);
413405

414-
if (xa_empty(&guc->submission_state.exec_queue_lookup))
415-
wake_up(&guc->submission_state.fini_wq);
416-
417406
mutex_unlock(&guc->submission_state.lock);
418407
}
419408

@@ -1685,6 +1674,7 @@ static void guc_exec_queue_fini(struct xe_exec_queue *q)
16851674
{
16861675
struct xe_guc_exec_queue *ge = q->guc;
16871676
struct xe_guc *guc = exec_queue_to_guc(q);
1677+
struct drm_device *drm = &guc_to_xe(guc)->drm;
16881678

16891679
if (xe_exec_queue_is_multi_queue_secondary(q)) {
16901680
struct xe_exec_queue_group *group = q->multi_queue.group;
@@ -1703,36 +1693,52 @@ static void guc_exec_queue_fini(struct xe_exec_queue *q)
17031693
* (timeline name).
17041694
*/
17051695
kfree_rcu(ge, rcu);
1696+
1697+
drm_dev_put(drm);
17061698
}
17071699

1708-
static void __guc_exec_queue_destroy_async(struct work_struct *w)
1700+
static void guc_exec_queue_do_destroy(struct xe_exec_queue *q)
17091701
{
1710-
struct xe_guc_exec_queue *ge =
1711-
container_of(w, struct xe_guc_exec_queue, destroy_async);
1712-
struct xe_exec_queue *q = ge->q;
1702+
struct xe_guc_exec_queue *ge = q->guc;
17131703
struct xe_guc *guc = exec_queue_to_guc(q);
1704+
struct xe_device *xe = guc_to_xe(guc);
1705+
struct drm_device *drm = &xe->drm;
1706+
1707+
/*
1708+
* guc_exec_queue_fini() drops the queue's drm_device ref.
1709+
* Keep the device alive until the PM-runtime guard unwinds.
1710+
*/
1711+
drm_dev_get(drm);
1712+
1713+
scoped_guard(xe_pm_runtime, xe) {
1714+
trace_xe_exec_queue_destroy(q);
17141715

1715-
guard(xe_pm_runtime)(guc_to_xe(guc));
1716-
trace_xe_exec_queue_destroy(q);
1716+
/* Confirm no work left behind accessing device structures */
1717+
cancel_delayed_work_sync(&ge->sched.base.work_tdr);
17171718

1718-
/* Confirm no work left behind accessing device structures */
1719-
cancel_delayed_work_sync(&ge->sched.base.work_tdr);
1719+
xe_exec_queue_fini(q);
1720+
}
17201721

1721-
xe_exec_queue_fini(q);
1722+
drm_dev_put(drm);
17221723
}
17231724

1724-
static void guc_exec_queue_destroy_async(struct xe_exec_queue *q)
1725+
static void __guc_exec_queue_destroy_async(struct work_struct *w)
17251726
{
1726-
struct xe_guc *guc = exec_queue_to_guc(q);
1727-
struct xe_device *xe = guc_to_xe(guc);
1727+
struct xe_guc_exec_queue *ge =
1728+
container_of(w, struct xe_guc_exec_queue, destroy_async);
1729+
1730+
guc_exec_queue_do_destroy(ge->q);
1731+
}
17281732

1733+
static void guc_exec_queue_destroy_async(struct xe_exec_queue *q)
1734+
{
17291735
INIT_WORK(&q->guc->destroy_async, __guc_exec_queue_destroy_async);
17301736

17311737
/* We must block on kernel engines so slabs are empty on driver unload */
17321738
if (q->flags & EXEC_QUEUE_FLAG_PERMANENT || exec_queue_wedged(q))
1733-
__guc_exec_queue_destroy_async(&q->guc->destroy_async);
1739+
guc_exec_queue_do_destroy(q);
17341740
else
1735-
queue_work(xe->destroy_wq, &q->guc->destroy_async);
1741+
xe_destroy_wq_queue(&q->guc->destroy_async);
17361742
}
17371743

17381744
static void __guc_exec_queue_destroy(struct xe_guc *guc, struct xe_exec_queue *q)
@@ -1927,6 +1933,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
19271933
{
19281934
struct xe_gpu_scheduler *sched;
19291935
struct xe_guc *guc = exec_queue_to_guc(q);
1936+
struct drm_device *drm = &guc_to_xe(guc)->drm;
19301937
struct workqueue_struct *submit_wq = NULL;
19311938
struct xe_guc_exec_queue *ge;
19321939
long timeout;
@@ -1938,6 +1945,8 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
19381945
if (!ge)
19391946
return -ENOMEM;
19401947

1948+
drm_dev_get(drm);
1949+
19411950
q->guc = ge;
19421951
ge->q = q;
19431952
init_rcu_head(&ge->rcu);
@@ -1955,6 +1964,8 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
19551964

19561965
xe_exec_queue_assign_name(q, q->guc->id);
19571966

1967+
strscpy(ge->name, q->name, sizeof(ge->name));
1968+
19581969
/*
19591970
* Use primary queue's submit_wq for all secondary queues of a
19601971
* multi queue group. This serialization avoids any locking around
@@ -1969,7 +1980,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
19691980
err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops,
19701981
submit_wq, xe_lrc_ring_size() / MAX_JOB_SIZE_BYTES, 64,
19711982
timeout, guc_to_gt(guc)->ordered_wq, NULL,
1972-
q->name, gt_to_xe(q->gt)->drm.dev);
1983+
ge->name, gt_to_xe(q->gt)->drm.dev);
19731984
if (err)
19741985
goto err_release_id;
19751986

@@ -2014,6 +2025,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
20142025
release_guc_id(guc, q);
20152026
err_free:
20162027
kfree(ge);
2028+
drm_dev_put(drm);
20172029

20182030
return err;
20192031
}

drivers/gpu/drm/xe/xe_guc_types.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ struct xe_guc {
100100
* even initialized - before that not even the lock is valid
101101
*/
102102
bool initialized;
103-
/** @submission_state.fini_wq: submit fini wait queue */
104-
wait_queue_head_t fini_wq;
105103
} submission_state;
106104

107105
/** @hwconfig: Hardware config state */

0 commit comments

Comments
 (0)