diff options
author | Christian König <christian.koenig@amd.com> | 2016-03-11 11:49:58 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-03-16 17:58:12 -0400 |
commit | d9713ef6b99e43b93bf8e73fc210d2925322eacc (patch) | |
tree | d6c2d042395613f64041a2fbdcedd4ff99fae7ce /drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | |
parent | 22e5a2f46a26adc6822c54af946b384e14930417 (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.c | 35 |
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) | |||
166 | static bool amdgpu_fence_activity(struct amdgpu_ring *ring) | 166 | static 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) |