.. | .. |
---|
13 | 13 | #include "rga_mm.h" |
---|
14 | 14 | #include "rga_iommu.h" |
---|
15 | 15 | #include "rga_debugger.h" |
---|
| 16 | +#include "rga_common.h" |
---|
16 | 17 | |
---|
17 | 18 | static void rga_job_free(struct rga_job *job) |
---|
18 | 19 | { |
---|
.. | .. |
---|
40 | 41 | |
---|
41 | 42 | static int rga_job_cleanup(struct rga_job *job) |
---|
42 | 43 | { |
---|
43 | | - if (DEBUGGER_EN(TIME)) |
---|
44 | | - pr_err("(pid:%d) job clean use time = %lld\n", job->pid, |
---|
45 | | - ktime_us_delta(ktime_get(), job->timestamp)); |
---|
46 | | - |
---|
47 | 44 | rga_job_put(job); |
---|
| 45 | + |
---|
| 46 | + if (DEBUGGER_EN(TIME)) |
---|
| 47 | + pr_info("request[%d], job cleanup total cost time %lld us\n", |
---|
| 48 | + job->request_id, |
---|
| 49 | + ktime_us_delta(ktime_get(), job->timestamp)); |
---|
48 | 50 | |
---|
49 | 51 | return 0; |
---|
50 | 52 | } |
---|
.. | .. |
---|
272 | 274 | if (DEBUGGER_EN(DUMP_IMAGE)) |
---|
273 | 275 | rga_dump_job_image(job); |
---|
274 | 276 | |
---|
275 | | - if (DEBUGGER_EN(TIME)) { |
---|
276 | | - pr_info("hw use time = %lld\n", ktime_us_delta(now, job->hw_running_time)); |
---|
277 | | - pr_info("(pid:%d) job done use time = %lld\n", job->pid, |
---|
278 | | - ktime_us_delta(now, job->timestamp)); |
---|
279 | | - } |
---|
| 277 | + if (DEBUGGER_EN(TIME)) |
---|
| 278 | + pr_info("request[%d], hardware[%s] cost time %lld us\n", |
---|
| 279 | + job->request_id, |
---|
| 280 | + rga_get_core_name(scheduler->core), |
---|
| 281 | + ktime_us_delta(now, job->hw_running_time)); |
---|
280 | 282 | |
---|
281 | 283 | rga_mm_unmap_job_info(job); |
---|
282 | 284 | |
---|
.. | .. |
---|
492 | 494 | return false; |
---|
493 | 495 | } |
---|
494 | 496 | |
---|
495 | | -static int rga_request_get_current_mm(struct rga_request *request) |
---|
| 497 | +static struct mm_struct *rga_request_get_current_mm(struct rga_request *request) |
---|
496 | 498 | { |
---|
497 | 499 | int i; |
---|
498 | 500 | |
---|
.. | .. |
---|
500 | 502 | if (rga_is_need_current_mm(&(request->task_list[i]))) { |
---|
501 | 503 | mmgrab(current->mm); |
---|
502 | 504 | mmget(current->mm); |
---|
503 | | - request->current_mm = current->mm; |
---|
504 | 505 | |
---|
505 | | - break; |
---|
| 506 | + return current->mm; |
---|
506 | 507 | } |
---|
507 | 508 | } |
---|
508 | 509 | |
---|
509 | | - return 0; |
---|
| 510 | + return NULL; |
---|
510 | 511 | } |
---|
511 | 512 | |
---|
512 | | -static void rga_request_put_current_mm(struct rga_request *request) |
---|
| 513 | +static void rga_request_put_current_mm(struct mm_struct *mm) |
---|
513 | 514 | { |
---|
514 | | - if (request->current_mm == NULL) |
---|
| 515 | + if (mm == NULL) |
---|
515 | 516 | return; |
---|
516 | 517 | |
---|
517 | | - mmput(request->current_mm); |
---|
518 | | - mmdrop(request->current_mm); |
---|
519 | | - request->current_mm = NULL; |
---|
| 518 | + mmput(mm); |
---|
| 519 | + mmdrop(mm); |
---|
520 | 520 | } |
---|
521 | 521 | |
---|
522 | 522 | static int rga_request_add_acquire_fence_callback(int acquire_fence_fd, |
---|
.. | .. |
---|
536 | 536 | __func__, acquire_fence_fd); |
---|
537 | 537 | return -EINVAL; |
---|
538 | 538 | } |
---|
539 | | - /* close acquire fence fd */ |
---|
| 539 | + |
---|
| 540 | + if (!request->feature.user_close_fence) { |
---|
| 541 | + /* close acquire fence fd */ |
---|
| 542 | +#ifdef CONFIG_NO_GKI |
---|
540 | 543 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) |
---|
541 | | - close_fd(acquire_fence_fd); |
---|
| 544 | + close_fd(acquire_fence_fd); |
---|
542 | 545 | #else |
---|
543 | | - ksys_close(acquire_fence_fd); |
---|
| 546 | + ksys_close(acquire_fence_fd); |
---|
544 | 547 | #endif |
---|
| 548 | +#else |
---|
| 549 | + pr_err("Please update the driver to v1.2.28 to prevent acquire_fence_fd leaks."); |
---|
| 550 | + return -EFAULT; |
---|
| 551 | +#endif |
---|
| 552 | + } |
---|
| 553 | + |
---|
545 | 554 | |
---|
546 | 555 | ret = rga_dma_fence_get_status(acquire_fence); |
---|
547 | 556 | if (ret < 0) { |
---|
.. | .. |
---|
650 | 659 | scheduler->ops->soft_reset(scheduler); |
---|
651 | 660 | } |
---|
652 | 661 | |
---|
653 | | - pr_err("reset core[%d] by request abort", scheduler->core); |
---|
| 662 | + pr_err("reset core[%d] by request[%d] abort", |
---|
| 663 | + scheduler->core, request->id); |
---|
654 | 664 | running_abort_count++; |
---|
655 | 665 | } |
---|
656 | 666 | } |
---|
.. | .. |
---|
683 | 693 | static void rga_request_release_abort(struct rga_request *request, int err_code) |
---|
684 | 694 | { |
---|
685 | 695 | unsigned long flags; |
---|
| 696 | + struct mm_struct *current_mm; |
---|
686 | 697 | struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager; |
---|
687 | 698 | |
---|
688 | 699 | if (rga_request_scheduler_job_abort(request) > 0) |
---|
.. | .. |
---|
697 | 708 | |
---|
698 | 709 | request->is_running = false; |
---|
699 | 710 | request->is_done = false; |
---|
700 | | - |
---|
701 | | - rga_request_put_current_mm(request); |
---|
| 711 | + current_mm = request->current_mm; |
---|
| 712 | + request->current_mm = NULL; |
---|
702 | 713 | |
---|
703 | 714 | spin_unlock_irqrestore(&request->lock, flags); |
---|
| 715 | + |
---|
| 716 | + rga_request_put_current_mm(current_mm); |
---|
704 | 717 | |
---|
705 | 718 | rga_dma_fence_signal(request->release_fence, err_code); |
---|
706 | 719 | |
---|
.. | .. |
---|
757 | 770 | } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && |
---|
758 | 771 | test_bit(RGA_JOB_STATE_FINISH, &job->state)) { |
---|
759 | 772 | spin_unlock_irqrestore(&scheduler->irq_lock, flags); |
---|
760 | | - pr_err("hardware has finished, but the software has timeout!\n"); |
---|
| 773 | + pr_err("request[%d] hardware has finished, but the software has timeout!\n", |
---|
| 774 | + request->id); |
---|
761 | 775 | return -EBUSY; |
---|
762 | 776 | } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && |
---|
763 | 777 | !test_bit(RGA_JOB_STATE_FINISH, &job->state)) { |
---|
764 | 778 | spin_unlock_irqrestore(&scheduler->irq_lock, flags); |
---|
765 | | - pr_err("hardware has timeout.\n"); |
---|
| 779 | + pr_err("request[%d] hardware has timeout.\n", request->id); |
---|
766 | 780 | return -EBUSY; |
---|
767 | 781 | } |
---|
768 | 782 | } |
---|
.. | .. |
---|
809 | 823 | struct rga_job *job; |
---|
810 | 824 | |
---|
811 | 825 | for (i = 0; i < request->task_count; i++) { |
---|
812 | | - job = rga_job_commit(&(request->task_list[i]), request); |
---|
| 826 | + struct rga_req *req = &(request->task_list[i]); |
---|
| 827 | + |
---|
| 828 | + if (DEBUGGER_EN(MSG)) { |
---|
| 829 | + pr_info("commit request[%d] task[%d]:\n", request->id, i); |
---|
| 830 | + rga_cmd_print_debug_info(req); |
---|
| 831 | + } |
---|
| 832 | + |
---|
| 833 | + job = rga_job_commit(req, request); |
---|
813 | 834 | if (IS_ERR(job)) { |
---|
814 | 835 | pr_err("request[%d] task[%d] job_commit failed.\n", request->id, i); |
---|
815 | 836 | rga_request_release_abort(request, PTR_ERR(job)); |
---|
.. | .. |
---|
830 | 851 | static void rga_request_acquire_fence_signaled_cb(struct dma_fence *fence, |
---|
831 | 852 | struct dma_fence_cb *_waiter) |
---|
832 | 853 | { |
---|
| 854 | + int ret; |
---|
| 855 | + unsigned long flags; |
---|
| 856 | + struct mm_struct *current_mm; |
---|
833 | 857 | struct rga_fence_waiter *waiter = (struct rga_fence_waiter *)_waiter; |
---|
834 | 858 | struct rga_request *request = (struct rga_request *)waiter->private; |
---|
835 | 859 | struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager; |
---|
836 | 860 | |
---|
837 | | - if (rga_request_commit(request)) |
---|
838 | | - pr_err("rga request commit failed!\n"); |
---|
| 861 | + ret = rga_request_commit(request); |
---|
| 862 | + if (ret < 0) { |
---|
| 863 | + pr_err("acquire_fence callback: rga request[%d] commit failed!\n", request->id); |
---|
| 864 | + |
---|
| 865 | + spin_lock_irqsave(&request->lock, flags); |
---|
| 866 | + |
---|
| 867 | + request->is_running = false; |
---|
| 868 | + current_mm = request->current_mm; |
---|
| 869 | + request->current_mm = NULL; |
---|
| 870 | + |
---|
| 871 | + spin_unlock_irqrestore(&request->lock, flags); |
---|
| 872 | + |
---|
| 873 | + rga_request_put_current_mm(current_mm); |
---|
| 874 | + |
---|
| 875 | + /* |
---|
| 876 | + * Since the callback is called while holding &dma_fence.lock, |
---|
| 877 | + * the _locked API is used here. |
---|
| 878 | + */ |
---|
| 879 | + if (dma_fence_get_status_locked(request->release_fence) == 0) |
---|
| 880 | + dma_fence_signal_locked(request->release_fence); |
---|
| 881 | + } |
---|
839 | 882 | |
---|
840 | 883 | mutex_lock(&request_manager->lock); |
---|
841 | 884 | rga_request_put(request); |
---|
.. | .. |
---|
848 | 891 | { |
---|
849 | 892 | struct rga_pending_request_manager *request_manager; |
---|
850 | 893 | struct rga_request *request; |
---|
| 894 | + struct mm_struct *current_mm; |
---|
851 | 895 | int finished_count, failed_count; |
---|
| 896 | + bool is_finished = false; |
---|
852 | 897 | unsigned long flags; |
---|
853 | 898 | |
---|
854 | 899 | request_manager = rga_drvdata->pend_request_manager; |
---|
.. | .. |
---|
883 | 928 | |
---|
884 | 929 | spin_unlock_irqrestore(&request->lock, flags); |
---|
885 | 930 | |
---|
886 | | - rga_job_cleanup(job); |
---|
887 | | - |
---|
888 | 931 | if ((failed_count + finished_count) >= request->task_count) { |
---|
889 | 932 | spin_lock_irqsave(&request->lock, flags); |
---|
890 | 933 | |
---|
891 | 934 | request->is_running = false; |
---|
892 | 935 | request->is_done = true; |
---|
893 | | - |
---|
894 | | - rga_request_put_current_mm(request); |
---|
| 936 | + current_mm = request->current_mm; |
---|
| 937 | + request->current_mm = NULL; |
---|
895 | 938 | |
---|
896 | 939 | spin_unlock_irqrestore(&request->lock, flags); |
---|
897 | 940 | |
---|
| 941 | + rga_request_put_current_mm(current_mm); |
---|
| 942 | + |
---|
898 | 943 | rga_dma_fence_signal(request->release_fence, request->ret); |
---|
899 | 944 | |
---|
900 | | - wake_up(&request->finished_wq); |
---|
| 945 | + is_finished = true; |
---|
901 | 946 | |
---|
902 | 947 | if (DEBUGGER_EN(MSG)) |
---|
903 | 948 | pr_info("request[%d] finished %d failed %d\n", |
---|
.. | .. |
---|
910 | 955 | } |
---|
911 | 956 | |
---|
912 | 957 | mutex_lock(&request_manager->lock); |
---|
| 958 | + |
---|
| 959 | + if (is_finished) |
---|
| 960 | + wake_up(&request->finished_wq); |
---|
| 961 | + |
---|
913 | 962 | rga_request_put(request); |
---|
| 963 | + |
---|
914 | 964 | mutex_unlock(&request_manager->lock); |
---|
| 965 | + |
---|
| 966 | + if (DEBUGGER_EN(TIME)) |
---|
| 967 | + pr_info("request[%d], job done total cost time %lld us\n", |
---|
| 968 | + job->request_id, |
---|
| 969 | + ktime_us_delta(ktime_get(), job->timestamp)); |
---|
| 970 | + |
---|
| 971 | + rga_job_cleanup(job); |
---|
915 | 972 | |
---|
916 | 973 | return 0; |
---|
917 | 974 | } |
---|
.. | .. |
---|
964 | 1021 | request->sync_mode = user_request->sync_mode; |
---|
965 | 1022 | request->mpi_config_flags = user_request->mpi_config_flags; |
---|
966 | 1023 | request->acquire_fence_fd = user_request->acquire_fence_fd; |
---|
| 1024 | + request->feature = task_list[0].feature; |
---|
967 | 1025 | |
---|
968 | 1026 | spin_unlock_irqrestore(&request->lock, flags); |
---|
969 | 1027 | |
---|
.. | .. |
---|
1041 | 1099 | int ret = 0; |
---|
1042 | 1100 | unsigned long flags; |
---|
1043 | 1101 | struct dma_fence *release_fence; |
---|
| 1102 | + struct mm_struct *current_mm; |
---|
| 1103 | + |
---|
| 1104 | + current_mm = rga_request_get_current_mm(request); |
---|
1044 | 1105 | |
---|
1045 | 1106 | spin_lock_irqsave(&request->lock, flags); |
---|
1046 | 1107 | |
---|
.. | .. |
---|
1048 | 1109 | spin_unlock_irqrestore(&request->lock, flags); |
---|
1049 | 1110 | |
---|
1050 | 1111 | pr_err("can not re-config when request is running\n"); |
---|
1051 | | - return -EFAULT; |
---|
| 1112 | + ret = -EFAULT; |
---|
| 1113 | + goto err_put_current_mm; |
---|
1052 | 1114 | } |
---|
1053 | 1115 | |
---|
1054 | 1116 | if (request->task_list == NULL) { |
---|
1055 | 1117 | spin_unlock_irqrestore(&request->lock, flags); |
---|
1056 | 1118 | |
---|
1057 | 1119 | pr_err("can not find task list from id[%d]\n", request->id); |
---|
1058 | | - return -EINVAL; |
---|
| 1120 | + ret = -EINVAL; |
---|
| 1121 | + goto err_put_current_mm; |
---|
1059 | 1122 | } |
---|
1060 | 1123 | |
---|
1061 | 1124 | /* Reset */ |
---|
.. | .. |
---|
1063 | 1126 | request->is_done = false; |
---|
1064 | 1127 | request->finished_task_count = 0; |
---|
1065 | 1128 | request->failed_task_count = 0; |
---|
1066 | | - |
---|
1067 | | - rga_request_get_current_mm(request); |
---|
| 1129 | + request->current_mm = current_mm; |
---|
1068 | 1130 | |
---|
1069 | 1131 | /* Unlock after ensuring that the current request will not be resubmitted. */ |
---|
1070 | 1132 | spin_unlock_irqrestore(&request->lock, flags); |
---|
.. | .. |
---|
1074 | 1136 | if (IS_ERR(release_fence)) { |
---|
1075 | 1137 | pr_err("Can not alloc release fence!\n"); |
---|
1076 | 1138 | ret = IS_ERR(release_fence); |
---|
1077 | | - goto error_put_current_mm; |
---|
| 1139 | + goto err_reset_request; |
---|
1078 | 1140 | } |
---|
1079 | 1141 | request->release_fence = release_fence; |
---|
1080 | 1142 | |
---|
.. | .. |
---|
1099 | 1161 | request_commit: |
---|
1100 | 1162 | ret = rga_request_commit(request); |
---|
1101 | 1163 | if (ret < 0) { |
---|
1102 | | - pr_err("rga request commit failed!\n"); |
---|
| 1164 | + pr_err("rga request[%d] commit failed!\n", request->id); |
---|
1103 | 1165 | goto err_put_release_fence; |
---|
1104 | 1166 | } |
---|
1105 | 1167 | |
---|
.. | .. |
---|
1123 | 1185 | request->release_fence = NULL; |
---|
1124 | 1186 | } |
---|
1125 | 1187 | |
---|
1126 | | -error_put_current_mm: |
---|
| 1188 | +err_reset_request: |
---|
1127 | 1189 | spin_lock_irqsave(&request->lock, flags); |
---|
1128 | 1190 | |
---|
1129 | | - rga_request_put_current_mm(request); |
---|
| 1191 | + request->current_mm = NULL; |
---|
1130 | 1192 | request->is_running = false; |
---|
1131 | 1193 | |
---|
1132 | 1194 | spin_unlock_irqrestore(&request->lock, flags); |
---|
| 1195 | + |
---|
| 1196 | +err_put_current_mm: |
---|
| 1197 | + rga_request_put_current_mm(current_mm); |
---|
1133 | 1198 | |
---|
1134 | 1199 | return ret; |
---|
1135 | 1200 | } |
---|
.. | .. |
---|
1219 | 1284 | static void rga_request_kref_release(struct kref *ref) |
---|
1220 | 1285 | { |
---|
1221 | 1286 | struct rga_request *request; |
---|
| 1287 | + struct mm_struct *current_mm; |
---|
1222 | 1288 | unsigned long flags; |
---|
1223 | 1289 | |
---|
1224 | 1290 | request = container_of(ref, struct rga_request, refcount); |
---|
.. | .. |
---|
1228 | 1294 | |
---|
1229 | 1295 | spin_lock_irqsave(&request->lock, flags); |
---|
1230 | 1296 | |
---|
1231 | | - rga_request_put_current_mm(request); |
---|
1232 | 1297 | rga_dma_fence_put(request->release_fence); |
---|
| 1298 | + current_mm = request->current_mm; |
---|
| 1299 | + request->current_mm = NULL; |
---|
1233 | 1300 | |
---|
1234 | 1301 | if (!request->is_running || request->is_done) { |
---|
1235 | 1302 | spin_unlock_irqrestore(&request->lock, flags); |
---|
| 1303 | + |
---|
| 1304 | + rga_request_put_current_mm(current_mm); |
---|
| 1305 | + |
---|
1236 | 1306 | goto free_request; |
---|
1237 | 1307 | } |
---|
1238 | 1308 | |
---|
1239 | 1309 | spin_unlock_irqrestore(&request->lock, flags); |
---|
1240 | 1310 | |
---|
| 1311 | + rga_request_put_current_mm(current_mm); |
---|
| 1312 | + |
---|
1241 | 1313 | rga_request_scheduler_job_abort(request); |
---|
1242 | 1314 | |
---|
1243 | 1315 | free_request: |
---|