drivers/gpu/drm/virtio/virtgpu_submit.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/virtio/virtgpu_submit.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/virtio/virtgpu_submit.c
Extension
.c
Size
12288 bytes
Lines
545
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

struct virtio_gpu_submit_post_dep {
	struct drm_syncobj *syncobj;
	struct dma_fence_chain *chain;
	u64 point;
};

struct virtio_gpu_submit {
	struct virtio_gpu_submit_post_dep *post_deps;
	unsigned int num_out_syncobjs;

	struct drm_syncobj **in_syncobjs;
	unsigned int num_in_syncobjs;

	struct virtio_gpu_object_array *buflist;
	struct drm_virtgpu_execbuffer *exbuf;
	struct virtio_gpu_fence *out_fence;
	struct virtio_gpu_fpriv *vfpriv;
	struct virtio_gpu_device *vgdev;
	struct sync_file *sync_file;
	struct drm_file *file;
	int out_fence_fd;
	u64 fence_ctx;
	u32 ring_idx;
	void *buf;
};

static int virtio_gpu_do_fence_wait(struct virtio_gpu_submit *submit,
				    struct dma_fence *in_fence)
{
	u64 context = submit->fence_ctx + submit->ring_idx;

	if (dma_fence_match_context(in_fence, context))
		return 0;

	return dma_fence_wait(in_fence, true);
}

static int virtio_gpu_dma_fence_wait(struct virtio_gpu_submit *submit,
				     struct dma_fence *fence)
{
	struct dma_fence_unwrap itr;
	struct dma_fence *f;
	int err;

	dma_fence_unwrap_for_each(f, &itr, fence) {
		err = virtio_gpu_do_fence_wait(submit, f);
		if (err) {
			dma_fence_put(itr.chain);
			return err;
		}
	}

	return 0;
}

static void virtio_gpu_free_syncobjs(struct drm_syncobj **syncobjs,
				     u32 nr_syncobjs)
{
	u32 i = nr_syncobjs;

	while (i--) {
		if (syncobjs[i])
			drm_syncobj_put(syncobjs[i]);
	}

	kvfree(syncobjs);
}

static int
virtio_gpu_parse_deps(struct virtio_gpu_submit *submit)
{
	struct drm_virtgpu_execbuffer *exbuf = submit->exbuf;
	struct drm_virtgpu_execbuffer_syncobj syncobj_desc;
	size_t syncobj_stride = exbuf->syncobj_stride;
	u32 num_in_syncobjs = exbuf->num_in_syncobjs;
	struct drm_syncobj **syncobjs;
	int ret = 0, i;

	if (!num_in_syncobjs)
		return 0;

	/*
	 * kvmalloc() at first tries to allocate memory using kmalloc() and
	 * falls back to vmalloc() only on failure. It also uses __GFP_NOWARN
	 * internally for allocations larger than a page size, preventing
	 * storm of KMSG warnings.
	 */
	syncobjs = kvzalloc_objs(*syncobjs, num_in_syncobjs);
	if (!syncobjs)
		return -ENOMEM;

Annotation

Implementation Notes