| .. | .. |
|---|
| 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 */ |
|---|
| 540 | | - ksys_close(acquire_fence_fd); |
|---|
| 539 | + |
|---|
| 540 | + if (!request->feature.user_close_fence) { |
|---|
| 541 | + /* close acquire fence fd */ |
|---|
| 542 | +#ifdef CONFIG_NO_GKI |
|---|
| 543 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) |
|---|
| 544 | + close_fd(acquire_fence_fd); |
|---|
| 545 | +#else |
|---|
| 546 | + ksys_close(acquire_fence_fd); |
|---|
| 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 | + |
|---|
| 541 | 554 | |
|---|
| 542 | 555 | ret = rga_dma_fence_get_status(acquire_fence); |
|---|
| 543 | 556 | if (ret < 0) { |
|---|
| .. | .. |
|---|
| 646 | 659 | scheduler->ops->soft_reset(scheduler); |
|---|
| 647 | 660 | } |
|---|
| 648 | 661 | |
|---|
| 649 | | - 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); |
|---|
| 650 | 664 | running_abort_count++; |
|---|
| 651 | 665 | } |
|---|
| 652 | 666 | } |
|---|
| .. | .. |
|---|
| 679 | 693 | static void rga_request_release_abort(struct rga_request *request, int err_code) |
|---|
| 680 | 694 | { |
|---|
| 681 | 695 | unsigned long flags; |
|---|
| 696 | + struct mm_struct *current_mm; |
|---|
| 682 | 697 | struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager; |
|---|
| 683 | 698 | |
|---|
| 684 | 699 | if (rga_request_scheduler_job_abort(request) > 0) |
|---|
| .. | .. |
|---|
| 693 | 708 | |
|---|
| 694 | 709 | request->is_running = false; |
|---|
| 695 | 710 | request->is_done = false; |
|---|
| 696 | | - |
|---|
| 697 | | - rga_request_put_current_mm(request); |
|---|
| 711 | + current_mm = request->current_mm; |
|---|
| 712 | + request->current_mm = NULL; |
|---|
| 698 | 713 | |
|---|
| 699 | 714 | spin_unlock_irqrestore(&request->lock, flags); |
|---|
| 715 | + |
|---|
| 716 | + rga_request_put_current_mm(current_mm); |
|---|
| 700 | 717 | |
|---|
| 701 | 718 | rga_dma_fence_signal(request->release_fence, err_code); |
|---|
| 702 | 719 | |
|---|
| .. | .. |
|---|
| 753 | 770 | } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && |
|---|
| 754 | 771 | test_bit(RGA_JOB_STATE_FINISH, &job->state)) { |
|---|
| 755 | 772 | spin_unlock_irqrestore(&scheduler->irq_lock, flags); |
|---|
| 756 | | - 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); |
|---|
| 757 | 775 | return -EBUSY; |
|---|
| 758 | 776 | } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && |
|---|
| 759 | 777 | !test_bit(RGA_JOB_STATE_FINISH, &job->state)) { |
|---|
| 760 | 778 | spin_unlock_irqrestore(&scheduler->irq_lock, flags); |
|---|
| 761 | | - pr_err("hardware has timeout.\n"); |
|---|
| 779 | + pr_err("request[%d] hardware has timeout.\n", request->id); |
|---|
| 762 | 780 | return -EBUSY; |
|---|
| 763 | 781 | } |
|---|
| 764 | 782 | } |
|---|
| .. | .. |
|---|
| 805 | 823 | struct rga_job *job; |
|---|
| 806 | 824 | |
|---|
| 807 | 825 | for (i = 0; i < request->task_count; i++) { |
|---|
| 808 | | - 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); |
|---|
| 809 | 834 | if (IS_ERR(job)) { |
|---|
| 810 | 835 | pr_err("request[%d] task[%d] job_commit failed.\n", request->id, i); |
|---|
| 811 | 836 | rga_request_release_abort(request, PTR_ERR(job)); |
|---|
| .. | .. |
|---|
| 826 | 851 | static void rga_request_acquire_fence_signaled_cb(struct dma_fence *fence, |
|---|
| 827 | 852 | struct dma_fence_cb *_waiter) |
|---|
| 828 | 853 | { |
|---|
| 854 | + int ret; |
|---|
| 855 | + unsigned long flags; |
|---|
| 856 | + struct mm_struct *current_mm; |
|---|
| 829 | 857 | struct rga_fence_waiter *waiter = (struct rga_fence_waiter *)_waiter; |
|---|
| 830 | 858 | struct rga_request *request = (struct rga_request *)waiter->private; |
|---|
| 831 | 859 | struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager; |
|---|
| 832 | 860 | |
|---|
| 833 | | - if (rga_request_commit(request)) |
|---|
| 834 | | - 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 | + } |
|---|
| 835 | 882 | |
|---|
| 836 | 883 | mutex_lock(&request_manager->lock); |
|---|
| 837 | 884 | rga_request_put(request); |
|---|
| .. | .. |
|---|
| 844 | 891 | { |
|---|
| 845 | 892 | struct rga_pending_request_manager *request_manager; |
|---|
| 846 | 893 | struct rga_request *request; |
|---|
| 894 | + struct mm_struct *current_mm; |
|---|
| 847 | 895 | int finished_count, failed_count; |
|---|
| 896 | + bool is_finished = false; |
|---|
| 848 | 897 | unsigned long flags; |
|---|
| 849 | 898 | |
|---|
| 850 | 899 | request_manager = rga_drvdata->pend_request_manager; |
|---|
| .. | .. |
|---|
| 879 | 928 | |
|---|
| 880 | 929 | spin_unlock_irqrestore(&request->lock, flags); |
|---|
| 881 | 930 | |
|---|
| 882 | | - rga_job_cleanup(job); |
|---|
| 883 | | - |
|---|
| 884 | 931 | if ((failed_count + finished_count) >= request->task_count) { |
|---|
| 885 | 932 | spin_lock_irqsave(&request->lock, flags); |
|---|
| 886 | 933 | |
|---|
| 887 | 934 | request->is_running = false; |
|---|
| 888 | 935 | request->is_done = true; |
|---|
| 889 | | - |
|---|
| 890 | | - rga_request_put_current_mm(request); |
|---|
| 936 | + current_mm = request->current_mm; |
|---|
| 937 | + request->current_mm = NULL; |
|---|
| 891 | 938 | |
|---|
| 892 | 939 | spin_unlock_irqrestore(&request->lock, flags); |
|---|
| 893 | 940 | |
|---|
| 941 | + rga_request_put_current_mm(current_mm); |
|---|
| 942 | + |
|---|
| 894 | 943 | rga_dma_fence_signal(request->release_fence, request->ret); |
|---|
| 895 | 944 | |
|---|
| 896 | | - wake_up(&request->finished_wq); |
|---|
| 945 | + is_finished = true; |
|---|
| 897 | 946 | |
|---|
| 898 | 947 | if (DEBUGGER_EN(MSG)) |
|---|
| 899 | 948 | pr_info("request[%d] finished %d failed %d\n", |
|---|
| .. | .. |
|---|
| 906 | 955 | } |
|---|
| 907 | 956 | |
|---|
| 908 | 957 | mutex_lock(&request_manager->lock); |
|---|
| 958 | + |
|---|
| 959 | + if (is_finished) |
|---|
| 960 | + wake_up(&request->finished_wq); |
|---|
| 961 | + |
|---|
| 909 | 962 | rga_request_put(request); |
|---|
| 963 | + |
|---|
| 910 | 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); |
|---|
| 911 | 972 | |
|---|
| 912 | 973 | return 0; |
|---|
| 913 | 974 | } |
|---|
| .. | .. |
|---|
| 960 | 1021 | request->sync_mode = user_request->sync_mode; |
|---|
| 961 | 1022 | request->mpi_config_flags = user_request->mpi_config_flags; |
|---|
| 962 | 1023 | request->acquire_fence_fd = user_request->acquire_fence_fd; |
|---|
| 1024 | + request->feature = task_list[0].feature; |
|---|
| 963 | 1025 | |
|---|
| 964 | 1026 | spin_unlock_irqrestore(&request->lock, flags); |
|---|
| 965 | 1027 | |
|---|
| .. | .. |
|---|
| 1037 | 1099 | int ret = 0; |
|---|
| 1038 | 1100 | unsigned long flags; |
|---|
| 1039 | 1101 | struct dma_fence *release_fence; |
|---|
| 1102 | + struct mm_struct *current_mm; |
|---|
| 1103 | + |
|---|
| 1104 | + current_mm = rga_request_get_current_mm(request); |
|---|
| 1040 | 1105 | |
|---|
| 1041 | 1106 | spin_lock_irqsave(&request->lock, flags); |
|---|
| 1042 | 1107 | |
|---|
| .. | .. |
|---|
| 1044 | 1109 | spin_unlock_irqrestore(&request->lock, flags); |
|---|
| 1045 | 1110 | |
|---|
| 1046 | 1111 | pr_err("can not re-config when request is running\n"); |
|---|
| 1047 | | - return -EFAULT; |
|---|
| 1112 | + ret = -EFAULT; |
|---|
| 1113 | + goto err_put_current_mm; |
|---|
| 1048 | 1114 | } |
|---|
| 1049 | 1115 | |
|---|
| 1050 | 1116 | if (request->task_list == NULL) { |
|---|
| 1051 | 1117 | spin_unlock_irqrestore(&request->lock, flags); |
|---|
| 1052 | 1118 | |
|---|
| 1053 | 1119 | pr_err("can not find task list from id[%d]\n", request->id); |
|---|
| 1054 | | - return -EINVAL; |
|---|
| 1120 | + ret = -EINVAL; |
|---|
| 1121 | + goto err_put_current_mm; |
|---|
| 1055 | 1122 | } |
|---|
| 1056 | 1123 | |
|---|
| 1057 | 1124 | /* Reset */ |
|---|
| .. | .. |
|---|
| 1059 | 1126 | request->is_done = false; |
|---|
| 1060 | 1127 | request->finished_task_count = 0; |
|---|
| 1061 | 1128 | request->failed_task_count = 0; |
|---|
| 1062 | | - |
|---|
| 1063 | | - rga_request_get_current_mm(request); |
|---|
| 1129 | + request->current_mm = current_mm; |
|---|
| 1064 | 1130 | |
|---|
| 1065 | 1131 | /* Unlock after ensuring that the current request will not be resubmitted. */ |
|---|
| 1066 | 1132 | spin_unlock_irqrestore(&request->lock, flags); |
|---|
| .. | .. |
|---|
| 1070 | 1136 | if (IS_ERR(release_fence)) { |
|---|
| 1071 | 1137 | pr_err("Can not alloc release fence!\n"); |
|---|
| 1072 | 1138 | ret = IS_ERR(release_fence); |
|---|
| 1073 | | - goto error_put_current_mm; |
|---|
| 1139 | + goto err_reset_request; |
|---|
| 1074 | 1140 | } |
|---|
| 1075 | 1141 | request->release_fence = release_fence; |
|---|
| 1076 | 1142 | |
|---|
| .. | .. |
|---|
| 1095 | 1161 | request_commit: |
|---|
| 1096 | 1162 | ret = rga_request_commit(request); |
|---|
| 1097 | 1163 | if (ret < 0) { |
|---|
| 1098 | | - pr_err("rga request commit failed!\n"); |
|---|
| 1164 | + pr_err("rga request[%d] commit failed!\n", request->id); |
|---|
| 1099 | 1165 | goto err_put_release_fence; |
|---|
| 1100 | 1166 | } |
|---|
| 1101 | 1167 | |
|---|
| .. | .. |
|---|
| 1119 | 1185 | request->release_fence = NULL; |
|---|
| 1120 | 1186 | } |
|---|
| 1121 | 1187 | |
|---|
| 1122 | | -error_put_current_mm: |
|---|
| 1188 | +err_reset_request: |
|---|
| 1123 | 1189 | spin_lock_irqsave(&request->lock, flags); |
|---|
| 1124 | 1190 | |
|---|
| 1125 | | - rga_request_put_current_mm(request); |
|---|
| 1191 | + request->current_mm = NULL; |
|---|
| 1126 | 1192 | request->is_running = false; |
|---|
| 1127 | 1193 | |
|---|
| 1128 | 1194 | spin_unlock_irqrestore(&request->lock, flags); |
|---|
| 1195 | + |
|---|
| 1196 | +err_put_current_mm: |
|---|
| 1197 | + rga_request_put_current_mm(current_mm); |
|---|
| 1129 | 1198 | |
|---|
| 1130 | 1199 | return ret; |
|---|
| 1131 | 1200 | } |
|---|
| .. | .. |
|---|
| 1215 | 1284 | static void rga_request_kref_release(struct kref *ref) |
|---|
| 1216 | 1285 | { |
|---|
| 1217 | 1286 | struct rga_request *request; |
|---|
| 1287 | + struct mm_struct *current_mm; |
|---|
| 1218 | 1288 | unsigned long flags; |
|---|
| 1219 | 1289 | |
|---|
| 1220 | 1290 | request = container_of(ref, struct rga_request, refcount); |
|---|
| .. | .. |
|---|
| 1224 | 1294 | |
|---|
| 1225 | 1295 | spin_lock_irqsave(&request->lock, flags); |
|---|
| 1226 | 1296 | |
|---|
| 1227 | | - rga_request_put_current_mm(request); |
|---|
| 1228 | 1297 | rga_dma_fence_put(request->release_fence); |
|---|
| 1298 | + current_mm = request->current_mm; |
|---|
| 1299 | + request->current_mm = NULL; |
|---|
| 1229 | 1300 | |
|---|
| 1230 | 1301 | if (!request->is_running || request->is_done) { |
|---|
| 1231 | 1302 | spin_unlock_irqrestore(&request->lock, flags); |
|---|
| 1303 | + |
|---|
| 1304 | + rga_request_put_current_mm(current_mm); |
|---|
| 1305 | + |
|---|
| 1232 | 1306 | goto free_request; |
|---|
| 1233 | 1307 | } |
|---|
| 1234 | 1308 | |
|---|
| 1235 | 1309 | spin_unlock_irqrestore(&request->lock, flags); |
|---|
| 1236 | 1310 | |
|---|
| 1311 | + rga_request_put_current_mm(current_mm); |
|---|
| 1312 | + |
|---|
| 1237 | 1313 | rga_request_scheduler_job_abort(request); |
|---|
| 1238 | 1314 | |
|---|
| 1239 | 1315 | free_request: |
|---|