Skip to content

Commit aa87b68

Browse files
committed
drm/xe: Disallow input fences on zero batch execs and zero binds
Prevent input fences from being installed on zero batch execs or zero binds, which were originally added to support queue idling in Mesa via output fences. Although input fence support was introduced for interface consistency, it leads to incorrect behavior due to chained composite fences, which are disallowed. Avoid the complexity of fixing this by removing support, as input fences for these cases are not used in practice. Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Link: https://patch.msgid.link/20251031234050.3043507-6-matthew.brost@intel.com
1 parent ebb0880 commit aa87b68

1 file changed

Lines changed: 36 additions & 65 deletions

File tree

drivers/gpu/drm/xe/xe_sync.c

Lines changed: 36 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -301,84 +301,55 @@ xe_sync_in_fence_get(struct xe_sync_entry *sync, int num_sync,
301301

302302
lockdep_assert_held(&vm->lock);
303303

304-
/* Count in-fences */
305-
for (i = 0; i < num_sync; ++i) {
306-
if (sync[i].fence) {
307-
++num_fence;
308-
fence = sync[i].fence;
309-
}
310-
}
311-
312-
/* Easy case... */
313-
if (!num_fence) {
314-
if (q->flags & EXEC_QUEUE_FLAG_VM) {
315-
struct xe_exec_queue *__q;
316-
struct xe_tile *tile;
317-
u8 id;
318-
319-
for_each_tile(tile, vm->xe, id)
320-
num_fence += (1 + XE_MAX_GT_PER_TILE);
321-
322-
fences = kmalloc_array(num_fence, sizeof(*fences),
323-
GFP_KERNEL);
324-
if (!fences)
325-
return ERR_PTR(-ENOMEM);
326-
304+
/* Reject in fences */
305+
for (i = 0; i < num_sync; ++i)
306+
if (sync[i].fence)
307+
return ERR_PTR(-EOPNOTSUPP);
308+
309+
if (q->flags & EXEC_QUEUE_FLAG_VM) {
310+
struct xe_exec_queue *__q;
311+
struct xe_tile *tile;
312+
u8 id;
313+
314+
for_each_tile(tile, vm->xe, id)
315+
num_fence += (1 + XE_MAX_GT_PER_TILE);
316+
317+
fences = kmalloc_array(num_fence, sizeof(*fences),
318+
GFP_KERNEL);
319+
if (!fences)
320+
return ERR_PTR(-ENOMEM);
321+
322+
fences[current_fence++] =
323+
xe_exec_queue_last_fence_get(q, vm);
324+
for_each_tlb_inval(i)
325+
fences[current_fence++] =
326+
xe_exec_queue_tlb_inval_last_fence_get(q, vm, i);
327+
list_for_each_entry(__q, &q->multi_gt_list,
328+
multi_gt_link) {
327329
fences[current_fence++] =
328-
xe_exec_queue_last_fence_get(q, vm);
330+
xe_exec_queue_last_fence_get(__q, vm);
329331
for_each_tlb_inval(i)
330332
fences[current_fence++] =
331-
xe_exec_queue_tlb_inval_last_fence_get(q, vm, i);
332-
list_for_each_entry(__q, &q->multi_gt_list,
333-
multi_gt_link) {
334-
fences[current_fence++] =
335-
xe_exec_queue_last_fence_get(__q, vm);
336-
for_each_tlb_inval(i)
337-
fences[current_fence++] =
338-
xe_exec_queue_tlb_inval_last_fence_get(__q, vm, i);
339-
}
340-
341-
xe_assert(vm->xe, current_fence == num_fence);
342-
cf = dma_fence_array_create(num_fence, fences,
343-
dma_fence_context_alloc(1),
344-
1, false);
345-
if (!cf)
346-
goto err_out;
347-
348-
return &cf->base;
333+
xe_exec_queue_tlb_inval_last_fence_get(__q, vm, i);
349334
}
350335

351-
fence = xe_exec_queue_last_fence_get(q, vm);
352-
return fence;
353-
}
336+
xe_assert(vm->xe, current_fence == num_fence);
337+
cf = dma_fence_array_create(num_fence, fences,
338+
dma_fence_context_alloc(1),
339+
1, false);
340+
if (!cf)
341+
goto err_out;
354342

355-
/*
356-
* Create composite fence - FIXME - the below code doesn't work. This is
357-
* unused in Mesa so we are ok for the moment. Perhaps we just disable
358-
* this entire code path if number of in fences != 0.
359-
*/
360-
fences = kmalloc_array(num_fence + 1, sizeof(*fences), GFP_KERNEL);
361-
if (!fences)
362-
return ERR_PTR(-ENOMEM);
363-
for (i = 0; i < num_sync; ++i) {
364-
if (sync[i].fence) {
365-
dma_fence_get(sync[i].fence);
366-
fences[current_fence++] = sync[i].fence;
367-
}
343+
return &cf->base;
368344
}
369-
fences[current_fence++] = xe_exec_queue_last_fence_get(q, vm);
370-
cf = dma_fence_array_create(num_fence, fences,
371-
dma_fence_context_alloc(1), 1, false);
372-
if (!cf)
373-
goto err_out;
374345

375-
return &cf->base;
346+
fence = xe_exec_queue_last_fence_get(q, vm);
347+
return fence;
376348

377349
err_out:
378350
while (current_fence)
379351
dma_fence_put(fences[--current_fence]);
380352
kfree(fences);
381-
kfree(cf);
382353

383354
return ERR_PTR(-ENOMEM);
384355
}

0 commit comments

Comments
 (0)