diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 101 |
1 files changed, 55 insertions, 46 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index e4424b4db5d3..c8de4b6194e8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -126,19 +126,6 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, | |||
126 | return 0; | 126 | return 0; |
127 | } | 127 | } |
128 | 128 | ||
129 | static void amdgpu_job_work_func(struct work_struct *work) | ||
130 | { | ||
131 | struct amdgpu_cs_parser *sched_job = | ||
132 | container_of(work, struct amdgpu_cs_parser, | ||
133 | job_work); | ||
134 | mutex_lock(&sched_job->job_lock); | ||
135 | if (sched_job->free_job) | ||
136 | sched_job->free_job(sched_job); | ||
137 | mutex_unlock(&sched_job->job_lock); | ||
138 | /* after processing job, free memory */ | ||
139 | fence_put(&sched_job->s_fence->base); | ||
140 | kfree(sched_job); | ||
141 | } | ||
142 | struct amdgpu_cs_parser *amdgpu_cs_parser_create(struct amdgpu_device *adev, | 129 | struct amdgpu_cs_parser *amdgpu_cs_parser_create(struct amdgpu_device *adev, |
143 | struct drm_file *filp, | 130 | struct drm_file *filp, |
144 | struct amdgpu_ctx *ctx, | 131 | struct amdgpu_ctx *ctx, |
@@ -157,10 +144,6 @@ struct amdgpu_cs_parser *amdgpu_cs_parser_create(struct amdgpu_device *adev, | |||
157 | parser->ctx = ctx; | 144 | parser->ctx = ctx; |
158 | parser->ibs = ibs; | 145 | parser->ibs = ibs; |
159 | parser->num_ibs = num_ibs; | 146 | parser->num_ibs = num_ibs; |
160 | if (amdgpu_enable_scheduler) { | ||
161 | mutex_init(&parser->job_lock); | ||
162 | INIT_WORK(&parser->job_work, amdgpu_job_work_func); | ||
163 | } | ||
164 | for (i = 0; i < num_ibs; i++) | 147 | for (i = 0; i < num_ibs; i++) |
165 | ibs[i].ctx = ctx; | 148 | ibs[i].ctx = ctx; |
166 | 149 | ||
@@ -508,15 +491,17 @@ static void amdgpu_cs_parser_fini_late(struct amdgpu_cs_parser *parser) | |||
508 | for (i = 0; i < parser->nchunks; i++) | 491 | for (i = 0; i < parser->nchunks; i++) |
509 | drm_free_large(parser->chunks[i].kdata); | 492 | drm_free_large(parser->chunks[i].kdata); |
510 | kfree(parser->chunks); | 493 | kfree(parser->chunks); |
511 | if (parser->ibs) | ||
512 | for (i = 0; i < parser->num_ibs; i++) | ||
513 | amdgpu_ib_free(parser->adev, &parser->ibs[i]); | ||
514 | kfree(parser->ibs); | ||
515 | if (parser->uf.bo) | ||
516 | drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base); | ||
517 | |||
518 | if (!amdgpu_enable_scheduler) | 494 | if (!amdgpu_enable_scheduler) |
519 | kfree(parser); | 495 | { |
496 | if (parser->ibs) | ||
497 | for (i = 0; i < parser->num_ibs; i++) | ||
498 | amdgpu_ib_free(parser->adev, &parser->ibs[i]); | ||
499 | kfree(parser->ibs); | ||
500 | if (parser->uf.bo) | ||
501 | drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base); | ||
502 | } | ||
503 | |||
504 | kfree(parser); | ||
520 | } | 505 | } |
521 | 506 | ||
522 | /** | 507 | /** |
@@ -533,12 +518,6 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo | |||
533 | amdgpu_cs_parser_fini_late(parser); | 518 | amdgpu_cs_parser_fini_late(parser); |
534 | } | 519 | } |
535 | 520 | ||
536 | static int amdgpu_cs_parser_free_job(struct amdgpu_cs_parser *sched_job) | ||
537 | { | ||
538 | amdgpu_cs_parser_fini_late(sched_job); | ||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, | 521 | static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, |
543 | struct amdgpu_vm *vm) | 522 | struct amdgpu_vm *vm) |
544 | { | 523 | { |
@@ -874,6 +853,19 @@ static struct amdgpu_ring *amdgpu_cs_parser_get_ring( | |||
874 | return ring; | 853 | return ring; |
875 | } | 854 | } |
876 | 855 | ||
856 | static int amdgpu_cs_free_job(struct amdgpu_job *sched_job) | ||
857 | { | ||
858 | int i; | ||
859 | amdgpu_ctx_put(sched_job->ctx); | ||
860 | if (sched_job->ibs) | ||
861 | for (i = 0; i < sched_job->num_ibs; i++) | ||
862 | amdgpu_ib_free(sched_job->adev, &sched_job->ibs[i]); | ||
863 | kfree(sched_job->ibs); | ||
864 | if (sched_job->uf.bo) | ||
865 | drm_gem_object_unreference_unlocked(&sched_job->uf.bo->gem_base); | ||
866 | return 0; | ||
867 | } | ||
868 | |||
877 | int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 869 | int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
878 | { | 870 | { |
879 | struct amdgpu_device *adev = dev->dev_private; | 871 | struct amdgpu_device *adev = dev->dev_private; |
@@ -900,33 +892,50 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
900 | } | 892 | } |
901 | 893 | ||
902 | if (amdgpu_enable_scheduler && parser->num_ibs) { | 894 | if (amdgpu_enable_scheduler && parser->num_ibs) { |
895 | struct amdgpu_job *job; | ||
903 | struct amdgpu_ring * ring = | 896 | struct amdgpu_ring * ring = |
904 | amdgpu_cs_parser_get_ring(adev, parser); | 897 | amdgpu_cs_parser_get_ring(adev, parser); |
905 | r = amdgpu_cs_parser_prepare_job(parser); | 898 | r = amdgpu_cs_parser_prepare_job(parser); |
906 | if (r) | 899 | if (r) |
907 | goto out; | 900 | goto out; |
908 | parser->ring = ring; | 901 | job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); |
909 | parser->free_job = amdgpu_cs_parser_free_job; | 902 | if (!job) |
910 | mutex_lock(&parser->job_lock); | 903 | return -ENOMEM; |
911 | r = amd_sched_push_job(ring->scheduler, | 904 | job->base.sched = ring->scheduler; |
912 | &parser->ctx->rings[ring->idx].entity, | 905 | job->base.s_entity = &parser->ctx->rings[ring->idx].entity; |
913 | parser, | 906 | job->adev = parser->adev; |
914 | &parser->s_fence); | 907 | job->ibs = parser->ibs; |
908 | job->num_ibs = parser->num_ibs; | ||
909 | job->owner = parser->filp; | ||
910 | job->ctx = amdgpu_ctx_get_ref(parser->ctx); | ||
911 | mutex_init(&job->job_lock); | ||
912 | if (job->ibs[job->num_ibs - 1].user) { | ||
913 | memcpy(&job->uf, &parser->uf, | ||
914 | sizeof(struct amdgpu_user_fence)); | ||
915 | job->ibs[job->num_ibs - 1].user = &job->uf; | ||
916 | } | ||
917 | |||
918 | job->free_job = amdgpu_cs_free_job; | ||
919 | mutex_lock(&job->job_lock); | ||
920 | r = amd_sched_push_job((struct amd_sched_job *)job); | ||
915 | if (r) { | 921 | if (r) { |
916 | mutex_unlock(&parser->job_lock); | 922 | mutex_unlock(&job->job_lock); |
923 | amdgpu_cs_free_job(job); | ||
924 | kfree(job); | ||
917 | goto out; | 925 | goto out; |
918 | } | 926 | } |
919 | parser->ibs[parser->num_ibs - 1].sequence = | 927 | job->ibs[parser->num_ibs - 1].sequence = |
920 | amdgpu_ctx_add_fence(parser->ctx, ring, | 928 | amdgpu_ctx_add_fence(job->ctx, ring, |
921 | &parser->s_fence->base, | 929 | &job->base.s_fence->base, |
922 | parser->s_fence->v_seq); | 930 | job->base.s_fence->v_seq); |
923 | cs->out.handle = parser->s_fence->v_seq; | 931 | cs->out.handle = job->base.s_fence->v_seq; |
924 | list_sort(NULL, &parser->validated, cmp_size_smaller_first); | 932 | list_sort(NULL, &parser->validated, cmp_size_smaller_first); |
925 | ttm_eu_fence_buffer_objects(&parser->ticket, | 933 | ttm_eu_fence_buffer_objects(&parser->ticket, |
926 | &parser->validated, | 934 | &parser->validated, |
927 | &parser->s_fence->base); | 935 | &job->base.s_fence->base); |
928 | 936 | ||
929 | mutex_unlock(&parser->job_lock); | 937 | mutex_unlock(&job->job_lock); |
938 | amdgpu_cs_parser_fini_late(parser); | ||
930 | up_read(&adev->exclusive_lock); | 939 | up_read(&adev->exclusive_lock); |
931 | return 0; | 940 | return 0; |
932 | } | 941 | } |