Commit f2cd6b26 authored by Alex Deucher's avatar Alex Deucher

drm/amdkfd: fix stack size in svm_range_validate_and_map

Allocate large local variable on heap to avoid exceeding the
stack size:
drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_svm.c: In function ‘svm_range_validate_and_map’:
drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_svm.c:1690:1: warning: the frame size of 2360 bytes is larger than 2048 bytes [-Wframe-larger-than=]
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 01c3f464
...@@ -1554,48 +1554,54 @@ static int svm_range_validate_and_map(struct mm_struct *mm, ...@@ -1554,48 +1554,54 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
struct svm_range *prange, int32_t gpuidx, struct svm_range *prange, int32_t gpuidx,
bool intr, bool wait, bool flush_tlb) bool intr, bool wait, bool flush_tlb)
{ {
struct svm_validate_context ctx; struct svm_validate_context *ctx;
unsigned long start, end, addr; unsigned long start, end, addr;
struct kfd_process *p; struct kfd_process *p;
void *owner; void *owner;
int32_t idx; int32_t idx;
int r = 0; int r = 0;
ctx.process = container_of(prange->svms, struct kfd_process, svms); ctx = kzalloc(sizeof(struct svm_validate_context), GFP_KERNEL);
ctx.prange = prange; if (!ctx)
ctx.intr = intr; return -ENOMEM;
ctx->process = container_of(prange->svms, struct kfd_process, svms);
ctx->prange = prange;
ctx->intr = intr;
if (gpuidx < MAX_GPU_INSTANCE) { if (gpuidx < MAX_GPU_INSTANCE) {
bitmap_zero(ctx.bitmap, MAX_GPU_INSTANCE); bitmap_zero(ctx->bitmap, MAX_GPU_INSTANCE);
bitmap_set(ctx.bitmap, gpuidx, 1); bitmap_set(ctx->bitmap, gpuidx, 1);
} else if (ctx.process->xnack_enabled) { } else if (ctx->process->xnack_enabled) {
bitmap_copy(ctx.bitmap, prange->bitmap_aip, MAX_GPU_INSTANCE); bitmap_copy(ctx->bitmap, prange->bitmap_aip, MAX_GPU_INSTANCE);
/* If prefetch range to GPU, or GPU retry fault migrate range to /* If prefetch range to GPU, or GPU retry fault migrate range to
* GPU, which has ACCESS attribute to the range, create mapping * GPU, which has ACCESS attribute to the range, create mapping
* on that GPU. * on that GPU.
*/ */
if (prange->actual_loc) { if (prange->actual_loc) {
gpuidx = kfd_process_gpuidx_from_gpuid(ctx.process, gpuidx = kfd_process_gpuidx_from_gpuid(ctx->process,
prange->actual_loc); prange->actual_loc);
if (gpuidx < 0) { if (gpuidx < 0) {
WARN_ONCE(1, "failed get device by id 0x%x\n", WARN_ONCE(1, "failed get device by id 0x%x\n",
prange->actual_loc); prange->actual_loc);
return -EINVAL; r = -EINVAL;
goto free_ctx;
} }
if (test_bit(gpuidx, prange->bitmap_access)) if (test_bit(gpuidx, prange->bitmap_access))
bitmap_set(ctx.bitmap, gpuidx, 1); bitmap_set(ctx->bitmap, gpuidx, 1);
} }
} else { } else {
bitmap_or(ctx.bitmap, prange->bitmap_access, bitmap_or(ctx->bitmap, prange->bitmap_access,
prange->bitmap_aip, MAX_GPU_INSTANCE); prange->bitmap_aip, MAX_GPU_INSTANCE);
} }
if (bitmap_empty(ctx.bitmap, MAX_GPU_INSTANCE)) { if (bitmap_empty(ctx->bitmap, MAX_GPU_INSTANCE)) {
if (!prange->mapped_to_gpu) if (!prange->mapped_to_gpu) {
return 0; r = 0;
goto free_ctx;
}
bitmap_copy(ctx.bitmap, prange->bitmap_access, MAX_GPU_INSTANCE); bitmap_copy(ctx->bitmap, prange->bitmap_access, MAX_GPU_INSTANCE);
} }
if (prange->actual_loc && !prange->ttm_res) { if (prange->actual_loc && !prange->ttm_res) {
...@@ -1603,15 +1609,16 @@ static int svm_range_validate_and_map(struct mm_struct *mm, ...@@ -1603,15 +1609,16 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
* svm_migrate_ram_to_vram after allocating a BO. * svm_migrate_ram_to_vram after allocating a BO.
*/ */
WARN_ONCE(1, "VRAM BO missing during validation\n"); WARN_ONCE(1, "VRAM BO missing during validation\n");
return -EINVAL; r = -EINVAL;
goto free_ctx;
} }
svm_range_reserve_bos(&ctx); svm_range_reserve_bos(ctx);
p = container_of(prange->svms, struct kfd_process, svms); p = container_of(prange->svms, struct kfd_process, svms);
owner = kfd_svm_page_owner(p, find_first_bit(ctx.bitmap, owner = kfd_svm_page_owner(p, find_first_bit(ctx->bitmap,
MAX_GPU_INSTANCE)); MAX_GPU_INSTANCE));
for_each_set_bit(idx, ctx.bitmap, MAX_GPU_INSTANCE) { for_each_set_bit(idx, ctx->bitmap, MAX_GPU_INSTANCE) {
if (kfd_svm_page_owner(p, idx) != owner) { if (kfd_svm_page_owner(p, idx) != owner) {
owner = NULL; owner = NULL;
break; break;
...@@ -1648,7 +1655,7 @@ static int svm_range_validate_and_map(struct mm_struct *mm, ...@@ -1648,7 +1655,7 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
} }
offset = (addr - start) >> PAGE_SHIFT; offset = (addr - start) >> PAGE_SHIFT;
r = svm_range_dma_map(prange, ctx.bitmap, offset, npages, r = svm_range_dma_map(prange, ctx->bitmap, offset, npages,
hmm_range->hmm_pfns); hmm_range->hmm_pfns);
if (r) { if (r) {
pr_debug("failed %d to dma map range\n", r); pr_debug("failed %d to dma map range\n", r);
...@@ -1668,7 +1675,7 @@ static int svm_range_validate_and_map(struct mm_struct *mm, ...@@ -1668,7 +1675,7 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
} }
r = svm_range_map_to_gpus(prange, offset, npages, readonly, r = svm_range_map_to_gpus(prange, offset, npages, readonly,
ctx.bitmap, wait, flush_tlb); ctx->bitmap, wait, flush_tlb);
unlock_out: unlock_out:
svm_range_unlock(prange); svm_range_unlock(prange);
...@@ -1682,11 +1689,14 @@ static int svm_range_validate_and_map(struct mm_struct *mm, ...@@ -1682,11 +1689,14 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
} }
unreserve_out: unreserve_out:
svm_range_unreserve_bos(&ctx); svm_range_unreserve_bos(ctx);
if (!r) if (!r)
prange->validate_timestamp = ktime_get_boottime(); prange->validate_timestamp = ktime_get_boottime();
free_ctx:
kfree(ctx);
return r; return r;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment