The `kfd_get_cu_occupancy` function previously declared a large `cu_occupancy` array as a local variable, which could lead to stack overflows due to excessive stack usage. This commit replaces the static array allocation with dynamic memory allocation using `kmalloc_array`, thereby reducing the stack size. This change avoids the risk of stack overflows in kernel space, in scenarios where `AMDGPU_MAX_QUEUES` is large. The allocated memory is freed using `kfree` before the function returns to prevent memory leaks. Fixes the below with gcc W=1: drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_process.c: In function ‘kfd_get_cu_occupancy’: drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_process.c:322:1: warning: the frame size of 1056 bytes is larger than 1024 bytes [-Wframe-larger-than=] 322 | } | ^ Fixes: 6fc91266b798 ("drm/amdkfd: Update logic for CU occupancy calculations") Cc: Mukul Joshi <mukul.joshi@xxxxxxx> Cc: Harish Kasiviswanathan <Harish.Kasiviswanathan@xxxxxxx> Cc: Felix Kuehling <felix.kuehling@xxxxxxx> Cc: Christian König <christian.koenig@xxxxxxx> Cc: Alex Deucher <alexander.deucher@xxxxxxx> Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@xxxxxxx> --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index d665ecdcd12f..33109d9f6eed 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -271,10 +271,13 @@ static int kfd_get_cu_occupancy(struct attribute *attr, char *buffer) struct kfd_process *proc = NULL; struct kfd_process_device *pdd = NULL; int i; - struct kfd_cu_occupancy cu_occupancy[AMDGPU_MAX_QUEUES]; + struct kfd_cu_occupancy *cu_occupancy; u32 queue_format; + int bytes_written; - memset(cu_occupancy, 0x0, sizeof(cu_occupancy)); + cu_occupancy = kmalloc_array(AMDGPU_MAX_QUEUES, sizeof(*cu_occupancy), GFP_KERNEL); + if (!cu_occupancy) + return -ENOMEM; pdd = container_of(attr, struct kfd_process_device, attr_cu_occupancy); dev = pdd->dev; @@ -318,7 +321,10 @@ static int kfd_get_cu_occupancy(struct attribute *attr, char *buffer) /* Translate wave count to number of compute units */ cu_cnt = (wave_cnt + (max_waves_per_cu - 1)) / max_waves_per_cu; - return snprintf(buffer, PAGE_SIZE, "%d\n", cu_cnt); + bytes_written = snprintf(buffer, PAGE_SIZE, "%d\n", cu_cnt); + + kfree(cu_occupancy); + return bytes_written; } static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr, -- 2.34.1