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

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

drm/amdgpu: cleanup amdgpu_ctx inti/fini v2



Cleanup the kernel context handling.

v2: rebased

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com> (v1)
parent 0e89d0c1
Loading
Loading
Loading
Loading
+4 −5
Original line number Original line Diff line number Diff line
@@ -1033,10 +1033,9 @@ struct amdgpu_ctx_mgr {
	struct idr		ctx_handles;
	struct idr		ctx_handles;
};
};


int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,
		     uint32_t *id);
		    struct amdgpu_ctx *ctx);
int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
void amdgpu_ctx_fini(struct amdgpu_ctx *ctx);
		    uint32_t id);


struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id);
struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id);
int amdgpu_ctx_put(struct amdgpu_ctx *ctx);
int amdgpu_ctx_put(struct amdgpu_ctx *ctx);
@@ -2095,7 +2094,7 @@ struct amdgpu_device {
	struct kfd_dev          *kfd;
	struct kfd_dev          *kfd;


	/* kernel conext for IB submission */
	/* kernel conext for IB submission */
	struct amdgpu_ctx *kernel_ctx;
	struct amdgpu_ctx	kernel_ctx;
};
};


bool amdgpu_device_is_px(struct drm_device *dev);
bool amdgpu_device_is_px(struct drm_device *dev);
+68 −77
Original line number Original line Diff line number Diff line
@@ -25,15 +25,49 @@
#include <drm/drmP.h>
#include <drm/drmP.h>
#include "amdgpu.h"
#include "amdgpu.h"


static void amdgpu_ctx_do_release(struct kref *ref)
int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,
		    struct amdgpu_ctx *ctx)
{
{
	struct amdgpu_ctx *ctx;
	struct amdgpu_device *adev;
	unsigned i, j;
	unsigned i, j;
	int r;


	ctx = container_of(ref, struct amdgpu_ctx, refcount);
	memset(ctx, 0, sizeof(*ctx));
	adev = ctx->adev;
	ctx->adev = adev;
	kref_init(&ctx->refcount);
	spin_lock_init(&ctx->ring_lock);
	for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
		ctx->rings[i].sequence = 1;

	if (amdgpu_enable_scheduler) {
		/* create context entity for each ring */
		for (i = 0; i < adev->num_rings; i++) {
			struct amd_run_queue *rq;
			if (kernel)
				rq = &adev->rings[i]->scheduler->kernel_rq;
			else
				rq = &adev->rings[i]->scheduler->sched_rq;
			r = amd_context_entity_init(adev->rings[i]->scheduler,
						    &ctx->rings[i].c_entity,
						    NULL, rq, amdgpu_sched_jobs);
			if (r)
				break;
		}


		if (i < adev->num_rings) {
			for (j = 0; j < i; j++)
				amd_context_entity_fini(adev->rings[j]->scheduler,
							&ctx->rings[j].c_entity);
			kfree(ctx);
			return r;
		}
	}
	return 0;
}

void amdgpu_ctx_fini(struct amdgpu_ctx *ctx)
{
	struct amdgpu_device *adev = ctx->adev;
	unsigned i, j;


	for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
	for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
		for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j)
		for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j)
@@ -44,34 +78,20 @@ static void amdgpu_ctx_do_release(struct kref *ref)
			amd_context_entity_fini(adev->rings[i]->scheduler,
			amd_context_entity_fini(adev->rings[i]->scheduler,
						&ctx->rings[i].c_entity);
						&ctx->rings[i].c_entity);
	}
	}

	kfree(ctx);
}
}


static void amdgpu_ctx_init(struct amdgpu_device *adev,
static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
			    struct amdgpu_fpriv *fpriv,
			    struct amdgpu_fpriv *fpriv,
			    struct amdgpu_ctx *ctx)
{
	int i;
	memset(ctx, 0, sizeof(*ctx));
	ctx->adev = adev;
	kref_init(&ctx->refcount);
	spin_lock_init(&ctx->ring_lock);
	for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
		ctx->rings[i].sequence = 1;
}

