aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Goz <ben.goz@amd.com>2015-03-08 08:17:02 -0400
committerOded Gabbay <oded.gabbay@amd.com>2015-03-16 17:36:58 -0400
commitaaad2d8c7b62489f03ceac4fa3c9ebb17ccc7860 (patch)
tree1b20a28ff7aca134b3eec9e4a5428f7771743640
parent06e5801b8cb3fc057d88cb4dc03c0b64b2744cda (diff)
drm/amdkfd: destroy mqd when destroying kernel queue
This patch adds a missing destruction of mqd, when destroying a kernel queue. Without the destruction, there is a memory leakage when repeatedly creating and destroying kernel queues. Signed-off-by: Ben Goz <ben.goz@amd.com> Signed-off-by: Oded Gabbay <oded.gabbay@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
index e415a2a9207e..c7d298e62c96 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
@@ -44,7 +44,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
44 BUG_ON(!kq || !dev); 44 BUG_ON(!kq || !dev);
45 BUG_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ); 45 BUG_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ);
46 46
47 pr_debug("kfd: In func %s initializing queue type %d size %d\n", 47 pr_debug("amdkfd: In func %s initializing queue type %d size %d\n",
48 __func__, KFD_QUEUE_TYPE_HIQ, queue_size); 48 __func__, KFD_QUEUE_TYPE_HIQ, queue_size);
49 49
50 nop.opcode = IT_NOP; 50 nop.opcode = IT_NOP;
@@ -69,12 +69,16 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
69 69
70 prop.doorbell_ptr = kfd_get_kernel_doorbell(dev, &prop.doorbell_off); 70 prop.doorbell_ptr = kfd_get_kernel_doorbell(dev, &prop.doorbell_off);
71 71
72 if (prop.doorbell_ptr == NULL) 72 if (prop.doorbell_ptr == NULL) {
73 pr_err("amdkfd: error init doorbell");
73 goto err_get_kernel_doorbell; 74 goto err_get_kernel_doorbell;
75 }
74 76
75 retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq); 77 retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq);
76 if (retval != 0) 78 if (retval != 0) {
79 pr_err("amdkfd: error init pq queues size (%d)\n", queue_size);
77 goto err_pq_allocate_vidmem; 80 goto err_pq_allocate_vidmem;
81 }
78 82
79 kq->pq_kernel_addr = kq->pq->cpu_ptr; 83 kq->pq_kernel_addr = kq->pq->cpu_ptr;
80 kq->pq_gpu_addr = kq->pq->gpu_addr; 84 kq->pq_gpu_addr = kq->pq->gpu_addr;
@@ -165,10 +169,8 @@ err_rptr_allocate_vidmem:
165err_eop_allocate_vidmem: 169err_eop_allocate_vidmem:
166 kfd_gtt_sa_free(dev, kq->pq); 170 kfd_gtt_sa_free(dev, kq->pq);
167err_pq_allocate_vidmem: 171err_pq_allocate_vidmem:
168 pr_err("kfd: error init pq\n");
169 kfd_release_kernel_doorbell(dev, prop.doorbell_ptr); 172 kfd_release_kernel_doorbell(dev, prop.doorbell_ptr);
170err_get_kernel_doorbell: 173err_get_kernel_doorbell:
171 pr_err("kfd: error init doorbell");
172 return false; 174 return false;
173 175
174} 176}
@@ -187,6 +189,8 @@ static void uninitialize(struct kernel_queue *kq)
187 else if (kq->queue->properties.type == KFD_QUEUE_TYPE_DIQ) 189 else if (kq->queue->properties.type == KFD_QUEUE_TYPE_DIQ)
188 kfd_gtt_sa_free(kq->dev, kq->fence_mem_obj); 190 kfd_gtt_sa_free(kq->dev, kq->fence_mem_obj);
189 191
192 kq->mqd->uninit_mqd(kq->mqd, kq->queue->mqd, kq->queue->mqd_mem_obj);
193
190 kfd_gtt_sa_free(kq->dev, kq->rptr_mem); 194 kfd_gtt_sa_free(kq->dev, kq->rptr_mem);
191 kfd_gtt_sa_free(kq->dev, kq->wptr_mem); 195 kfd_gtt_sa_free(kq->dev, kq->wptr_mem);
192 kq->ops_asic_specific.uninitialize(kq); 196 kq->ops_asic_specific.uninitialize(kq);
@@ -211,7 +215,7 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
211 queue_address = (unsigned int *)kq->pq_kernel_addr; 215 queue_address = (unsigned int *)kq->pq_kernel_addr;
212 queue_size_dwords = kq->queue->properties.queue_size / sizeof(uint32_t); 216 queue_size_dwords = kq->queue->properties.queue_size / sizeof(uint32_t);
213 217
214 pr_debug("kfd: In func %s\nrptr: %d\nwptr: %d\nqueue_address 0x%p\n", 218 pr_debug("amdkfd: In func %s\nrptr: %d\nwptr: %d\nqueue_address 0x%p\n",
215 __func__, rptr, wptr, queue_address); 219 __func__, rptr, wptr, queue_address);
216 220
217 available_size = (rptr - 1 - wptr + queue_size_dwords) % 221 available_size = (rptr - 1 - wptr + queue_size_dwords) %
@@ -296,7 +300,7 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
296 } 300 }
297 301
298 if (kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) { 302 if (kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) {
299 pr_err("kfd: failed to init kernel queue\n"); 303 pr_err("amdkfd: failed to init kernel queue\n");
300 kfree(kq); 304 kfree(kq);
301 return NULL; 305 return NULL;
302 } 306 }
@@ -319,7 +323,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
319 323
320 BUG_ON(!dev); 324 BUG_ON(!dev);
321 325
322 pr_err("kfd: starting kernel queue test\n"); 326 pr_err("amdkfd: starting kernel queue test\n");
323 327
324 kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ); 328 kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
325 BUG_ON(!kq); 329 BUG_ON(!kq);
@@ -330,7 +334,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
330 buffer[i] = kq->nop_packet; 334 buffer[i] = kq->nop_packet;
331 kq->ops.submit_packet(kq); 335 kq->ops.submit_packet(kq);
332 336
333 pr_err("kfd: ending kernel queue test\n"); 337 pr_err("amdkfd: ending kernel queue test\n");
334} 338}
335 339
336 340