diff options
author | Oak Zeng <Oak.Zeng@amd.com> | 2018-09-05 23:51:23 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-09-12 17:28:53 -0400 |
commit | 240cd9a64226e013ac1a608ebf720a1813790196 (patch) | |
tree | de0ab86452ec57fc396591708230ee549e98bac4 /drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | |
parent | 7e7bf8de432db3de912050856e641458de72a7b1 (diff) |
drm/amdgpu: Move fault hash table to amdgpu vm
In stead of share one fault hash table per device, make it
per vm. This can avoid inter-process lock issue when fault
hash table is full.
Change-Id: I5d1281b7c41eddc8e26113e010516557588d3708
Signed-off-by: Oak Zeng <Oak.Zeng@amd.com>
Suggested-by: Christian Konig <Christian.Koenig@amd.com>
Suggested-by: Felix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: Christian Konig <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 75 |
1 files changed, 0 insertions, 75 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index 06373d44b3da..4ed86218cef3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | |||
@@ -197,78 +197,3 @@ restart_ih: | |||
197 | return IRQ_HANDLED; | 197 | return IRQ_HANDLED; |
198 | } | 198 | } |
199 | 199 | ||
200 | /** | ||
201 | * amdgpu_ih_add_fault - Add a page fault record | ||
202 | * | ||
203 | * @adev: amdgpu device pointer | ||
204 | * @key: 64-bit encoding of PASID and address | ||
205 | * | ||
206 | * This should be called when a retry page fault interrupt is | ||
207 | * received. If this is a new page fault, it will be added to a hash | ||
208 | * table. The return value indicates whether this is a new fault, or | ||
209 | * a fault that was already known and is already being handled. | ||
210 | * | ||
211 | * If there are too many pending page faults, this will fail. Retry | ||
212 | * interrupts should be ignored in this case until there is enough | ||
213 | * free space. | ||
214 | * | ||
215 | * Returns 0 if the fault was added, 1 if the fault was already known, | ||
216 | * -ENOSPC if there are too many pending faults. | ||
217 | */ | ||
218 | int amdgpu_ih_add_fault(struct amdgpu_device *adev, u64 key) | ||
219 | { | ||
220 | unsigned long flags; | ||
221 | int r = -ENOSPC; | ||
222 | |||
223 | if (WARN_ON_ONCE(!adev->irq.ih.faults)) | ||
224 | /* Should be allocated in <IP>_ih_sw_init on GPUs that | ||
225 | * support retry faults and require retry filtering. | ||
226 | */ | ||
227 | return r; | ||
228 | |||
229 | spin_lock_irqsave(&adev->irq.ih.faults->lock, flags); | ||
230 | |||
231 | /* Only let the hash table fill up to 50% for best performance */ | ||
232 | if (adev->irq.ih.faults->count >= (1 << (AMDGPU_PAGEFAULT_HASH_BITS-1))) | ||
233 | goto unlock_out; | ||
234 | |||
235 | r = chash_table_copy_in(&adev->irq.ih.faults->hash, key, NULL); | ||
236 | if (!r) | ||
237 | adev->irq.ih.faults->count++; | ||
238 | |||
239 | /* chash_table_copy_in should never fail unless we're losing count */ | ||
240 | WARN_ON_ONCE(r < 0); | ||
241 | |||
242 | unlock_out: | ||
243 | spin_unlock_irqrestore(&adev->irq.ih.faults->lock, flags); | ||
244 | return r; | ||
245 | } | ||
246 | |||
247 | /** | ||
248 | * amdgpu_ih_clear_fault - Remove a page fault record | ||
249 | * | ||
250 | * @adev: amdgpu device pointer | ||
251 | * @key: 64-bit encoding of PASID and address | ||
252 | * | ||
253 | * This should be called when a page fault has been handled. Any | ||
254 | * future interrupt with this key will be processed as a new | ||
255 | * page fault. | ||
256 | */ | ||
257 | void amdgpu_ih_clear_fault(struct amdgpu_device *adev, u64 key) | ||
258 | { | ||
259 | unsigned long flags; | ||
260 | int r; | ||
261 | |||
262 | if (!adev->irq.ih.faults) | ||
263 | return; | ||
264 | |||
265 | spin_lock_irqsave(&adev->irq.ih.faults->lock, flags); | ||
266 | |||
267 | r = chash_table_remove(&adev->irq.ih.faults->hash, key, NULL); | ||
268 | if (!WARN_ON_ONCE(r < 0)) { | ||
269 | adev->irq.ih.faults->count--; | ||
270 | WARN_ON_ONCE(adev->irq.ih.faults->count < 0); | ||
271 | } | ||
272 | |||
273 | spin_unlock_irqrestore(&adev->irq.ih.faults->lock, flags); | ||
274 | } | ||