int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
			    uint32_t *id)
			    uint32_t *id)
{
{
	struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
	struct amdgpu_ctx *ctx;
	struct amdgpu_ctx *ctx;
	int i, j, r;
	int r;


	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
	if (!ctx)
		return -ENOMEM;
		return -ENOMEM;
	if (fpriv) {

		struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
	mutex_lock(&mgr->lock);
	mutex_lock(&mgr->lock);
	r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL);
	r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL);
	if (r < 0) {
	if (r < 0) {
@@ -80,52 +100,28 @@ int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
		return r;
		return r;
	}
	}
	*id = (uint32_t)r;
	*id = (uint32_t)r;
		amdgpu_ctx_init(adev, fpriv, ctx);
	r = amdgpu_ctx_init(adev, false, ctx);
	mutex_unlock(&mgr->lock);
	mutex_unlock(&mgr->lock);
	} else {
		if (adev->kernel_ctx) {
			DRM_ERROR("kernel cnotext has been created.\n");
			kfree(ctx);
			return 0;
		}
		amdgpu_ctx_init(adev, fpriv, ctx);


		adev->kernel_ctx = ctx;
	return r;
}
}


	if (amdgpu_enable_scheduler) {
static void amdgpu_ctx_do_release(struct kref *ref)
		/* create context entity for each ring */
{
		for (i = 0; i < adev->num_rings; i++) {
	struct amdgpu_ctx *ctx;
			struct amd_run_queue *rq;
			if (fpriv)
				rq = &adev->rings[i]->scheduler->sched_rq;
			else
				rq = &adev->rings[i]->scheduler->kernel_rq;
			r = amd_context_entity_init(adev->rings[i]->scheduler,
						    &ctx->rings[i].c_entity,
						    NULL, rq, amdgpu_sched_jobs);
			if (r)
				break;
		}


		if (i < adev->num_rings) {
	ctx = container_of(ref, struct amdgpu_ctx, refcount);
			for (j = 0; j < i; j++)
				amd_context_entity_fini(adev->rings[j]->scheduler,
							&ctx->rings[j].c_entity);
			kfree(ctx);
			return -EINVAL;
		}
	}


	return 0;
	amdgpu_ctx_fini(ctx);

	kfree(ctx);
}
}


int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t id)
static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id)
{
{
	struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
	struct amdgpu_ctx *ctx;
	struct amdgpu_ctx *ctx;


	if (fpriv) {
		struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
	mutex_lock(&mgr->lock);
	mutex_lock(&mgr->lock);
	ctx = idr_find(&mgr->ctx_handles, id);
	ctx = idr_find(&mgr->ctx_handles, id);
	if (ctx) {
	if (ctx) {
@@ -135,11 +131,6 @@ int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint
		return 0;
		return 0;
	}
	}
	mutex_unlock(&mgr->lock);
	mutex_unlock(&mgr->lock);
	} else {
		ctx = adev->kernel_ctx;
		kref_put(&ctx->refcount, amdgpu_ctx_do_release);
		return 0;
	}
	return -EINVAL;
	return -EINVAL;
}
}


@@ -198,7 +189,7 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
			args->out.alloc.ctx_id = id;
			args->out.alloc.ctx_id = id;
			break;
			break;
		case AMDGPU_CTX_OP_FREE_CTX:
		case AMDGPU_CTX_OP_FREE_CTX:
			r = amdgpu_ctx_free(adev, fpriv, id);
			r = amdgpu_ctx_free(fpriv, id);
			break;
			break;
		case AMDGPU_CTX_OP_QUERY_STATE:
		case AMDGPU_CTX_OP_QUERY_STATE:
			r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
			r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
+5 −8
Original line number Original line Diff line number Diff line
@@ -1525,14 +1525,11 @@ int amdgpu_device_init(struct amdgpu_device *adev,
		return r;
		return r;
	}
	}


	if (!adev->kernel_ctx) {
	r = amdgpu_ctx_init(adev, true, &adev->kernel_ctx);
		uint32_t id = 0;
		r = amdgpu_ctx_alloc(adev, NULL, &id);
	if (r) {
	if (r) {
		dev_err(adev->dev, "failed to create kernel context (%d).\n", r);
		dev_err(adev->dev, "failed to create kernel context (%d).\n", r);
		return r;
		return r;
	}
	}
	}
	r = amdgpu_ib_ring_tests(adev);
	r = amdgpu_ib_ring_tests(adev);
	if (r)
	if (r)
		DRM_ERROR("ib ring test failed (%d).\n", r);
		DRM_ERROR("ib ring test failed (%d).\n", r);
@@ -1594,7 +1591,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
	adev->shutdown = true;
	adev->shutdown = true;
	/* evict vram memory */
	/* evict vram memory */
	amdgpu_bo_evict_vram(adev);
	amdgpu_bo_evict_vram(adev);
	amdgpu_ctx_free(adev, NULL, 0);
	amdgpu_ctx_fini(&adev->kernel_ctx);
	amdgpu_ib_pool_fini(adev);
	amdgpu_ib_pool_fini(adev);
	amdgpu_fence_driver_fini(adev);
	amdgpu_fence_driver_fini(adev);
	amdgpu_fbdev_fini(adev);
	amdgpu_fbdev_fini(adev);
