| @@ -27,6 +27,7 @@ · 26 unmodified lines |
| 27 | 27 | #include <linux/pagemap.h> |
| 28 | 28 | #include <drm/drmP.h> |
| 29 | 29 | #include <drm/amdgpu_drm.h> |
| 30 | +#include <drm/drm_syncobj.h> |
| 30 | 31 | #include "amdgpu.h" |
| 31 | 32 | #include "amdgpu_trace.h" |
| 32 | 33 | |
| @@ -154,6 +155,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) · 121 unmodified lines |
| 154 | 155 | break; |
| 155 | 156 | |
| 156 | 157 | case AMDGPU_CHUNK_ID_DEPENDENCIES: |
| 158 | + case AMDGPU_CHUNK_ID_SYNCOBJ_IN: |
| 159 | + case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: |
| 157 | 160 | break; |
| 158 | 161 | |
| 159 | 162 | default: |
| @@ -682,6 +685,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo · 522 unmodified lines |
| 682 | 685 | ttm_eu_backoff_reservation(&parser->ticket, |
| 683 | 686 | &parser->validated); |
| 684 | 687 | } |
| 688 | + |
| 689 | + for (i = 0; i < parser->num_post_dep_syncobjs; i++) |
| 690 | + drm_syncobj_put(parser->post_dep_syncobjs[i]); |
| 691 | + kfree(parser->post_dep_syncobjs); |
| 692 | + |
| 685 | 693 | dma_fence_put(parser->fence); |
| 686 | 694 | |
| 687 | 695 | if (parser->ctx) |
| @@ -971,6 +979,64 @@ static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p, · 283 unmodified lines |
| 971 | 979 | return 0; |
| 972 | 980 | } |
| 973 | 981 | |
| 982 | +static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p, |
| 983 | + uint32_t handle) |
| 984 | +{ |
| 985 | + int r; |
| 986 | + struct dma_fence *fence; |
| 987 | + r = drm_syncobj_fence_get(p->filp, handle, &fence); |
| 988 | + if (r) |
| 989 | + return r; |
| 990 | + |
| 991 | + r = amdgpu_sync_fence(p->adev, &p->job->sync, fence); |
| 992 | + dma_fence_put(fence); |
| 993 | + |
| 994 | + return r; |
| 995 | +} |
| 996 | + |
| 997 | +static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p, |
| 998 | + struct amdgpu_cs_chunk *chunk) |
| 999 | +{ |
| 1000 | + unsigned num_deps; |
| 1001 | + int i, r; |
| 1002 | + struct drm_amdgpu_cs_chunk_sem *deps; |
| 1003 | + |
| 1004 | + deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata; |
| 1005 | + num_deps = chunk->length_dw * 4 / |
| 1006 | + sizeof(struct drm_amdgpu_cs_chunk_sem); |
| 1007 | + |
| 1008 | + for (i = 0; i < num_deps; ++i) { |
| 1009 | + r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle); |
| 1010 | + if (r) |
| 1011 | + return r; |
| 1012 | + } |
| 1013 | + return 0; |
| 1014 | +} |
| 1015 | + |
| 1016 | +static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p, |
| 1017 | + struct amdgpu_cs_chunk *chunk) |
| 1018 | +{ |
| 1019 | + unsigned num_deps; |
| 1020 | + int i; |
| 1021 | + struct drm_amdgpu_cs_chunk_sem *deps; |
| 1022 | + deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata; |
| 1023 | + num_deps = chunk->length_dw * 4 / |
| 1024 | + sizeof(struct drm_amdgpu_cs_chunk_sem); |
| 1025 | + |
| 1026 | + p->post_dep_syncobjs = kmalloc_array(num_deps, |
| 1027 | + sizeof(struct drm_syncobj *), |
| 1028 | + GFP_KERNEL); |
| 1029 | + p->num_post_dep_syncobjs = 0; |
| 1030 | + |
| 1031 | + for (i = 0; i < num_deps; ++i) { |
| 1032 | + p->post_dep_syncobjs[i] = drm_syncobj_find(p->filp, deps[i].handle); |
| 1033 | + if (!p->post_dep_syncobjs[i]) |
| 1034 | + return -EINVAL; |
| 1035 | + p->num_post_dep_syncobjs++; |
| 1036 | + } |
| 1037 | + return 0; |
| 1038 | +} |
| 1039 | + |
| 974 | 1040 | static int amdgpu_cs_dependencies(struct amdgpu_device *adev, |
| 975 | 1041 | struct amdgpu_cs_parser *p) |
| 976 | 1042 | { |
| @@ -985,12 +1051,30 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, · 8 unmodified lines |
| 985 | 1051 | r = amdgpu_cs_process_fence_dep(p, chunk); |
| 986 | 1052 | if (r) |
| 987 | 1053 | return r; |
| 1054 | + } else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_IN) { |
| 1055 | + r = amdgpu_cs_process_syncobj_in_dep(p, chunk); |
| 1056 | + if (r) |
| 1057 | + return r; |
| 1058 | + } else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_OUT) { |
| 1059 | + r = amdgpu_cs_process_syncobj_out_dep(p, chunk); |
| 1060 | + if (r) |
| 1061 | + return r; |
| 988 | 1062 | } |
| 989 | 1063 | } |
| 990 | 1064 | |
| 991 | 1065 | return 0; |
| 992 | 1066 | } |
| 993 | 1067 | |
| 1068 | +static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p) |
| 1069 | +{ |
| 1070 | + int i; |
| 1071 | + |
| 1072 | + for (i = 0; i < p->num_post_dep_syncobjs; ++i) { |
| 1073 | + drm_syncobj_replace_fence(p->filp, p->post_dep_syncobjs[i], |
| 1074 | + p->fence); |
| 1075 | + } |
| 1076 | +} |
| 1077 | + |
| 994 | 1078 | static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, |
| 995 | 1079 | union drm_amdgpu_cs *cs) |
| 996 | 1080 | { |
| @@ -1011,6 +1095,9 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 14 unmodified lines |
| 1011 | 1095 | job->owner = p->filp; |
| 1012 | 1096 | job->fence_ctx = entity->fence_context; |
| 1013 | 1097 | p->fence = dma_fence_get(&job->base.s_fence->finished); |
| 1098 | + |
| 1099 | + amdgpu_cs_post_dependencies(p); |
| 1100 | + |
| 1014 | 1101 | cs->out.handle = amdgpu_ctx_add_fence(p->ctx, ring, p->fence); |
| 1015 | 1102 | job->uf_sequence = cs->out.handle; |
| 1016 | 1103 | amdgpu_job_free_resources(job); |
| @@ -1018,7 +1105,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 1 unmodified line |
| 1018 | 1105 | |
| 1019 | 1106 | trace_amdgpu_cs_ioctl(job); |
| 1020 | 1107 | amd_sched_entity_push_job(&job->base); |
| 1021 | | − |
| 1022 | 1108 | return 0; |
| 1023 | 1109 | } |
| 1024 | 1110 | |