Commit aa87b681 authored by Matthew Brost's avatar Matthew Brost
Browse files

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: default avatarMatthew Brost <matthew.brost@intel.com>
Reviewed-by: default avatarThomas Hellström <thomas.hellstrom@linux.intel.com>
Link: https://patch.msgid.link/20251031234050.3043507-6-matthew.brost@intel.com
parent ebb0880d
Loading
Loading
Loading
Loading
+36 −65
Original line number Diff line number Diff line
@@ -301,16 +301,11 @@ xe_sync_in_fence_get(struct xe_sync_entry *sync, int num_sync,

	lockdep_assert_held(&vm->lock);

	/* Count in-fences */
	for (i = 0; i < num_sync; ++i) {
		if (sync[i].fence) {
			++num_fence;
			fence = sync[i].fence;
		}
	}
	/* Reject in fences */
	for (i = 0; i < num_sync; ++i)
		if (sync[i].fence)
			return ERR_PTR(-EOPNOTSUPP);

	/* Easy case... */
	if (!num_fence) {
	if (q->flags & EXEC_QUEUE_FLAG_VM) {
		struct xe_exec_queue *__q;
		struct xe_tile *tile;
@@ -350,35 +345,11 @@ xe_sync_in_fence_get(struct xe_sync_entry *sync, int num_sync,

	fence = xe_exec_queue_last_fence_get(q, vm);
	return fence;
	}

	/*
	 * Create composite fence - FIXME - the below code doesn't work. This is
	 * unused in Mesa so we are ok for the moment. Perhaps we just disable
	 * this entire code path if number of in fences != 0.
	 */
	fences = kmalloc_array(num_fence + 1, sizeof(*fences), GFP_KERNEL);
	if (!fences)
		return ERR_PTR(-ENOMEM);
	for (i = 0; i < num_sync; ++i) {
		if (sync[i].fence) {
			dma_fence_get(sync[i].fence);
			fences[current_fence++] = sync[i].fence;
		}
	}
	fences[current_fence++] = xe_exec_queue_last_fence_get(q, vm);
	cf = dma_fence_array_create(num_fence, fences,
				    dma_fence_context_alloc(1), 1, false);
	if (!cf)
		goto err_out;

	return &cf->base;

err_out:
	while (current_fence)
		dma_fence_put(fences[--current_fence]);
	kfree(fences);
	kfree(cf);

	return ERR_PTR(-ENOMEM);
}