aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-03-11 11:49:58 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-03-16 17:58:12 -0400
commitd9713ef6b99e43b93bf8e73fc210d2925322eacc (patch)
treed6c2d042395613f64041a2fbdcedd4ff99fae7ce /drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
parent22e5a2f46a26adc6822c54af946b384e14930417 (diff)
drm/amdgpu: cleanup amdgpu_fence_activity
The comment about the loop counter was never valid, even when you have multiple threads this loop only runs as long as the sequence increases. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c35
1 files changed, 3 insertions, 32 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 3db18f42c5c9..35fbc8874514 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -166,30 +166,8 @@ static void amdgpu_fence_schedule_fallback(struct amdgpu_ring *ring)
166static bool amdgpu_fence_activity(struct amdgpu_ring *ring) 166static bool amdgpu_fence_activity(struct amdgpu_ring *ring)
167{ 167{
168 uint64_t seq, last_seq, last_emitted; 168 uint64_t seq, last_seq, last_emitted;
169 unsigned count_loop = 0;
170 bool wake = false; 169 bool wake = false;
171 170
172 /* Note there is a scenario here for an infinite loop but it's
173 * very unlikely to happen. For it to happen, the current polling
174 * process need to be interrupted by another process and another
175 * process needs to update the last_seq btw the atomic read and
176 * xchg of the current process.
177 *
178 * More over for this to go in infinite loop there need to be
179 * continuously new fence signaled ie amdgpu_fence_read needs
180 * to return a different value each time for both the currently
181 * polling process and the other process that xchg the last_seq
182 * btw atomic read and xchg of the current process. And the
183 * value the other process set as last seq must be higher than
184 * the seq value we just read. Which means that current process
185 * need to be interrupted after amdgpu_fence_read and before
186 * atomic xchg.
187 *
188 * To be even more safe we count the number of time we loop and
189 * we bail after 10 loop just accepting the fact that we might
190 * have temporarly set the last_seq not to the true real last
191 * seq but to an older one.
192 */
193 last_seq = atomic64_read(&ring->fence_drv.last_seq); 171 last_seq = atomic64_read(&ring->fence_drv.last_seq);
194 do { 172 do {
195 last_emitted = ring->fence_drv.sync_seq; 173 last_emitted = ring->fence_drv.sync_seq;
@@ -200,23 +178,16 @@ static bool amdgpu_fence_activity(struct amdgpu_ring *ring)
200 seq |= last_emitted & 0xffffffff00000000LL; 178 seq |= last_emitted & 0xffffffff00000000LL;
201 } 179 }
202 180
203 if (seq <= last_seq || seq > last_emitted) { 181 if (seq <= last_seq || seq > last_emitted)
204 break; 182 break;
205 } 183
206 /* If we loop over we don't want to return without 184 /* If we loop over we don't want to return without
207 * checking if a fence is signaled as it means that the 185 * checking if a fence is signaled as it means that the
208 * seq we just read is different from the previous on. 186 * seq we just read is different from the previous on.
209 */ 187 */
210 wake = true; 188 wake = true;
211 last_seq = seq; 189 last_seq = seq;
212 if ((count_loop++) > 10) { 190
213 /* We looped over too many time leave with the
214 * fact that we might have set an older fence
215 * seq then the current real last seq as signaled
216 * by the hw.
217 */
218 break;
219 }
220 } while (atomic64_xchg(&ring->fence_drv.last_seq, seq) > seq); 191 } while (atomic64_xchg(&ring->fence_drv.last_seq, seq) > seq);
221 192
222 if (seq < last_emitted) 193 if (seq < last_emitted)