From aeda036c371c58d3a6dcb3e5ac3c1503e7ffc4cf Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 3 Dec 2014 09:26:25 -0500 Subject: [PATCH 1/3] amdkfd: use sizeof(long) granularity for the pasid bitmask All the bit operations (such as find_first_zero_bit()) read sizeof(long) bytes at a time. If we allocated less than sizeof(long) bytes for the bitmask we would be accessing invalid memory when working with the bitmask. Change the allocator to allocate sizeof(long) multiples for the bitmask. Signed-off-by: Sasha Levin Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_pasid.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c index 2458ab7c0c6e..71699ad97d74 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c @@ -32,8 +32,7 @@ int kfd_pasid_init(void) { pasid_limit = max_num_of_processes; - pasid_bitmap = kzalloc(DIV_ROUND_UP(pasid_limit, BITS_PER_BYTE), - GFP_KERNEL); + pasid_bitmap = kzalloc(BITS_TO_LONGS(pasid_limit), GFP_KERNEL); if (!pasid_bitmap) return -ENOMEM; From c448a142a714b4ad25ebd4c872b7c9752e428c88 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 3 Dec 2014 10:19:36 -0500 Subject: [PATCH 2/3] amdkfd: use atomic allocations within srcu callbacks srcu callbacks are running in atomic context, we can't allocate using __GFP_WAIT. Signed-off-by: Sasha Levin Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index b4f49ac13334..b85eb0b830b4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -196,7 +196,7 @@ static void kfd_process_destroy_delayed(struct rcu_head *rcu) mmdrop(p->mm); work = (struct kfd_process_release_work *) - kmalloc(sizeof(struct kfd_process_release_work), GFP_KERNEL); + kmalloc(sizeof(struct kfd_process_release_work), GFP_ATOMIC); if (work) { INIT_WORK((struct work_struct *) work, kfd_process_wq_release); From a550bb3d5313c3d894cac552e13037394ac78fd4 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Thu, 4 Dec 2014 14:09:02 +0200 Subject: [PATCH 3/3] amdkfd: Set *buffer_ptr to NULL in case of error In function acquire_packet_buffer() we may return -ENOMEM. In that case, we should set the *buffer_ptr to NULL, so that calling functions which check the *buffer_ptr value as a criteria for success, will know that acquire_packet_buffer() failed. Reviewed-by: Alexey Skidanov Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c index 9abac48de499..935071410724 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c @@ -221,8 +221,14 @@ static int acquire_packet_buffer(struct kernel_queue *kq, queue_size_dwords; if (packet_size_in_dwords >= queue_size_dwords || - packet_size_in_dwords >= available_size) + packet_size_in_dwords >= available_size) { + /* + * make sure calling functions know + * acquire_packet_buffer() failed + */ + *buffer_ptr = NULL; return -ENOMEM; + } if (wptr + packet_size_in_dwords >= queue_size_dwords) { while (wptr > 0) {