Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amd/ras: Reduce stack usage in amdgpu_virt_ras_get_cper_records()

amdgpu_virt_ras_get_cper_records() was using a large stack array
of ras_log_info pointers. This contributed to the frame size
warning on this function.

Replace the fixed-size stack array:

struct ras_log_info *trace[MAX_RECORD_PER_BATCH];

with a heap-allocated array using kcalloc().

We free the trace buffer together with out_buf on all exit paths.
If allocation of trace or out_buf fails, we return a generic RAS
error code.

This reduces stack usage and keeps the runtime behaviour
unchanged.

Fixes:
stack frame size: 1112 bytes (limit: 1024)

Cc: Tao Zhou <tao.zhou1@amd.com>
Cc: Hawking Zhang <Hawking.Zhang@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Srinivasan Shanmugam and committed by
Alex Deucher
6ef93f62 5b57c3c3

+14 -5
+14 -5
drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c
··· 183 183 (struct ras_cmd_cper_record_rsp *)cmd->output_buff_raw; 184 184 struct ras_log_batch_overview *overview = &virt_ras->batch_mgr.batch_overview; 185 185 struct ras_cmd_batch_trace_record_rsp *rsp_cache = &virt_ras->batch_mgr.batch_trace; 186 - struct ras_log_info *trace[MAX_RECORD_PER_BATCH] = {0}; 186 + struct ras_log_info **trace; 187 187 uint32_t offset = 0, real_data_len = 0; 188 188 uint64_t batch_id; 189 189 uint8_t *out_buf; ··· 195 195 if (!req->buf_size || !req->buf_ptr || !req->cper_num) 196 196 return RAS_CMD__ERROR_INVALID_INPUT_DATA; 197 197 198 - out_buf = kzalloc(req->buf_size, GFP_KERNEL); 199 - if (!out_buf) 198 + trace = kcalloc(MAX_RECORD_PER_BATCH, sizeof(*trace), GFP_KERNEL); 199 + if (!trace) 200 200 return RAS_CMD__ERROR_GENERIC; 201 + 202 + out_buf = kzalloc(req->buf_size, GFP_KERNEL); 203 + if (!out_buf) { 204 + kfree(trace); 205 + return RAS_CMD__ERROR_GENERIC; 206 + } 201 207 202 208 memset(out_buf, 0, req->buf_size); 203 209 ··· 211 205 batch_id = req->cper_start_id + i; 212 206 if (batch_id >= overview->last_batch_id) 213 207 break; 214 - count = amdgpu_virt_ras_get_batch_records(ras_core, batch_id, trace, 215 - ARRAY_SIZE(trace), rsp_cache); 208 + count = amdgpu_virt_ras_get_batch_records(ras_core, batch_id, 209 + trace, MAX_RECORD_PER_BATCH, 210 + rsp_cache); 216 211 if (count > 0) { 217 212 ret = ras_cper_generate_cper(ras_core, trace, count, 218 213 &out_buf[offset], req->buf_size - offset, &real_data_len); ··· 227 220 if ((ret && (ret != -ENOMEM)) || 228 221 copy_to_user(u64_to_user_ptr(req->buf_ptr), out_buf, offset)) { 229 222 kfree(out_buf); 223 + kfree(trace); 230 224 return RAS_CMD__ERROR_GENERIC; 231 225 } 232 226 ··· 239 231 cmd->output_size = sizeof(struct ras_cmd_cper_record_rsp); 240 232 241 233 kfree(out_buf); 234 + kfree(trace); 242 235 243 236 return RAS_CMD__SUCCESS; 244 237 }