diff options
author | Christian König <christian.koenig@amd.com> | 2015-05-11 09:34:59 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-06-03 21:03:34 -0400 |
commit | 3cb485f34049b7f3a00f6f73d2325e0858f64ddb (patch) | |
tree | ed523717c68630c27010a39d112b360492b23c93 /drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |
parent | d919ad49ac04e1e417ea511d61455786a0f0fdb7 (diff) |
drm/amdgpu: fix context switch
Properly protect the state and also handle submission failures.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com>
Reviewed-by: Monk Liu <monk.liu@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 74ed94ee7102..560c5fd347be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |||
@@ -140,6 +140,7 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, | |||
140 | { | 140 | { |
141 | struct amdgpu_ib *ib = &ibs[0]; | 141 | struct amdgpu_ib *ib = &ibs[0]; |
142 | struct amdgpu_ring *ring; | 142 | struct amdgpu_ring *ring; |
143 | struct amdgpu_ctx *ctx, *old_ctx; | ||
143 | struct amdgpu_vm *vm; | 144 | struct amdgpu_vm *vm; |
144 | unsigned i; | 145 | unsigned i; |
145 | int r = 0; | 146 | int r = 0; |
@@ -148,6 +149,7 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, | |||
148 | return -EINVAL; | 149 | return -EINVAL; |
149 | 150 | ||
150 | ring = ibs->ring; | 151 | ring = ibs->ring; |
152 | ctx = ibs->ctx; | ||
151 | vm = ibs->vm; | 153 | vm = ibs->vm; |
152 | 154 | ||
153 | if (!ring->ready) { | 155 | if (!ring->ready) { |
@@ -189,19 +191,23 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, | |||
189 | if (ring->funcs->emit_hdp_flush) | 191 | if (ring->funcs->emit_hdp_flush) |
190 | amdgpu_ring_emit_hdp_flush(ring); | 192 | amdgpu_ring_emit_hdp_flush(ring); |
191 | 193 | ||
194 | old_ctx = ring->current_ctx; | ||
192 | for (i = 0; i < num_ibs; ++i) { | 195 | for (i = 0; i < num_ibs; ++i) { |
193 | ib = &ibs[i]; | 196 | ib = &ibs[i]; |
194 | 197 | ||
195 | if (ib->ring != ring) { | 198 | if (ib->ring != ring || ib->ctx != ctx || ib->vm != vm) { |
199 | ring->current_ctx = old_ctx; | ||
196 | amdgpu_ring_unlock_undo(ring); | 200 | amdgpu_ring_unlock_undo(ring); |
197 | return -EINVAL; | 201 | return -EINVAL; |
198 | } | 202 | } |
199 | amdgpu_ring_emit_ib(ring, ib); | 203 | amdgpu_ring_emit_ib(ring, ib); |
204 | ring->current_ctx = ctx; | ||
200 | } | 205 | } |
201 | 206 | ||
202 | r = amdgpu_fence_emit(ring, owner, &ib->fence); | 207 | r = amdgpu_fence_emit(ring, owner, &ib->fence); |
203 | if (r) { | 208 | if (r) { |
204 | dev_err(adev->dev, "failed to emit fence (%d)\n", r); | 209 | dev_err(adev->dev, "failed to emit fence (%d)\n", r); |
210 | ring->current_ctx = old_ctx; | ||
205 | amdgpu_ring_unlock_undo(ring); | 211 | amdgpu_ring_unlock_undo(ring); |
206 | return r; | 212 | return r; |
207 | } | 213 | } |