Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d71518b5 authored by Christian König's avatar Christian König Committed by Alex Deucher
Browse files

drm/amdgpu: cleanup in kernel job submission



Add a job_alloc_with_ib helper and proper job submission.

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucer@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a0332b56
Loading
Loading
Loading
Loading
+4 −9
Original line number Diff line number Diff line
@@ -797,14 +797,11 @@ extern struct amd_sched_backend_ops amdgpu_sched_ops;

int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
		     struct amdgpu_job **job);
int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
			     struct amdgpu_job **job);
void amdgpu_job_free(struct amdgpu_job *job);
int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,
					 struct amdgpu_ring *ring,
					 struct amdgpu_ib *ibs,
					 unsigned num_ibs,
					 int (*free_job)(struct amdgpu_job *),
					 void *owner,
					 struct fence **fence);
int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring,
		      void *owner, struct fence **f);

struct amdgpu_ring {
	struct amdgpu_device		*adev;
@@ -987,7 +984,6 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
		       uint64_t addr);
void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
		      struct amdgpu_bo_va *bo_va);
int amdgpu_vm_free_job(struct amdgpu_job *job);

/*
 * context related structures
@@ -1244,7 +1240,6 @@ struct amdgpu_job {
	uint32_t		num_ibs;
	void			*owner;
	struct amdgpu_user_fence uf;
	int (*free_job)(struct amdgpu_job *job);
};
#define to_amdgpu_job(sched_job)		\
		container_of((sched_job), struct amdgpu_job, base)
+1 −9
Original line number Diff line number Diff line
@@ -752,12 +752,6 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev,
	return 0;
}

static int amdgpu_cs_free_job(struct amdgpu_job *job)
{
	amdgpu_job_free(job);
	return 0;
}

static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
			    union drm_amdgpu_cs *cs)
{
@@ -771,12 +765,10 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
	job->base.sched = &ring->sched;
	job->base.s_entity = &p->ctx->rings[ring->idx].entity;
	job->owner = p->filp;
	job->free_job = amdgpu_cs_free_job;

	fence = amd_sched_fence_create(job->base.s_entity, p->filp);
	if (!fence) {
		amdgpu_cs_free_job(job);
		kfree(job);
		amdgpu_job_free(job);
		return -ENOMEM;
	}

+38 −38
Original line number Diff line number Diff line
@@ -45,11 +45,26 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
	(*job)->adev = adev;
	(*job)->ibs = (void *)&(*job)[1];
	(*job)->num_ibs = num_ibs;
	(*job)->free_job = NULL;

	return 0;
}

int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
			     struct amdgpu_job **job)
{
	int r;

	r = amdgpu_job_alloc(adev, 1, job);
	if (r)
		return r;

	r = amdgpu_ib_get(adev, NULL, size, &(*job)->ibs[0]);
	if (r)
		kfree(*job);

	return r;
}

void amdgpu_job_free(struct amdgpu_job *job)
{
	unsigned i;
@@ -58,7 +73,27 @@ void amdgpu_job_free(struct amdgpu_job *job)
		amdgpu_ib_free(job->adev, &job->ibs[i]);

	amdgpu_bo_unref(&job->uf.bo);
	/* TODO: Free the job structure here as well */
	kfree(job);
}

int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring,
		      void *owner, struct fence **f)
{
	struct amdgpu_device *adev = job->adev;

	job->ring = ring;
	job->base.sched = &ring->sched;
	job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity;
	job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner);
	if (!job->base.s_fence)
		return -ENOMEM;

	*f = fence_get(&job->base.s_fence->base);

	job->owner = owner;
	amd_sched_entity_push_job(&job->base);

	return 0;
}

static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job)
@@ -106,10 +141,7 @@ static struct fence *amdgpu_sched_run_job(struct amd_sched_job *sched_job)
	}

err:
	if (job->free_job)
		job->free_job(job);

	kfree(job);
	amdgpu_job_free(job);
	return fence;
}

@@ -117,35 +149,3 @@ struct amd_sched_backend_ops amdgpu_sched_ops = {
	.dependency = amdgpu_sched_dependency,
	.run_job = amdgpu_sched_run_job,
};

int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,
					 struct amdgpu_ring *ring,
					 struct amdgpu_ib *ibs,
					 unsigned num_ibs,
					 int (*free_job)(struct amdgpu_job *),
					 void *owner,
					 struct fence **f)
{
	struct amdgpu_job *job =
		kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL);
	if (!job)
		return -ENOMEM;
	job->base.sched = &ring->sched;
	job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity;
	job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner);
	if (!job->base.s_fence) {
		kfree(job);
		return -ENOMEM;
	}
	*f = fence_get(&job->base.s_fence->base);

	job->adev = adev;
	job->ring = ring;
	job->ibs = ibs;
	job->num_ibs = num_ibs;
	job->owner = owner;
	job->free_job = free_job;
	amd_sched_entity_push_job(&job->base);

	return 0;
}
+12 −22
Original line number Diff line number Diff line
@@ -1012,9 +1012,10 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring,
		       struct fence **fence)
{
	struct amdgpu_device *adev = ring->adev;
	struct amdgpu_job *job;

