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 | |
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')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 75 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 102 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 38 |
5 files changed, 128 insertions, 111 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 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h index a23e1c0bed93..0d5b3f5201d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | |||
@@ -24,7 +24,6 @@ | |||
24 | #ifndef __AMDGPU_IH_H__ | 24 | #ifndef __AMDGPU_IH_H__ |
25 | #define __AMDGPU_IH_H__ | 25 | #define __AMDGPU_IH_H__ |
26 | 26 | ||
27 | #include <linux/chash.h> | ||
28 | #include "soc15_ih_clientid.h" | 27 | #include "soc15_ih_clientid.h" |
29 | 28 | ||
30 | struct amdgpu_device; | 29 | struct amdgpu_device; |
@@ -32,13 +31,6 @@ struct amdgpu_device; | |||
32 | #define AMDGPU_IH_CLIENTID_LEGACY 0 | 31 | #define AMDGPU_IH_CLIENTID_LEGACY 0 |
33 | #define AMDGPU_IH_CLIENTID_MAX SOC15_IH_CLIENTID_MAX | 32 | #define AMDGPU_IH_CLIENTID_MAX SOC15_IH_CLIENTID_MAX |
34 | 33 | ||
35 | #define AMDGPU_PAGEFAULT_HASH_BITS 8 | ||
36 | struct amdgpu_retryfault_hashtable { | ||
37 | DECLARE_CHASH_TABLE(hash, AMDGPU_PAGEFAULT_HASH_BITS, 8, 0); | ||
38 | spinlock_t lock; | ||
39 | int count; | ||
40 | }; | ||
41 | |||
42 | /* | 34 | /* |
43 | * R6xx+ IH ring | 35 | * R6xx+ IH ring |
44 | */ | 36 | */ |
@@ -57,7 +49,6 @@ struct amdgpu_ih_ring { | |||
57 | bool use_doorbell; | 49 | bool use_doorbell; |
58 | bool use_bus_addr; | 50 | bool use_bus_addr; |
59 | dma_addr_t rb_dma_addr; /* only used when use_bus_addr = true */ | 51 | dma_addr_t rb_dma_addr; /* only used when use_bus_addr = true */ |
60 | struct amdgpu_retryfault_hashtable *faults; | ||
61 | }; | 52 | }; |
62 | 53 | ||
63 | #define AMDGPU_IH_SRC_DATA_MAX_SIZE_DW 4 | 54 | #define AMDGPU_IH_SRC_DATA_MAX_SIZE_DW 4 |
@@ -95,7 +86,5 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, | |||
95 | bool use_bus_addr); | 86 | bool use_bus_addr); |
96 | void amdgpu_ih_ring_fini(struct amdgpu_device *adev); | 87 | void amdgpu_ih_ring_fini(struct amdgpu_device *adev); |
97 | int amdgpu_ih_process(struct amdgpu_device *adev); | 88 | int amdgpu_ih_process(struct amdgpu_device *adev); |
98 | int amdgpu_ih_add_fault(struct amdgpu_device *adev, u64 key); | ||
99 | void amdgpu_ih_clear_fault(struct amdgpu_device *adev, u64 key); | ||
100 | 89 | ||
101 | #endif | 90 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 136b00412dc8..be1659fedf94 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -2717,6 +2717,22 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size, | |||
2717 | adev->vm_manager.fragment_size); | 2717 | adev->vm_manager.fragment_size); |
2718 | } | 2718 | } |
2719 | 2719 | ||
2720 | static struct amdgpu_retryfault_hashtable *init_fault_hash(void) | ||
2721 | { | ||
2722 | struct amdgpu_retryfault_hashtable *fault_hash; | ||
2723 | |||
2724 | fault_hash = kmalloc(sizeof(*fault_hash), GFP_KERNEL); | ||
2725 | if (!fault_hash) | ||
2726 | return fault_hash; | ||
2727 | |||
2728 | INIT_CHASH_TABLE(fault_hash->hash, | ||
2729 | AMDGPU_PAGEFAULT_HASH_BITS, 8, 0); | ||
2730 | spin_lock_init(&fault_hash->lock); | ||
2731 | fault_hash->count = 0; | ||
2732 | |||
2733 | return fault_hash; | ||
2734 | } | ||
2735 | |||
2720 | /** | 2736 | /** |
2721 | * amdgpu_vm_init - initialize a vm instance | 2737 | * amdgpu_vm_init - initialize a vm instance |
2722 | * | 2738 | * |
@@ -2805,6 +2821,12 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
2805 | vm->pasid = pasid; | 2821 | vm->pasid = pasid; |
2806 | } | 2822 | } |
2807 | 2823 | ||
2824 | vm->fault_hash = init_fault_hash(); | ||
2825 | if (!vm->fault_hash) { | ||
2826 | r = -ENOMEM; | ||
2827 | goto error_free_root; | ||
2828 | } | ||
2829 | |||
2808 | INIT_KFIFO(vm->faults); | 2830 | INIT_KFIFO(vm->faults); |
2809 | vm->fault_credit = 16; | 2831 | vm->fault_credit = 16; |
2810 | 2832 | ||
@@ -2998,7 +3020,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
2998 | 3020 | ||
2999 | /* Clear pending page faults from IH when the VM is destroyed */ | 3021 | /* Clear pending page faults from IH when the VM is destroyed */ |
3000 | while (kfifo_get(&vm->faults, &fault)) | 3022 | while (kfifo_get(&vm->faults, &fault)) |
3001 | amdgpu_ih_clear_fault(adev, fault); | 3023 | amdgpu_vm_clear_fault(vm->fault_hash, fault); |
3002 | 3024 | ||
3003 | if (vm->pasid) { | 3025 | if (vm->pasid) { |
3004 | unsigned long flags; | 3026 | unsigned long flags; |
@@ -3008,6 +3030,9 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
3008 | spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); | 3030 | spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); |
3009 | } | 3031 | } |
3010 | 3032 | ||
3033 | kfree(vm->fault_hash); | ||
3034 | vm->fault_hash = NULL; | ||
3035 | |||
3011 | drm_sched_entity_destroy(&vm->entity); | 3036 | drm_sched_entity_destroy(&vm->entity); |
3012 | 3037 | ||
3013 | if (!RB_EMPTY_ROOT(&vm->va.rb_root)) { | 3038 | if (!RB_EMPTY_ROOT(&vm->va.rb_root)) { |
@@ -3208,3 +3233,78 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm) | |||
3208 | } | 3233 | } |
3209 | } | 3234 | } |
3210 | } | 3235 | } |
3236 | |||
3237 | /** | ||
3238 | * amdgpu_vm_add_fault - Add a page fault record to fault hash table | ||
3239 | * | ||
3240 | * @fault_hash: fault hash table | ||
3241 | * @key: 64-bit encoding of PASID and address | ||
3242 | * | ||
3243 | * This should be called when a retry page fault interrupt is | ||
3244 | * received. If this is a new page fault, it will be added to a hash | ||
3245 | * table. The return value indicates whether this is a new fault, or | ||
3246 | * a fault that was already known and is already being handled. | ||
3247 | * | ||
3248 | * If there are too many pending page faults, this will fail. Retry | ||
3249 | * interrupts should be ignored in this case until there is enough | ||
3250 | * free space. | ||
3251 | * | ||
3252 | * Returns 0 if the fault was added, 1 if the fault was already known, | ||
3253 | * -ENOSPC if there are too many pending faults. | ||
3254 | */ | ||
3255 | int amdgpu_vm_add_fault(struct amdgpu_retryfault_hashtable *fault_hash, u64 key) | ||
3256 | { | ||
3257 | unsigned long flags; | ||
3258 | int r = -ENOSPC; | ||
3259 | |||
3260 | if (WARN_ON_ONCE(!fault_hash)) | ||
3261 | /* Should be allocated in amdgpu_vm_init | ||
3262 | */ | ||
3263 | return r; | ||
3264 | |||
3265 | spin_lock_irqsave(&fault_hash->lock, flags); | ||
3266 | |||
3267 | /* Only let the hash table fill up to 50% for best performance */ | ||
3268 | if (fault_hash->count >= (1 << (AMDGPU_PAGEFAULT_HASH_BITS-1))) | ||
3269 | goto unlock_out; | ||
3270 | |||
3271 | r = chash_table_copy_in(&fault_hash->hash, key, NULL); | ||
3272 | if (!r) | ||
3273 | fault_hash->count++; | ||
3274 | |||
3275 | /* chash_table_copy_in should never fail unless we're losing count */ | ||
3276 | WARN_ON_ONCE(r < 0); | ||
3277 | |||
3278 | unlock_out: | ||
3279 | spin_unlock_irqrestore(&fault_hash->lock, flags); | ||
3280 | return r; | ||
3281 | } | ||
3282 | |||
3283 | /** | ||
3284 | * amdgpu_vm_clear_fault - Remove a page fault record | ||
3285 | * | ||
3286 | * @fault_hash: fault hash table | ||
3287 | * @key: 64-bit encoding of PASID and address | ||
3288 | * | ||
3289 | * This should be called when a page fault has been handled. Any | ||
3290 | * future interrupt with this key will be processed as a new | ||
3291 | * page fault. | ||
3292 | */ | ||
3293 | void amdgpu_vm_clear_fault(struct amdgpu_retryfault_hashtable *fault_hash, u64 key) | ||
3294 | { | ||
3295 | unsigned long flags; | ||
3296 | int r; | ||
3297 | |||
3298 | if (!fault_hash) | ||
3299 | return; | ||
3300 | |||
3301 | spin_lock_irqsave(&fault_hash->lock, flags); | ||
3302 | |||
3303 | r = chash_table_remove(&fault_hash->hash, key, NULL); | ||
3304 | if (!WARN_ON_ONCE(r < 0)) { | ||
3305 | fault_hash->count--; | ||
3306 | WARN_ON_ONCE(fault_hash->count < 0); | ||
3307 | } | ||
3308 | |||
3309 | spin_unlock_irqrestore(&fault_hash->lock, flags); | ||
3310 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index e275ee7c1bc1..12d21eec4568 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <drm/gpu_scheduler.h> | 30 | #include <drm/gpu_scheduler.h> |
31 | #include <drm/drm_file.h> | 31 | #include <drm/drm_file.h> |
32 | #include <drm/ttm/ttm_bo_driver.h> | 32 | #include <drm/ttm/ttm_bo_driver.h> |
33 | #include <linux/chash.h> | ||
33 | 34 | ||
34 | #include "amdgpu_sync.h" | 35 | #include "amdgpu_sync.h" |
35 | #include "amdgpu_ring.h" | 36 | #include "amdgpu_ring.h" |
@@ -178,6 +179,13 @@ struct amdgpu_task_info { | |||
178 | pid_t tgid; | 179 | pid_t tgid; |
179 | }; | 180 | }; |
180 | 181 | ||
182 | #define AMDGPU_PAGEFAULT_HASH_BITS 8 | ||
183 | struct amdgpu_retryfault_hashtable { | ||
184 | DECLARE_CHASH_TABLE(hash, AMDGPU_PAGEFAULT_HASH_BITS, 8, 0); | ||
185 | spinlock_t lock; | ||
186 | int count; | ||
187 | }; | ||
188 | |||
181 | struct amdgpu_vm { | 189 | struct amdgpu_vm { |
182 | /* tree of virtual addresses mapped */ | 190 | /* tree of virtual addresses mapped */ |
183 | struct rb_root_cached va; | 191 | struct rb_root_cached va; |
@@ -240,6 +248,7 @@ struct amdgpu_vm { | |||
240 | struct ttm_lru_bulk_move lru_bulk_move; | 248 | struct ttm_lru_bulk_move lru_bulk_move; |
241 | /* mark whether can do the bulk move */ | 249 | /* mark whether can do the bulk move */ |
242 | bool bulk_moveable; | 250 | bool bulk_moveable; |
251 | struct amdgpu_retryfault_hashtable *fault_hash; | ||
243 | }; | 252 | }; |
244 | 253 | ||
245 | struct amdgpu_vm_manager { | 254 | struct amdgpu_vm_manager { |
@@ -355,4 +364,8 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm); | |||
355 | void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev, | 364 | void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev, |
356 | struct amdgpu_vm *vm); | 365 | struct amdgpu_vm *vm); |
357 | 366 | ||
367 | int amdgpu_vm_add_fault(struct amdgpu_retryfault_hashtable *fault_hash, u64 key); | ||
368 | |||
369 | void amdgpu_vm_clear_fault(struct amdgpu_retryfault_hashtable *fault_hash, u64 key); | ||
370 | |||
358 | #endif | 371 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index 5ae5ed2e62d6..acbe5a770207 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c | |||
@@ -265,35 +265,36 @@ static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev) | |||
265 | return true; | 265 | return true; |
266 | } | 266 | } |
267 | 267 | ||
268 | addr = ((u64)(dw5 & 0xf) << 44) | ((u64)dw4 << 12); | ||
269 | key = AMDGPU_VM_FAULT(pasid, addr); | ||
270 | r = amdgpu_ih_add_fault(adev, key); | ||
271 | |||
272 | /* Hash table is full or the fault is already being processed, | ||
273 | * ignore further page faults | ||
274 | */ | ||
275 | if (r != 0) | ||
276 | goto ignore_iv; | ||
277 | |||
278 | /* Track retry faults in per-VM fault FIFO. */ | 268 | /* Track retry faults in per-VM fault FIFO. */ |
279 | spin_lock(&adev->vm_manager.pasid_lock); | 269 | spin_lock(&adev->vm_manager.pasid_lock); |
280 | vm = idr_find(&adev->vm_manager.pasid_idr, pasid); | 270 | vm = idr_find(&adev->vm_manager.pasid_idr, pasid); |
271 | addr = ((u64)(dw5 & 0xf) << 44) | ((u64)dw4 << 12); | ||
272 | key = AMDGPU_VM_FAULT(pasid, addr); | ||
281 | if (!vm) { | 273 | if (!vm) { |
282 | /* VM not found, process it normally */ | 274 | /* VM not found, process it normally */ |
283 | spin_unlock(&adev->vm_manager.pasid_lock); | 275 | spin_unlock(&adev->vm_manager.pasid_lock); |
284 | amdgpu_ih_clear_fault(adev, key); | ||
285 | return true; | 276 | return true; |
277 | } else { | ||
278 | r = amdgpu_vm_add_fault(vm->fault_hash, key); | ||
279 | |||
280 | /* Hash table is full or the fault is already being processed, | ||
281 | * ignore further page faults | ||
282 | */ | ||
283 | if (r != 0) { | ||
284 | spin_unlock(&adev->vm_manager.pasid_lock); | ||
285 | goto ignore_iv; | ||
286 | } | ||
286 | } | 287 | } |
287 | /* No locking required with single writer and single reader */ | 288 | /* No locking required with single writer and single reader */ |
288 | r = kfifo_put(&vm->faults, key); | 289 | r = kfifo_put(&vm->faults, key); |
289 | if (!r) { | 290 | if (!r) { |
290 | /* FIFO is full. Ignore it until there is space */ | 291 | /* FIFO is full. Ignore it until there is space */ |
292 | amdgpu_vm_clear_fault(vm->fault_hash, key); | ||
291 | spin_unlock(&adev->vm_manager.pasid_lock); | 293 | spin_unlock(&adev->vm_manager.pasid_lock); |
292 | amdgpu_ih_clear_fault(adev, key); | ||
293 | goto ignore_iv; | 294 | goto ignore_iv; |
294 | } | 295 | } |
295 | spin_unlock(&adev->vm_manager.pasid_lock); | ||
296 | 296 | ||
297 | spin_unlock(&adev->vm_manager.pasid_lock); | ||
297 | /* It's the first fault for this address, process it normally */ | 298 | /* It's the first fault for this address, process it normally */ |
298 | return true; | 299 | return true; |
299 | 300 | ||
@@ -386,14 +387,6 @@ static int vega10_ih_sw_init(void *handle) | |||
386 | adev->irq.ih.use_doorbell = true; | 387 | adev->irq.ih.use_doorbell = true; |
387 | adev->irq.ih.doorbell_index = AMDGPU_DOORBELL64_IH << 1; | 388 | adev->irq.ih.doorbell_index = AMDGPU_DOORBELL64_IH << 1; |
388 | 389 | ||
389 | adev->irq.ih.faults = kmalloc(sizeof(*adev->irq.ih.faults), GFP_KERNEL); | ||
390 | if (!adev->irq.ih.faults) | ||
391 | return -ENOMEM; | ||
392 | INIT_CHASH_TABLE(adev->irq.ih.faults->hash, | ||
393 | AMDGPU_PAGEFAULT_HASH_BITS, 8, 0); | ||
394 | spin_lock_init(&adev->irq.ih.faults->lock); | ||
395 | adev->irq.ih.faults->count = 0; | ||
396 | |||
397 | r = amdgpu_irq_init(adev); | 390 | r = amdgpu_irq_init(adev); |
398 | 391 | ||
399 | return r; | 392 | return r; |
@@ -406,9 +399,6 @@ static int vega10_ih_sw_fini(void *handle) | |||
406 | amdgpu_irq_fini(adev); | 399 | amdgpu_irq_fini(adev); |
407 | amdgpu_ih_ring_fini(adev); | 400 | amdgpu_ih_ring_fini(adev); |
408 | 401 | ||
409 | kfree(adev->irq.ih.faults); | ||
410 | adev->irq.ih.faults = NULL; | ||
411 | |||
412 | return 0; | 402 | return 0; |
413 | } | 403 | } |
414 | 404 | ||