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

Commit 23ca0e4e authored by Chunming Zhou's avatar Chunming Zhou Committed by Alex Deucher
Browse files

drm/amdgpu: add kernel ctx support (v2)



v2: rebase against kfd changes

Signed-off-by: default avatarChunming Zhou <david1.zhou@amd.com>
Acked-by: default avatarChristian K?nig <christian.koenig@amd.com>
Reviewed-by: default avatarJammy Zhou <Jammy.Zhou@amd.com>
parent 4274f5d4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2065,6 +2065,9 @@ struct amdgpu_device {

	/* amdkfd interface */
	struct kfd_dev          *kfd;

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

bool amdgpu_device_is_px(struct drm_device *dev);
+59 −24
Original line number Diff line number Diff line
@@ -48,33 +48,53 @@ static void amdgpu_ctx_do_release(struct kref *ref)
	kfree(ctx);
}

static void amdgpu_ctx_init(struct amdgpu_device *adev,
			    struct amdgpu_fpriv *fpriv,
			    struct amdgpu_ctx *ctx,
			    uint32_t id)
{
	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)
{
	struct amdgpu_ctx *ctx;
	struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
	int i, j, r;

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

	if (fpriv) {
		struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
		mutex_lock(&mgr->lock);
	r = idr_alloc(&mgr->ctx_handles, ctx, 0, 0, GFP_KERNEL);
		r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL);
		if (r < 0) {
			mutex_unlock(&mgr->lock);
			kfree(ctx);
			return r;
		}
		*id = (uint32_t)r;

	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;
		amdgpu_ctx_init(adev, fpriv, ctx, *id);
		mutex_unlock(&mgr->lock);
	} else {
		if (adev->kernel_ctx) {
			DRM_ERROR("kernel cnotext has been created.\n");
			kfree(ctx);
			return 0;
		}
		*id = AMD_KERNEL_CONTEXT_ID;
		amdgpu_ctx_init(adev, fpriv, ctx, *id);

		adev->kernel_ctx = ctx;
	}

	if (amdgpu_enable_scheduler) {
		/* create context entity for each ring */
		for (i = 0; i < adev->num_rings; i++) {
@@ -105,8 +125,9 @@ int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t id)
{
	struct amdgpu_ctx *ctx;
	struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;

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

@@ -124,9 +150,13 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev,
			    union drm_amdgpu_ctx_out *out)
{
	struct amdgpu_ctx *ctx;
	struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
	struct amdgpu_ctx_mgr *mgr;
	unsigned reset_counter;

	if (!fpriv)
		return -EINVAL;

	mgr = &fpriv->ctx_mgr;
	mutex_lock(&mgr->lock);
	ctx = idr_find(&mgr->ctx_handles, id);
	if (!ctx) {
@@ -202,7 +232,12 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id)
{
	struct amdgpu_ctx *ctx;
	struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
	struct amdgpu_ctx_mgr *mgr;

	if (!fpriv)
		return NULL;

	mgr = &fpriv->ctx_mgr;

	mutex_lock(&mgr->lock);
	ctx = idr_find(&mgr->ctx_handles, id);
+9 −0
Original line number Diff line number Diff line
@@ -1525,6 +1525,14 @@ int amdgpu_device_init(struct amdgpu_device *adev,
		return r;
	}

	if (!adev->kernel_ctx) {
		uint32_t id = 0;
		r = amdgpu_ctx_alloc(adev, NULL, &id);
		if (r) {
			dev_err(adev->dev, "failed to create kernel context (%d).\n", r);
			return r;
		}
	}
	r = amdgpu_ib_ring_tests(adev);
	if (r)
		DRM_ERROR("ib ring test failed (%d).\n", r);
@@ -1586,6 +1594,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
	adev->shutdown = true;
	/* evict vram memory */
	amdgpu_bo_evict_vram(adev);
	amdgpu_ctx_free(adev, NULL, 0);
	amdgpu_ib_pool_fini(adev);
	amdgpu_fence_driver_fini(adev);
	amdgpu_fbdev_fini(adev);