+3 −5
Original line number Original line Diff line number Diff line
@@ -122,19 +122,17 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,
	int r = 0;
	int r = 0;
	if (amdgpu_enable_scheduler) {
	if (amdgpu_enable_scheduler) {
		struct amdgpu_cs_parser *sched_job =
		struct amdgpu_cs_parser *sched_job =
			amdgpu_cs_parser_create(adev,
			amdgpu_cs_parser_create(adev, owner, &adev->kernel_ctx,
						owner,
						adev->kernel_ctx,
						ibs, 1);
						ibs, 1);
		if(!sched_job) {
		if(!sched_job) {
			return -ENOMEM;
			return -ENOMEM;
		}
		}
		sched_job->free_job = free_job;
		sched_job->free_job = free_job;
		ibs[num_ibs - 1].sequence = amd_sched_push_job(ring->scheduler,
		ibs[num_ibs - 1].sequence = amd_sched_push_job(ring->scheduler,
				   &adev->kernel_ctx->rings[ring->idx].c_entity,
				   &adev->kernel_ctx.rings[ring->idx].c_entity,
				   sched_job);
				   sched_job);
		r = amd_sched_wait_emit(
		r = amd_sched_wait_emit(
			&adev->kernel_ctx->rings[ring->idx].c_entity,
			&adev->kernel_ctx.rings[ring->idx].c_entity,
			ibs[num_ibs - 1].sequence, false, -1);
			ibs[num_ibs - 1].sequence, false, -1);
		if (r)
		if (r)
			WARN(true, "emit timeout\n");
			WARN(true, "emit timeout\n");
+9 −9
Original line number Original line Diff line number Diff line
@@ -372,16 +372,16 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
	if (amdgpu_enable_scheduler) {
	if (amdgpu_enable_scheduler) {
		int r;
		int r;
		sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
		sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
						    adev->kernel_ctx, ib, 1);
						    &adev->kernel_ctx, ib, 1);
		if(!sched_job)
		if(!sched_job)
			goto error_free;
			goto error_free;
		sched_job->job_param.vm.bo = bo;
		sched_job->job_param.vm.bo = bo;
		sched_job->run_job = amdgpu_vm_run_job;
		sched_job->run_job = amdgpu_vm_run_job;
		sched_job->free_job = amdgpu_vm_free_job;
		sched_job->free_job = amdgpu_vm_free_job;
		ib->sequence = amd_sched_push_job(ring->scheduler,
		ib->sequence = amd_sched_push_job(ring->scheduler,
				   &adev->kernel_ctx->rings[ring->idx].c_entity,
				   &adev->kernel_ctx.rings[ring->idx].c_entity,
				   sched_job);
				   sched_job);
		r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity,
		r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity,
					ib->sequence, false, -1);
					ib->sequence, false, -1);
		if (r)
		if (r)
			DRM_ERROR("emit timeout\n");
			DRM_ERROR("emit timeout\n");
@@ -517,7 +517,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
		if (amdgpu_enable_scheduler) {
		if (amdgpu_enable_scheduler) {
			int r;
			int r;
			sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
			sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
							    adev->kernel_ctx,
							    &adev->kernel_ctx,
							    ib, 1);
							    ib, 1);
			if(!sched_job)
			if(!sched_job)
				goto error_free;
				goto error_free;
@@ -525,9 +525,9 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
			sched_job->run_job = amdgpu_vm_run_job;
			sched_job->run_job = amdgpu_vm_run_job;
			sched_job->free_job = amdgpu_vm_free_job;
			sched_job->free_job = amdgpu_vm_free_job;
			ib->sequence = amd_sched_push_job(ring->scheduler,
			ib->sequence = amd_sched_push_job(ring->scheduler,
					   &adev->kernel_ctx->rings[ring->idx].c_entity,
					   &adev->kernel_ctx.rings[ring->idx].c_entity,
					   sched_job);
					   sched_job);
			r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity,
			r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity,
						ib->sequence, false, -1);
						ib->sequence, false, -1);
			if (r)
			if (r)
				DRM_ERROR("emit timeout\n");
				DRM_ERROR("emit timeout\n");
@@ -863,7 +863,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
	if (amdgpu_enable_scheduler) {
	if (amdgpu_enable_scheduler) {
		int r;
		int r;
		sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
		sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
						    adev->kernel_ctx, ib, 1);
						    &adev->kernel_ctx, ib, 1);
		if(!sched_job)
		if(!sched_job)
			goto error_free;
			goto error_free;
		sched_job->job_param.vm_mapping.vm = vm;
		sched_job->job_param.vm_mapping.vm = vm;
@@ -873,9 +873,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
		sched_job->run_job = amdgpu_vm_bo_update_mapping_run_job;
		sched_job->run_job = amdgpu_vm_bo_update_mapping_run_job;
		sched_job->free_job = amdgpu_vm_free_job;
		sched_job->free_job = amdgpu_vm_free_job;
		ib->sequence = amd_sched_push_job(ring->scheduler,
		ib->sequence = amd_sched_push_job(ring->scheduler,
				   &adev->kernel_ctx->rings[ring->idx].c_entity,
				   &adev->kernel_ctx.rings[ring->idx].c_entity,
				   sched_job);
				   sched_job);
		r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity,
		r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity,
					ib->sequence, false, -1);
					ib->sequence, false, -1);
		if (r)
		if (r)
			DRM_ERROR("emit timeout\n");
			DRM_ERROR("emit timeout\n");