diff mbox

[11/31] drm/amdgpu: add kernel ctx support (v2)

Message ID 1438381367-24980-12-git-send-email-alexander.deucher@amd.com (mailing list archive)
State New, archived
Headers show

Commit Message

Alex Deucher July 31, 2015, 10:22 p.m. UTC
From: Chunming Zhou <david1.zhou@amd.com>

v2: rebase against kfd changes

Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
Acked-by: Christian K?nig <christian.koenig@amd.com>
Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  3 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c    | 83 +++++++++++++++++++++---------
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  9 ++++
 3 files changed, 71 insertions(+), 24 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index d85df45..a9be614 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -2058,6 +2058,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);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 41bc7fc..a5d8242 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -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;
-
-	mutex_lock(&mgr->lock);
-	r = idr_alloc(&mgr->ctx_handles, ctx, 0, 0, GFP_KERNEL);
-	if (r < 0) {
+	if (fpriv) {
+		struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
+		mutex_lock(&mgr->lock);
+		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;
+		amdgpu_ctx_init(adev, fpriv, ctx, *id);
 		mutex_unlock(&mgr->lock);
-		kfree(ctx);
-		return r;
+	} 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;
 	}
-	*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;
-	mutex_unlock(&mgr->lock);
 	if (amdgpu_enable_scheduler) {
 		/* create context entity for each ring */
 		for (i = 0; i < adev->num_rings; i++) {
@@ -105,17 +125,23 @@  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;
 
-	mutex_lock(&mgr->lock);
-	ctx = idr_find(&mgr->ctx_handles, id);
-	if (ctx) {
-		idr_remove(&mgr->ctx_handles, id);
-		kref_put(&ctx->refcount, amdgpu_ctx_do_release);
+	if (fpriv) {
+		struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
+		mutex_lock(&mgr->lock);
+		ctx = idr_find(&mgr->ctx_handles, id);
+		if (ctx) {
+			idr_remove(&mgr->ctx_handles, id);
+			kref_put(&ctx->refcount, amdgpu_ctx_do_release);
+			mutex_unlock(&mgr->lock);
+			return 0;
+		}
 		mutex_unlock(&mgr->lock);
+	} else {
+		ctx = adev->kernel_ctx;
+		kref_put(&ctx->refcount, amdgpu_ctx_do_release);
 		return 0;
 	}
-	mutex_unlock(&mgr->lock);
 	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);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 4b641f3..7e39b72 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1517,6 +1517,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);
@@ -1578,6 +1586,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);