aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c145
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c18
5 files changed, 89 insertions, 104 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 0cd776a55f05..53d70f766afe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1033,10 +1033,9 @@ struct amdgpu_ctx_mgr {
1033 struct idr ctx_handles; 1033 struct idr ctx_handles;
1034}; 1034};
1035 1035
1036int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, 1036int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,
1037 uint32_t *id); 1037 struct amdgpu_ctx *ctx);
1038int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, 1038void amdgpu_ctx_fini(struct amdgpu_ctx *ctx);
1039 uint32_t id);
1040 1039
1041struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id); 1040struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id);
1042int amdgpu_ctx_put(struct amdgpu_ctx *ctx); 1041int amdgpu_ctx_put(struct amdgpu_ctx *ctx);
@@ -2095,7 +2094,7 @@ struct amdgpu_device {
2095 struct kfd_dev *kfd; 2094 struct kfd_dev *kfd;
2096 2095
2097 /* kernel conext for IB submission */ 2096 /* kernel conext for IB submission */
2098 struct amdgpu_ctx *kernel_ctx; 2097 struct amdgpu_ctx kernel_ctx;
2099}; 2098};
2100 2099
2101bool amdgpu_device_is_px(struct drm_device *dev); 2100bool 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 c2290ae20312..08a9292729dc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -25,82 +25,27 @@
25#include <drm/drmP.h> 25#include <drm/drmP.h>
26#include "amdgpu.h" 26#include "amdgpu.h"
27 27
28static void amdgpu_ctx_do_release(struct kref *ref) 28int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,
29 struct amdgpu_ctx *ctx)
29{ 30{
30 struct amdgpu_ctx *ctx;
31 struct amdgpu_device *adev;
32 unsigned i, j; 31 unsigned i, j;
32 int r;
33 33
34 ctx = container_of(ref, struct amdgpu_ctx, refcount);
35 adev = ctx->adev;
36
37
38 for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
39 for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j)
40 fence_put(ctx->rings[i].fences[j]);
41
42 if (amdgpu_enable_scheduler) {
43 for (i = 0; i < adev->num_rings; i++)
44 amd_context_entity_fini(adev->rings[i]->scheduler,
45 &ctx->rings[i].c_entity);
46 }
47
48 kfree(ctx);
49}
50
51static void amdgpu_ctx_init(struct amdgpu_device *adev,
52 struct amdgpu_fpriv *fpriv,
53 struct amdgpu_ctx *ctx)
54{
55 int i;
56 memset(ctx, 0, sizeof(*ctx)); 34 memset(ctx, 0, sizeof(*ctx));
57 ctx->adev = adev; 35 ctx->adev = adev;
58 kref_init(&ctx->refcount); 36 kref_init(&ctx->refcount);
59 spin_lock_init(&ctx->ring_lock); 37 spin_lock_init(&ctx->ring_lock);
60 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) 38 for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
61 ctx->rings[i].sequence = 1; 39 ctx->rings[i].sequence = 1;
62}
63
64int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
65 uint32_t *id)
66{
67 struct amdgpu_ctx *ctx;
68 int i, j, r;
69
70 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
71 if (!ctx)
72 return -ENOMEM;
73 if (fpriv) {
74 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
75 mutex_lock(&mgr->lock);
76 r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL);
77 if (r < 0) {
78 mutex_unlock(&mgr->lock);
79 kfree(ctx);
80 return r;
81 }
82 *id = (uint32_t)r;
83 amdgpu_ctx_init(adev, fpriv, ctx);
84 mutex_unlock(&mgr->lock);
85 } else {
86 if (adev->kernel_ctx) {
87 DRM_ERROR("kernel cnotext has been created.\n");
88 kfree(ctx);
89 return 0;
90 }
91 amdgpu_ctx_init(adev, fpriv, ctx);
92
93 adev->kernel_ctx = ctx;
94 }
95 40
96 if (amdgpu_enable_scheduler) { 41 if (amdgpu_enable_scheduler) {
97 /* create context entity for each ring */ 42 /* create context entity for each ring */
98 for (i = 0; i < adev->num_rings; i++) { 43 for (i = 0; i < adev->num_rings; i++) {
99 struct amd_run_queue *rq; 44 struct amd_run_queue *rq;
100 if (fpriv) 45 if (kernel)
101 rq = &adev->rings[i]->scheduler->sched_rq;
102 else
103 rq = &adev->rings[i]->scheduler->kernel_rq; 46 rq = &adev->rings[i]->scheduler->kernel_rq;
47 else
48 rq = &adev->rings[i]->scheduler->sched_rq;
104 r = amd_context_entity_init(adev->rings[i]->scheduler, 49 r = amd_context_entity_init(adev->rings[i]->scheduler,
105 &ctx->rings[i].c_entity, 50 &ctx->rings[i].c_entity,
106 NULL, rq, amdgpu_sched_jobs); 51 NULL, rq, amdgpu_sched_jobs);
@@ -113,33 +58,79 @@ int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
113 amd_context_entity_fini(adev->rings[j]->scheduler, 58 amd_context_entity_fini(adev->rings[j]->scheduler,
114 &ctx->rings[j].c_entity); 59 &ctx->rings[j].c_entity);
115 kfree(ctx); 60 kfree(ctx);
116 return -EINVAL; 61 return r;
117 } 62 }
118 } 63 }
119
120 return 0; 64 return 0;
121} 65}
122 66
123int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t id) 67void amdgpu_ctx_fini(struct amdgpu_ctx *ctx)
124{ 68{
69 struct amdgpu_device *adev = ctx->adev;
70 unsigned i, j;
71
72 for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
73 for (j = 0; j < AMDGPU_CTX_MAX_CS_PENDING; ++j)
74 fence_put(ctx->rings[i].fences[j]);
75
76 if (amdgpu_enable_scheduler) {
77 for (i = 0; i < adev->num_rings; i++)
78 amd_context_entity_fini(adev->rings[i]->scheduler,
79 &ctx->rings[i].c_entity);
80 }
81}
82
83static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
84 struct amdgpu_fpriv *fpriv,
85 uint32_t *id)
86{
87 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
125 struct amdgpu_ctx *ctx; 88 struct amdgpu_ctx *ctx;
89 int r;
126 90
127 if (fpriv) { 91 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
128 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; 92 if (!ctx)
129 mutex_lock(&mgr->lock); 93 return -ENOMEM;
130 ctx = idr_find(&mgr->ctx_handles, id); 94
131 if (ctx) { 95 mutex_lock(&mgr->lock);
132 idr_remove(&mgr->ctx_handles, id); 96 r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL);
133 kref_put(&ctx->refcount, amdgpu_ctx_do_release); 97 if (r < 0) {
134 mutex_unlock(&mgr->lock);
135 return 0;
136 }
137 mutex_unlock(&mgr->lock); 98 mutex_unlock(&mgr->lock);
138 } else { 99 kfree(ctx);
139 ctx = adev->kernel_ctx; 100 return r;
101 }
102 *id = (uint32_t)r;
103 r = amdgpu_ctx_init(adev, false, ctx);
104 mutex_unlock(&mgr->lock);
105
106 return r;
107}
108
109static void amdgpu_ctx_do_release(struct kref *ref)
110{
111 struct amdgpu_ctx *ctx;
112
113 ctx = container_of(ref, struct amdgpu_ctx, refcount);
114
115 amdgpu_ctx_fini(ctx);
116
117 kfree(ctx);
118}
119
120static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id)
121{
122 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
123 struct amdgpu_ctx *ctx;
124
125 mutex_lock(&mgr->lock);
126 ctx = idr_find(&mgr->ctx_handles, id);
127 if (ctx) {
128 idr_remove(&mgr->ctx_handles, id);
140 kref_put(&ctx->refcount, amdgpu_ctx_do_release); 129 kref_put(&ctx->refcount, amdgpu_ctx_do_release);
130 mutex_unlock(&mgr->lock);
141 return 0; 131 return 0;
142 } 132 }
133 mutex_unlock(&mgr->lock);
143 return -EINVAL; 134 return -EINVAL;
144} 135}
145 136
@@ -198,7 +189,7 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
198 args->out.alloc.ctx_id = id; 189 args->out.alloc.ctx_id = id;
199 break; 190 break;
200 case AMDGPU_CTX_OP_FREE_CTX: 191 case AMDGPU_CTX_OP_FREE_CTX:
201 r = amdgpu_ctx_free(adev, fpriv, id); 192 r = amdgpu_ctx_free(fpriv, id);
202 break; 193 break;
203 case AMDGPU_CTX_OP_QUERY_STATE: 194 case AMDGPU_CTX_OP_QUERY_STATE:
204 r = amdgpu_ctx_query(adev, fpriv, id, &args->out); 195 r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 801ebfc44034..42d1a22c1199 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1525,13 +1525,10 @@ int amdgpu_device_init(struct amdgpu_device *adev,
1525 return r; 1525 return r;
1526 } 1526 }
1527 1527
1528 if (!adev->kernel_ctx) { 1528 r = amdgpu_ctx_init(adev, true, &adev->kernel_ctx);
1529 uint32_t id = 0; 1529 if (r) {
1530 r = amdgpu_ctx_alloc(adev, NULL, &id); 1530 dev_err(adev->dev, "failed to create kernel context (%d).\n", r);
1531 if (r) { 1531 return r;
1532 dev_err(adev->dev, "failed to create kernel context (%d).\n", r);
1533 return r;
1534 }
1535 } 1532 }
1536 r = amdgpu_ib_ring_tests(adev); 1533 r = amdgpu_ib_ring_tests(adev);
1537 if (r) 1534 if (r)
@@ -1594,7 +1591,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
1594 adev->shutdown = true; 1591 adev->shutdown = true;
1595 /* evict vram memory */ 1592 /* evict vram memory */
1596 amdgpu_bo_evict_vram(adev); 1593 amdgpu_bo_evict_vram(adev);
1597 amdgpu_ctx_free(adev, NULL, 0); 1594 amdgpu_ctx_fini(&adev->kernel_ctx);
1598 amdgpu_ib_pool_fini(adev); 1595 amdgpu_ib_pool_fini(adev);
1599 amdgpu_fence_driver_fini(adev); 1596 amdgpu_fence_driver_fini(adev);
1600 amdgpu_fbdev_fini(adev); 1597 amdgpu_fbdev_fini(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
index 9f2f19cc4625..995901b9e428 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
@@ -122,19 +122,17 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,
122 int r = 0; 122 int r = 0;
123 if (amdgpu_enable_scheduler) { 123 if (amdgpu_enable_scheduler) {
124 struct amdgpu_cs_parser *sched_job = 124 struct amdgpu_cs_parser *sched_job =
125 amdgpu_cs_parser_create(adev, 125 amdgpu_cs_parser_create(adev, owner, &adev->kernel_ctx,
126 owner,
127 adev->kernel_ctx,
128 ibs, 1); 126 ibs, 1);
129 if(!sched_job) { 127 if(!sched_job) {
130 return -ENOMEM; 128 return -ENOMEM;
131 } 129 }
132 sched_job->free_job = free_job; 130 sched_job->free_job = free_job;
133 ibs[num_ibs - 1].sequence = amd_sched_push_job(ring->scheduler, 131 ibs[num_ibs - 1].sequence = amd_sched_push_job(ring->scheduler,
134 &adev->kernel_ctx->rings[ring->idx].c_entity, 132 &adev->kernel_ctx.rings[ring->idx].c_entity,
135 sched_job); 133 sched_job);
136 r = amd_sched_wait_emit( 134 r = amd_sched_wait_emit(
137 &adev->kernel_ctx->rings[ring->idx].c_entity, 135 &adev->kernel_ctx.rings[ring->idx].c_entity,
138 ibs[num_ibs - 1].sequence, false, -1); 136 ibs[num_ibs - 1].sequence, false, -1);
139 if (r) 137 if (r)
140 WARN(true, "emit timeout\n"); 138 WARN(true, "emit timeout\n");
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index ab9c65a245ba..78713ae3b158 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -372,16 +372,16 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
372 if (amdgpu_enable_scheduler) { 372 if (amdgpu_enable_scheduler) {
373 int r; 373 int r;
374 sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, 374 sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
375 adev->kernel_ctx, ib, 1); 375 &adev->kernel_ctx, ib, 1);
376 if(!sched_job) 376 if(!sched_job)
377 goto error_free; 377 goto error_free;
378 sched_job->job_param.vm.bo = bo; 378 sched_job->job_param.vm.bo = bo;
379 sched_job->run_job = amdgpu_vm_run_job; 379 sched_job->run_job = amdgpu_vm_run_job;
380 sched_job->free_job = amdgpu_vm_free_job; 380 sched_job->free_job = amdgpu_vm_free_job;
381 ib->sequence = amd_sched_push_job(ring->scheduler, 381 ib->sequence = amd_sched_push_job(ring->scheduler,
382 &adev->kernel_ctx->rings[ring->idx].c_entity, 382 &adev->kernel_ctx.rings[ring->idx].c_entity,
383 sched_job); 383 sched_job);
384 r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity, 384 r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity,
385 ib->sequence, false, -1); 385 ib->sequence, false, -1);
386 if (r) 386 if (r)
387 DRM_ERROR("emit timeout\n"); 387 DRM_ERROR("emit timeout\n");
@@ -517,7 +517,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
517 if (amdgpu_enable_scheduler) { 517 if (amdgpu_enable_scheduler) {
518 int r; 518 int r;
519 sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, 519 sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
520 adev->kernel_ctx, 520 &adev->kernel_ctx,
521 ib, 1); 521 ib, 1);
522 if(!sched_job) 522 if(!sched_job)
523 goto error_free; 523 goto error_free;
@@ -525,9 +525,9 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
525 sched_job->run_job = amdgpu_vm_run_job; 525 sched_job->run_job = amdgpu_vm_run_job;
526 sched_job->free_job = amdgpu_vm_free_job; 526 sched_job->free_job = amdgpu_vm_free_job;
527 ib->sequence = amd_sched_push_job(ring->scheduler, 527 ib->sequence = amd_sched_push_job(ring->scheduler,
528 &adev->kernel_ctx->rings[ring->idx].c_entity, 528 &adev->kernel_ctx.rings[ring->idx].c_entity,
529 sched_job); 529 sched_job);
530 r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity, 530 r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity,
531 ib->sequence, false, -1); 531 ib->sequence, false, -1);
532 if (r) 532 if (r)
533 DRM_ERROR("emit timeout\n"); 533 DRM_ERROR("emit timeout\n");
@@ -863,7 +863,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
863 if (amdgpu_enable_scheduler) { 863 if (amdgpu_enable_scheduler) {
864 int r; 864 int r;
865 sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, 865 sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM,
866 adev->kernel_ctx, ib, 1); 866 &adev->kernel_ctx, ib, 1);
867 if(!sched_job) 867 if(!sched_job)
868 goto error_free; 868 goto error_free;
869 sched_job->job_param.vm_mapping.vm = vm; 869 sched_job->job_param.vm_mapping.vm = vm;
@@ -873,9 +873,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
873 sched_job->run_job = amdgpu_vm_bo_update_mapping_run_job; 873 sched_job->run_job = amdgpu_vm_bo_update_mapping_run_job;
874 sched_job->free_job = amdgpu_vm_free_job; 874 sched_job->free_job = amdgpu_vm_free_job;
875 ib->sequence = amd_sched_push_job(ring->scheduler, 875 ib->sequence = amd_sched_push_job(ring->scheduler,
876 &adev->kernel_ctx->rings[ring->idx].c_entity, 876 &adev->kernel_ctx.rings[ring->idx].c_entity,
877 sched_job); 877 sched_job);
878 r = amd_sched_wait_emit(&adev->kernel_ctx->rings[ring->idx].c_entity, 878 r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].c_entity,
879 ib->sequence, false, -1); 879 ib->sequence, false, -1);
880 if (r) 880 if (r)
881 DRM_ERROR("emit timeout\n"); 881 DRM_ERROR("emit timeout\n");