From 31a49299abd2794060bbca480a837af44185d264 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Fri, 28 Jul 2017 15:51:15 -0400 Subject: [PATCH 1755/4131] drm/amdkfd: Fix doorbell initialization and finalization Handle errors in doorbell aperture initialization instead of BUG_ON. iounmap doorbell aperture during finalization. Change-Id: I45971955f13c66ea230994d2471264514043b158 Signed-off-by: Felix Kuehling --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 9 ++++++++- drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c | 13 +++++++++++-- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 3 ++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 35c0b554..d8b6489 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -611,7 +611,11 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto kfd_gtt_sa_init_error; } - kfd_doorbell_init(kfd); + if (kfd_doorbell_init(kfd)) { + dev_err(kfd_device, + "Error initializing doorbell aperture\n"); + goto kfd_doorbell_error; + } if (kfd_topology_add_device(kfd) != 0) { dev_err(kfd_device, @@ -678,6 +682,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, kfd_interrupt_error: kfd_topology_remove_device(kfd); kfd_topology_add_device_error: + kfd_doorbell_fini(kfd); +kfd_doorbell_error: kfd_gtt_sa_fini(kfd); kfd_gtt_sa_init_error: kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem); @@ -699,6 +705,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd) device_queue_manager_uninit(kfd->dqm); kfd_interrupt_exit(kfd); kfd_topology_remove_device(kfd); + kfd_doorbell_fini(kfd); kfd_gtt_sa_fini(kfd); kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c index f4833b2..55a0fda 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c @@ -58,7 +58,7 @@ size_t kfd_doorbell_process_slice(struct kfd_dev *kfd) } /* Doorbell calculations for device init. */ -void kfd_doorbell_init(struct kfd_dev *kfd) +int kfd_doorbell_init(struct kfd_dev *kfd) { size_t doorbell_start_offset; size_t doorbell_aperture_size; @@ -94,7 +94,8 @@ void kfd_doorbell_init(struct kfd_dev *kfd) kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base, kfd_doorbell_process_slice(kfd)); - WARN_ON(!kfd->doorbell_kernel_ptr); + if (!kfd->doorbell_kernel_ptr) + return -ENOMEM; pr_debug("Doorbell initialization:\n"); pr_debug("doorbell base == 0x%08lX\n", @@ -114,6 +115,14 @@ void kfd_doorbell_init(struct kfd_dev *kfd) pr_debug("doorbell kernel address == 0x%08lX\n", (uintptr_t)kfd->doorbell_kernel_ptr); + + return 0; +} + +void kfd_doorbell_fini(struct kfd_dev *kfd) +{ + if (kfd->doorbell_kernel_ptr) + iounmap(kfd->doorbell_kernel_ptr); } int kfd_doorbell_mmap(struct kfd_dev *dev, struct kfd_process *process, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 4b27428..a711c86 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -813,7 +813,8 @@ void kfd_pasid_free(unsigned int pasid); /* Doorbells */ size_t kfd_doorbell_process_slice(struct kfd_dev *kfd); -void kfd_doorbell_init(struct kfd_dev *kfd); +int kfd_doorbell_init(struct kfd_dev *kfd); +void kfd_doorbell_fini(struct kfd_dev *kfd); int kfd_doorbell_mmap(struct kfd_dev *kfd, struct kfd_process *process, struct vm_area_struct *vma); void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd, -- 2.7.4