diff options
author | Chunming Zhou <david1.zhou@amd.com> | 2015-08-03 00:57:31 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-08-17 16:51:07 -0400 |
commit | 4af9f07ccdac96e16f7a0ddaf983891a29ebd11a (patch) | |
tree | 2c95acf9753bb1881b174e700b9b38bcc81870ea | |
parent | 953e8fd4e734857f6dabbaf325035bf10c4a9c7a (diff) |
drm/amdgpu: use kernel submit helper in vm
Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
Reviewed-by: Christian K?nig <christian.koenig@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 159 |
3 files changed, 33 insertions, 144 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 1e6800050ad8..987e3075a03f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1235,19 +1235,6 @@ struct amdgpu_cs_chunk { | |||
1235 | void __user *user_ptr; | 1235 | void __user *user_ptr; |
1236 | }; | 1236 | }; |
1237 | 1237 | ||
1238 | union amdgpu_sched_job_param { | ||
1239 | struct { | ||
1240 | struct amdgpu_vm *vm; | ||
1241 | uint64_t start; | ||
1242 | uint64_t last; | ||
1243 | struct fence **fence; | ||
1244 | |||
1245 | } vm_mapping; | ||
1246 | struct { | ||
1247 | struct amdgpu_bo *bo; | ||
1248 | } vm; | ||
1249 | }; | ||
1250 | |||
1251 | struct amdgpu_cs_parser { | 1238 | struct amdgpu_cs_parser { |
1252 | struct amdgpu_device *adev; | 1239 | struct amdgpu_device *adev; |
1253 | struct drm_file *filp; | 1240 | struct drm_file *filp; |
@@ -1272,7 +1259,6 @@ struct amdgpu_cs_parser { | |||
1272 | struct mutex job_lock; | 1259 | struct mutex job_lock; |
1273 | struct work_struct job_work; | 1260 | struct work_struct job_work; |
1274 | int (*prepare_job)(struct amdgpu_cs_parser *sched_job); | 1261 | int (*prepare_job)(struct amdgpu_cs_parser *sched_job); |
1275 | union amdgpu_sched_job_param job_param; | ||
1276 | int (*run_job)(struct amdgpu_cs_parser *sched_job); | 1262 | int (*run_job)(struct amdgpu_cs_parser *sched_job); |
1277 | int (*free_job)(struct amdgpu_cs_parser *sched_job); | 1263 | int (*free_job)(struct amdgpu_cs_parser *sched_job); |
1278 | }; | 1264 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index d13d01511694..d82f2481bd0e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | |||
@@ -121,7 +121,7 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, | |||
121 | uint64_t v_seq; | 121 | uint64_t v_seq; |
122 | struct amdgpu_cs_parser *sched_job = | 122 | struct amdgpu_cs_parser *sched_job = |
123 | amdgpu_cs_parser_create(adev, owner, &adev->kernel_ctx, | 123 | amdgpu_cs_parser_create(adev, owner, &adev->kernel_ctx, |
124 | ibs, 1); | 124 | ibs, num_ibs); |
125 | if(!sched_job) { | 125 | if(!sched_job) { |
126 | return -ENOMEM; | 126 | return -ENOMEM; |
127 | } | 127 | } |
@@ -139,7 +139,7 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, | |||
139 | if (r) | 139 | if (r) |
140 | WARN(true, "emit timeout\n"); | 140 | WARN(true, "emit timeout\n"); |
141 | } else | 141 | } else |
142 | r = amdgpu_ib_schedule(adev, 1, ibs, owner); | 142 | r = amdgpu_ib_schedule(adev, num_ibs, ibs, owner); |
143 | if (r) | 143 | if (r) |
144 | return r; | 144 | return r; |
145 | *f = &ibs[num_ibs - 1].fence->base; | 145 | *f = &ibs[num_ibs - 1].fence->base; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 230bf1f34ead..b3f5d0484980 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -316,14 +316,6 @@ static int amdgpu_vm_free_job( | |||
316 | return 0; | 316 | return 0; |
317 | } | 317 | } |
318 | 318 | ||
319 | static int amdgpu_vm_run_job( | ||
320 | struct amdgpu_cs_parser *sched_job) | ||
321 | { | ||
322 | amdgpu_bo_fence(sched_job->job_param.vm.bo, | ||
323 | &sched_job->ibs[sched_job->num_ibs -1].fence->base, true); | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | /** | 319 | /** |
328 | * amdgpu_vm_clear_bo - initially clear the page dir/table | 320 | * amdgpu_vm_clear_bo - initially clear the page dir/table |
329 | * | 321 | * |
@@ -334,7 +326,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, | |||
334 | struct amdgpu_bo *bo) | 326 | struct amdgpu_bo *bo) |
335 | { | 327 | { |
336 | struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; | 328 | struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; |
337 | struct amdgpu_cs_parser *sched_job = NULL; | 329 | struct fence *fence = NULL; |
338 | struct amdgpu_ib *ib; | 330 | struct amdgpu_ib *ib; |
339 | unsigned entries; | 331 | unsigned entries; |
340 | uint64_t addr; | 332 | uint64_t addr; |
@@ -368,38 +360,16 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, | |||
368 | amdgpu_vm_update_pages(adev, ib, addr, 0, entries, 0, 0, 0); | 360 | amdgpu_vm_update_pages(adev, ib, addr, 0, entries, 0, 0, 0); |
369 | amdgpu_vm_pad_ib(adev, ib); | 361 | amdgpu_vm_pad_ib(adev, ib); |
370 | WARN_ON(ib->length_dw > 64); | 362 | WARN_ON(ib->length_dw > 64); |
371 | 363 | r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, | |
364 | &amdgpu_vm_free_job, | ||
365 | AMDGPU_FENCE_OWNER_VM, | ||
366 | &fence); | ||
367 | if (!r) | ||
368 | amdgpu_bo_fence(bo, fence, true); | ||
372 | if (amdgpu_enable_scheduler) { | 369 | if (amdgpu_enable_scheduler) { |
373 | int r; | ||
374 | uint64_t v_seq; | ||
375 | sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, | ||
376 | &adev->kernel_ctx, ib, 1); | ||
377 | if(!sched_job) | ||
378 | goto error_free; | ||
379 | sched_job->job_param.vm.bo = bo; | ||
380 | sched_job->run_job = amdgpu_vm_run_job; | ||
381 | sched_job->free_job = amdgpu_vm_free_job; | ||
382 | v_seq = atomic64_inc_return(&adev->kernel_ctx.rings[ring->idx].entity.last_queued_v_seq); | ||
383 | ib->sequence = v_seq; | ||
384 | amd_sched_push_job(ring->scheduler, | ||
385 | &adev->kernel_ctx.rings[ring->idx].entity, | ||
386 | sched_job); | ||
387 | r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].entity, | ||
388 | v_seq, | ||
389 | false, | ||
390 | -1); | ||
391 | if (r) | ||
392 | DRM_ERROR("emit timeout\n"); | ||
393 | |||
394 | amdgpu_bo_unreserve(bo); | 370 | amdgpu_bo_unreserve(bo); |
395 | return 0; | 371 | return 0; |
396 | } else { | ||
397 | r = amdgpu_ib_schedule(adev, 1, ib, AMDGPU_FENCE_OWNER_VM); | ||
398 | if (r) | ||
399 | goto error_free; | ||
400 | amdgpu_bo_fence(bo, &ib->fence->base, true); | ||
401 | } | 372 | } |
402 | |||
403 | error_free: | 373 | error_free: |
404 | amdgpu_ib_free(adev, ib); | 374 | amdgpu_ib_free(adev, ib); |
405 | kfree(ib); | 375 | kfree(ib); |
@@ -456,7 +426,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | |||
456 | uint64_t last_pde = ~0, last_pt = ~0; | 426 | uint64_t last_pde = ~0, last_pt = ~0; |
457 | unsigned count = 0, pt_idx, ndw; | 427 | unsigned count = 0, pt_idx, ndw; |
458 | struct amdgpu_ib *ib; | 428 | struct amdgpu_ib *ib; |
459 | struct amdgpu_cs_parser *sched_job = NULL; | 429 | struct fence *fence = NULL; |
460 | 430 | ||
461 | int r; | 431 | int r; |
462 | 432 | ||
@@ -518,37 +488,13 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | |||
518 | amdgpu_vm_pad_ib(adev, ib); | 488 | amdgpu_vm_pad_ib(adev, ib); |
519 | amdgpu_sync_resv(adev, &ib->sync, pd->tbo.resv, AMDGPU_FENCE_OWNER_VM); | 489 | amdgpu_sync_resv(adev, &ib->sync, pd->tbo.resv, AMDGPU_FENCE_OWNER_VM); |
520 | WARN_ON(ib->length_dw > ndw); | 490 | WARN_ON(ib->length_dw > ndw); |
521 | 491 | r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, | |
522 | if (amdgpu_enable_scheduler) { | 492 | &amdgpu_vm_free_job, |
523 | int r; | 493 | AMDGPU_FENCE_OWNER_VM, |
524 | uint64_t v_seq; | 494 | &fence); |
525 | sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, | 495 | if (r) |
526 | &adev->kernel_ctx, | 496 | goto error_free; |
527 | ib, 1); | 497 | amdgpu_bo_fence(pd, fence, true); |
528 | if(!sched_job) | ||
529 | goto error_free; | ||
530 | sched_job->job_param.vm.bo = pd; | ||
531 | sched_job->run_job = amdgpu_vm_run_job; | ||
532 | sched_job->free_job = amdgpu_vm_free_job; | ||
533 | v_seq = atomic64_inc_return(&adev->kernel_ctx.rings[ring->idx].entity.last_queued_v_seq); | ||
534 | ib->sequence = v_seq; | ||
535 | amd_sched_push_job(ring->scheduler, | ||
536 | &adev->kernel_ctx.rings[ring->idx].entity, | ||
537 | sched_job); | ||
538 | r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].entity, | ||
539 | v_seq, | ||
540 | false, | ||
541 | -1); | ||
542 | if (r) | ||
543 | DRM_ERROR("emit timeout\n"); | ||
544 | } else { | ||
545 | r = amdgpu_ib_schedule(adev, 1, ib, AMDGPU_FENCE_OWNER_VM); | ||
546 | if (r) { | ||
547 | amdgpu_ib_free(adev, ib); | ||
548 | return r; | ||
549 | } | ||
550 | amdgpu_bo_fence(pd, &ib->fence->base, true); | ||
551 | } | ||
552 | } | 498 | } |
553 | 499 | ||
554 | if (!amdgpu_enable_scheduler || ib->length_dw == 0) { | 500 | if (!amdgpu_enable_scheduler || ib->length_dw == 0) { |
@@ -559,11 +505,9 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | |||
559 | return 0; | 505 | return 0; |
560 | 506 | ||
561 | error_free: | 507 | error_free: |
562 | if (sched_job) | ||
563 | kfree(sched_job); | ||
564 | amdgpu_ib_free(adev, ib); | 508 | amdgpu_ib_free(adev, ib); |
565 | kfree(ib); | 509 | kfree(ib); |
566 | return -ENOMEM; | 510 | return r; |
567 | } | 511 | } |
568 | 512 | ||
569 | /** | 513 | /** |
@@ -748,20 +692,6 @@ static void amdgpu_vm_fence_pts(struct amdgpu_vm *vm, | |||
748 | amdgpu_bo_fence(vm->page_tables[i].bo, fence, true); | 692 | amdgpu_bo_fence(vm->page_tables[i].bo, fence, true); |
749 | } | 693 | } |
750 | 694 | ||
751 | static int amdgpu_vm_bo_update_mapping_run_job( | ||
752 | struct amdgpu_cs_parser *sched_job) | ||
753 | { | ||
754 | struct fence **fence = sched_job->job_param.vm_mapping.fence; | ||
755 | amdgpu_vm_fence_pts(sched_job->job_param.vm_mapping.vm, | ||
756 | sched_job->job_param.vm_mapping.start, | ||
757 | sched_job->job_param.vm_mapping.last + 1, | ||
758 | &sched_job->ibs[sched_job->num_ibs -1].fence->base); | ||
759 | if (fence) { | ||
760 | fence_put(*fence); | ||
761 | *fence = fence_get(&sched_job->ibs[sched_job->num_ibs -1].fence->base); | ||
762 | } | ||
763 | return 0; | ||
764 | } | ||
765 | /** | 695 | /** |
766 | * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table | 696 | * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table |
767 | * | 697 | * |
@@ -787,7 +717,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
787 | unsigned nptes, ncmds, ndw; | 717 | unsigned nptes, ncmds, ndw; |
788 | uint32_t flags = gtt_flags; | 718 | uint32_t flags = gtt_flags; |
789 | struct amdgpu_ib *ib; | 719 | struct amdgpu_ib *ib; |
790 | struct amdgpu_cs_parser *sched_job = NULL; | 720 | struct fence *f = NULL; |
791 | int r; | 721 | int r; |
792 | 722 | ||
793 | /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here | 723 | /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here |
@@ -869,56 +799,29 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
869 | 799 | ||
870 | amdgpu_vm_pad_ib(adev, ib); | 800 | amdgpu_vm_pad_ib(adev, ib); |
871 | WARN_ON(ib->length_dw > ndw); | 801 | WARN_ON(ib->length_dw > ndw); |
802 | r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, | ||
803 | &amdgpu_vm_free_job, | ||
804 | AMDGPU_FENCE_OWNER_VM, | ||
805 | &f); | ||
806 | if (r) | ||
807 | goto error_free; | ||
872 | 808 | ||
873 | if (amdgpu_enable_scheduler) { | 809 | amdgpu_vm_fence_pts(vm, mapping->it.start, |
874 | int r; | 810 | mapping->it.last + 1, f); |
875 | uint64_t v_seq; | 811 | if (fence) { |
876 | sched_job = amdgpu_cs_parser_create(adev, AMDGPU_FENCE_OWNER_VM, | 812 | fence_put(*fence); |
877 | &adev->kernel_ctx, ib, 1); | 813 | *fence = fence_get(f); |
878 | if(!sched_job) | 814 | } |
879 | goto error_free; | 815 | if (!amdgpu_enable_scheduler) { |
880 | sched_job->job_param.vm_mapping.vm = vm; | ||
881 | sched_job->job_param.vm_mapping.start = mapping->it.start; | ||
882 | sched_job->job_param.vm_mapping.last = mapping->it.last; | ||
883 | sched_job->job_param.vm_mapping.fence = fence; | ||
884 | sched_job->run_job = amdgpu_vm_bo_update_mapping_run_job; | ||
885 | sched_job->free_job = amdgpu_vm_free_job; | ||
886 | v_seq = atomic64_inc_return(&adev->kernel_ctx.rings[ring->idx].entity.last_queued_v_seq); | ||
887 | ib->sequence = v_seq; | ||
888 | amd_sched_push_job(ring->scheduler, | ||
889 | &adev->kernel_ctx.rings[ring->idx].entity, | ||
890 | sched_job); | ||
891 | r = amd_sched_wait_emit(&adev->kernel_ctx.rings[ring->idx].entity, | ||
892 | v_seq, | ||
893 | false, | ||
894 | -1); | ||
895 | if (r) | ||
896 | DRM_ERROR("emit timeout\n"); | ||
897 | } else { | ||
898 | r = amdgpu_ib_schedule(adev, 1, ib, AMDGPU_FENCE_OWNER_VM); | ||
899 | if (r) { | ||
900 | amdgpu_ib_free(adev, ib); | ||
901 | return r; | ||
902 | } | ||
903 | |||
904 | amdgpu_vm_fence_pts(vm, mapping->it.start, | ||
905 | mapping->it.last + 1, &ib->fence->base); | ||
906 | if (fence) { | ||
907 | fence_put(*fence); | ||
908 | *fence = fence_get(&ib->fence->base); | ||
909 | } | ||
910 | |||
911 | amdgpu_ib_free(adev, ib); | 816 | amdgpu_ib_free(adev, ib); |
912 | kfree(ib); | 817 | kfree(ib); |
913 | } | 818 | } |
914 | return 0; | 819 | return 0; |
915 | 820 | ||
916 | error_free: | 821 | error_free: |
917 | if (sched_job) | ||
918 | kfree(sched_job); | ||
919 | amdgpu_ib_free(adev, ib); | 822 | amdgpu_ib_free(adev, ib); |
920 | kfree(ib); | 823 | kfree(ib); |
921 | return -ENOMEM; | 824 | return r; |
922 | } | 825 | } |
923 | 826 | ||
924 | /** | 827 | /** |