	uint32_t max_bytes;
	unsigned num_loops, num_dw;
	struct amdgpu_ib *ib;
	unsigned i;
	int r;

@@ -1026,20 +1027,12 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring,
	while (num_dw & 0x7)
		num_dw++;

	ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL);
	if (!ib)
		return -ENOMEM;

	r = amdgpu_ib_get(adev, NULL, num_dw * 4, ib);
	if (r) {
		kfree(ib);
	r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job);
	if (r)
		return r;
	}

	ib->length_dw = 0;

	if (resv) {
		r = amdgpu_sync_resv(adev, &ib->sync, resv,
		r = amdgpu_sync_resv(adev, &job->ibs[0].sync, resv,
				     AMDGPU_FENCE_OWNER_UNDEFINED);
		if (r) {
			DRM_ERROR("sync failed (%d).\n", r);
@@ -1050,27 +1043,24 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring,
	for (i = 0; i < num_loops; i++) {
		uint32_t cur_size_in_bytes = min(byte_count, max_bytes);

		amdgpu_emit_copy_buffer(adev, ib, src_offset, dst_offset,
					cur_size_in_bytes);
		amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_offset,
					dst_offset, cur_size_in_bytes);

		src_offset += cur_size_in_bytes;
		dst_offset += cur_size_in_bytes;
		byte_count -= cur_size_in_bytes;
	}

	amdgpu_ring_pad_ib(ring, ib);
	WARN_ON(ib->length_dw > num_dw);
	r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1,
						 &amdgpu_vm_free_job,
						 AMDGPU_FENCE_OWNER_UNDEFINED,
						 fence);
	amdgpu_ring_pad_ib(ring, &job->ibs[0]);
	WARN_ON(job->ibs[0].length_dw > num_dw);
	r = amdgpu_job_submit(job, ring, AMDGPU_FENCE_OWNER_UNDEFINED, fence);
	if (r)
		goto error_free;

	return 0;

error_free:
	amdgpu_ib_free(adev, ib);
	kfree(ib);
	amdgpu_job_free(job);
	return r;
}

+12 −25
Original line number Diff line number Diff line
@@ -823,14 +823,6 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
	return 0;
}

static int amdgpu_uvd_free_job(
	struct amdgpu_job *job)
{
	amdgpu_ib_free(job->adev, job->ibs);
	kfree(job->ibs);
	return 0;
}

static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring,
			       struct amdgpu_bo *bo,
			       struct fence **fence)
@@ -838,7 +830,8 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring,
	struct ttm_validate_buffer tv;
	struct ww_acquire_ctx ticket;
	struct list_head head;
	struct amdgpu_ib *ib = NULL;
	struct amdgpu_job *job;
	struct amdgpu_ib *ib;
	struct fence *f = NULL;
	struct amdgpu_device *adev = ring->adev;
	uint64_t addr;
@@ -862,15 +855,12 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring,
	r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
	if (r)
		goto err;
	ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL);
	if (!ib) {
		r = -ENOMEM;
		goto err;
	}
	r = amdgpu_ib_get(adev, NULL, 64, ib);

	r = amdgpu_job_alloc_with_ib(adev, 64, &job);
	if (r)
		goto err1;
		goto err;

	ib = &job->ibs[0];
	addr = amdgpu_bo_gpu_offset(bo);
	ib->ptr[0] = PACKET0(mmUVD_GPCOM_VCPU_DATA0, 0);
	ib->ptr[1] = addr;
@@ -882,12 +872,9 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring,
		ib->ptr[i] = PACKET2(0);
	ib->length_dw = 16;

	r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1,
						 &amdgpu_uvd_free_job,
						 AMDGPU_FENCE_OWNER_UNDEFINED,
						 &f);
	r = amdgpu_job_submit(job, ring, AMDGPU_FENCE_OWNER_UNDEFINED, &f);
	if (r)
		goto err2;
		goto err_free;

	ttm_eu_fence_buffer_objects(&ticket, &head, f);

@@ -897,10 +884,10 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring,
	fence_put(f);

	return 0;
err2:
	amdgpu_ib_free(ring->adev, ib);
err1:
	kfree(ib);

err_free:
	amdgpu_job_free(job);

err:
	ttm_eu_backoff_reservation(&ticket, &head);
	return r;
Loading