drivers/gpu/drm/xe/xe_exec.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_exec.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_exec.c
Extension
.c
Size
10947 bytes
Lines
373
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!syncs) {
			err = -ENOMEM;
			goto err_exec_queue;
		}
	}

	vm = q->vm;

	for (num_syncs = 0; num_syncs < args->num_syncs; num_syncs++) {
		err = xe_sync_entry_parse(xe, xef, &syncs[num_syncs],
					  &syncs_user[num_syncs], NULL, 0,
					  SYNC_PARSE_FLAG_EXEC |
					  (xe_vm_in_lr_mode(vm) ?
					   SYNC_PARSE_FLAG_LR_MODE : 0));
		if (err)
			goto err_syncs;

		if (xe_sync_is_ufence(&syncs[num_syncs]))
			num_ufence++;

		if (!num_in_sync && xe_sync_needs_wait(&syncs[num_syncs]))
			num_in_sync++;
	}

	if (XE_IOCTL_DBG(xe, num_ufence > 1)) {
		err = -EINVAL;
		goto err_syncs;
	}

	if (args->num_batch_buffer && xe_exec_queue_is_parallel(q)) {
		err = copy_from_user(addresses, addresses_user,
				     sizeof(u64) * q->width);
		if (err) {
			err = -EFAULT;
			goto err_syncs;
		}
	}

	group = q->hwe->hw_engine_group;
	mode = xe_hw_engine_group_find_exec_mode(q);

	if (mode == EXEC_MODE_DMA_FENCE) {
		err = xe_hw_engine_group_get_mode(group, mode, &previous_mode,
						  syncs, num_in_sync ?
						  num_syncs : 0);
		if (err)
			goto err_syncs;
	}

retry:
	if (!xe_vm_in_lr_mode(vm) && xe_vm_userptr_check_repin(vm)) {
		err = down_write_killable(&vm->lock);
		write_locked = true;
	} else {
		/* We don't allow execs while the VM is in error state */
		err = down_read_interruptible(&vm->lock);
		write_locked = false;
	}
	if (err)
		goto err_hw_exec_mode;

	if (write_locked) {
		err = xe_vm_userptr_pin(vm);
		downgrade_write(&vm->lock);
		write_locked = false;
		if (err)
			goto err_unlock_list;
	}

	if (!args->num_batch_buffer) {
		err = xe_vm_lock(vm, true);
		if (err)
			goto err_unlock_list;

		if (!xe_vm_in_lr_mode(vm)) {
			struct dma_fence *fence;

			fence = xe_sync_in_fence_get(syncs, num_syncs, q, vm);
			if (IS_ERR(fence)) {
				err = PTR_ERR(fence);
				xe_vm_unlock(vm);
				goto err_unlock_list;
			}
			for (i = 0; i < num_syncs; i++)
				xe_sync_entry_signal(&syncs[i], fence);
			xe_exec_queue_last_fence_set(q, vm, fence);
			dma_fence_put(fence);
		}

		xe_vm_unlock(vm);

Annotation

Implementation Notes