summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChunming Zhou <david1.zhou@amd.com>2015-07-06 05:42:58 (GMT)
committerAlex Deucher <alexander.deucher@amd.com>2015-08-17 20:50:36 (GMT)
commit23ca0e4e478836dcb93a54aa68cb48fbc66fb0ed (patch)
tree6e68952c7bfac6a4409ba3a225e6567034de7649
parent4274f5d45cf11f88d7380702a7147b70553ddd6e (diff)
downloadlinux-23ca0e4e478836dcb93a54aa68cb48fbc66fb0ed.tar.xz
drm/amdgpu: add kernel ctx support (v2)
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>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c83
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c9
3 files changed, 71 insertions, 24 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 79e81f3..47e4809 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -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);
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 fefeeb2..801ebfc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -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);