diff options
author | Andrey Grodzovsky <andrey.grodzovsky@amd.com> | 2017-10-10 16:50:16 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-10-19 15:26:58 -0400 |
commit | ad864d243826cedc53404a1c0db7d1e38ddceb84 (patch) | |
tree | 1a77151d8588c460b26fb2d91d1dec0066d9d37e | |
parent | f15507a1ac0dcdbda0c6c4fe4dc168bfe0034535 (diff) |
drm/amdgpu: Refactor amdgpu_cs_ib_vm_chunk and amdgpu_cs_ib_fill.
This enables old fence waiting before reservation lock is aquired
which in turn is part of a bigger solution to deadlock happening
when gpu reset with VRAM recovery accures during intensive rendering.
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 112 |
1 files changed, 61 insertions, 51 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index fe7dd44ac9fe..9166d5e1e557 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -845,15 +845,60 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, | |||
845 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; | 845 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; |
846 | struct amdgpu_vm *vm = &fpriv->vm; | 846 | struct amdgpu_vm *vm = &fpriv->vm; |
847 | struct amdgpu_ring *ring = p->job->ring; | 847 | struct amdgpu_ring *ring = p->job->ring; |
848 | int i, r; | 848 | int i, j, r; |
849 | |||
850 | for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) { | ||
851 | |||
852 | struct amdgpu_cs_chunk *chunk; | ||
853 | struct amdgpu_ib *ib; | ||
854 | struct drm_amdgpu_cs_chunk_ib *chunk_ib; | ||
855 | |||
856 | chunk = &p->chunks[i]; | ||
857 | ib = &p->job->ibs[j]; | ||
858 | chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata; | ||
859 | |||
860 | if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) | ||
861 | continue; | ||
862 | |||
863 | if (p->job->ring->funcs->parse_cs) { | ||
864 | struct amdgpu_bo_va_mapping *m; | ||
865 | struct amdgpu_bo *aobj = NULL; | ||
866 | uint64_t offset; | ||
867 | uint8_t *kptr; | ||
868 | |||
869 | r = amdgpu_cs_find_mapping(p, chunk_ib->va_start, | ||
870 | &aobj, &m); | ||
871 | if (r) { | ||
872 | DRM_ERROR("IB va_start is invalid\n"); | ||
873 | return r; | ||
874 | } | ||
849 | 875 | ||
850 | /* Only for UVD/VCE VM emulation */ | 876 | if ((chunk_ib->va_start + chunk_ib->ib_bytes) > |
851 | if (ring->funcs->parse_cs) { | 877 | (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) { |
852 | for (i = 0; i < p->job->num_ibs; i++) { | 878 | DRM_ERROR("IB va_start+ib_bytes is invalid\n"); |
853 | r = amdgpu_ring_parse_cs(ring, p, i); | 879 | return -EINVAL; |
880 | } | ||
881 | |||
882 | /* the IB should be reserved at this point */ | ||
883 | r = amdgpu_bo_kmap(aobj, (void **)&kptr); | ||
884 | if (r) { | ||
885 | return r; | ||
886 | } | ||
887 | |||
888 | offset = m->start * AMDGPU_GPU_PAGE_SIZE; | ||
889 | kptr += chunk_ib->va_start - offset; | ||
890 | |||
891 | memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); | ||
892 | amdgpu_bo_kunmap(aobj); | ||
893 | |||
894 | /* Only for UVD/VCE VM emulation */ | ||
895 | r = amdgpu_ring_parse_cs(ring, p, j); | ||
854 | if (r) | 896 | if (r) |
855 | return r; | 897 | return r; |
898 | |||
856 | } | 899 | } |
900 | |||
901 | j++; | ||
857 | } | 902 | } |
858 | 903 | ||
859 | if (p->job->vm) { | 904 | if (p->job->vm) { |
@@ -919,54 +964,18 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, | |||
919 | 964 | ||
920 | parser->job->ring = ring; | 965 | parser->job->ring = ring; |
921 | 966 | ||
922 | if (ring->funcs->parse_cs) { | 967 | r = amdgpu_ib_get(adev, vm, |
923 | struct amdgpu_bo_va_mapping *m; | 968 | ring->funcs->parse_cs ? chunk_ib->ib_bytes : 0, |
924 | struct amdgpu_bo *aobj = NULL; | 969 | ib); |
925 | uint64_t offset; | 970 | if (r) { |
926 | uint8_t *kptr; | 971 | DRM_ERROR("Failed to get ib !\n"); |
927 | 972 | return r; | |
928 | r = amdgpu_cs_find_mapping(parser, chunk_ib->va_start, | ||
929 | &aobj, &m); | ||
930 | if (r) { | ||
931 | DRM_ERROR("IB va_start is invalid\n"); | ||
932 | return r; | ||
933 | } | ||
934 | |||
935 | if ((chunk_ib->va_start + chunk_ib->ib_bytes) > | ||
936 | (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) { | ||
937 | DRM_ERROR("IB va_start+ib_bytes is invalid\n"); | ||
938 | return -EINVAL; | ||
939 | } | ||
940 | |||
941 | /* the IB should be reserved at this point */ | ||
942 | r = amdgpu_bo_kmap(aobj, (void **)&kptr); | ||
943 | if (r) { | ||
944 | return r; | ||
945 | } | ||
946 | |||
947 | offset = m->start * AMDGPU_GPU_PAGE_SIZE; | ||
948 | kptr += chunk_ib->va_start - offset; | ||
949 | |||
950 | r = amdgpu_ib_get(adev, vm, chunk_ib->ib_bytes, ib); | ||
951 | if (r) { | ||
952 | DRM_ERROR("Failed to get ib !\n"); | ||
953 | return r; | ||
954 | } | ||
955 | |||
956 | memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); | ||
957 | amdgpu_bo_kunmap(aobj); | ||
958 | } else { | ||
959 | r = amdgpu_ib_get(adev, vm, 0, ib); | ||
960 | if (r) { | ||
961 | DRM_ERROR("Failed to get ib !\n"); | ||
962 | return r; | ||
963 | } | ||
964 | |||
965 | } | 973 | } |
966 | 974 | ||
967 | ib->gpu_addr = chunk_ib->va_start; | 975 | ib->gpu_addr = chunk_ib->va_start; |
968 | ib->length_dw = chunk_ib->ib_bytes / 4; | 976 | ib->length_dw = chunk_ib->ib_bytes / 4; |
969 | ib->flags = chunk_ib->flags; | 977 | ib->flags = chunk_ib->flags; |
978 | |||
970 | j++; | 979 | j++; |
971 | } | 980 | } |
972 | 981 | ||
@@ -1212,6 +1221,10 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
1212 | goto out; | 1221 | goto out; |
1213 | } | 1222 | } |
1214 | 1223 | ||
1224 | r = amdgpu_cs_ib_fill(adev, &parser); | ||
1225 | if (r) | ||
1226 | goto out; | ||
1227 | |||
1215 | r = amdgpu_cs_parser_bos(&parser, data); | 1228 | r = amdgpu_cs_parser_bos(&parser, data); |
1216 | if (r) { | 1229 | if (r) { |
1217 | if (r == -ENOMEM) | 1230 | if (r == -ENOMEM) |
@@ -1222,9 +1235,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
1222 | } | 1235 | } |
1223 | 1236 | ||
1224 | reserved_buffers = true; | 1237 | reserved_buffers = true; |
1225 | r = amdgpu_cs_ib_fill(adev, &parser); | ||
1226 | if (r) | ||
1227 | goto out; | ||
1228 | 1238 | ||
1229 | r = amdgpu_cs_dependencies(adev, &parser); | 1239 | r = amdgpu_cs_dependencies(adev, &parser); |
1230 | if (r) { | 1240 | if (r) { |