aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Grodzovsky <andrey.grodzovsky@amd.com>2017-10-10 16:50:16 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-10-19 15:26:58 -0400
commitad864d243826cedc53404a1c0db7d1e38ddceb84 (patch)
tree1a77151d8588c460b26fb2d91d1dec0066d9d37e
parentf15507a1ac0dcdbda0c6c4fe4dc168bfe0034535 (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.c112
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) {