As described in [1], compiling the ath12k driver using clang with KASAN enabled warns about some functions with excessive stack usage, with the worst case being: drivers/net/wireless/ath/ath12k/qmi.c:3546:13: warning: stack frame size (2456) exceeds limit (1024) in 'ath12k_qmi_driver_event_work' [-Wframe-larger-than] Nathan [2] highlighted work done by Arnd [3] to address similar issues in other portions of the kernel. ath12k_qmi_driver_event_work() itself is a pretty lightweight function, but it dispatches to several other functions which do the real work: ath12k_qmi_driver_event_work() ath12k_qmi_event_server_arrive() ath12k_qmi_host_cap_send() ath12k_qmi_event_mem_request() ath12k_qmi_respond_fw_mem_request() ath12k_qmi_event_load_bdf() ath12k_qmi_request_target_cap() ath12k_qmi_load_bdf_qmi() ath12k_qmi_wlanfw_m3_info_send() Mark all of those underlying functions as 'noinline_for_stack' to prevent them from being inlined in ath12k_qmi_driver_event_work(), thereby eliminating the excessive stack usage. Link: https://msgid.link/bc214795-1c51-4cb7-922f-67d6ef98bff2@xxxxxxxxxxx # [1] Link: https://msgid.link/20241025223321.GA3647469@thelio-3990X # [2] Link: https://lore.kernel.org/all/?q=f:arnd@xxxxxxxxxx+Wframe-larger-than # [3] Signed-off-by: Jeff Johnson <quic_jjohnson@xxxxxxxxxxx> --- drivers/net/wireless/ath/ath12k/qmi.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c index b93ce9f87f61..d2d9d03c7a28 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.c +++ b/drivers/net/wireless/ath/ath12k/qmi.c @@ -2066,7 +2066,9 @@ static void ath12k_host_cap_parse_mlo(struct ath12k_base *ab, req->mlo_chip_info_valid = 1; } -static int ath12k_qmi_host_cap_send(struct ath12k_base *ab) +/* clang stack usage explodes if this is inlined */ +static noinline_for_stack +int ath12k_qmi_host_cap_send(struct ath12k_base *ab) { struct qmi_wlanfw_host_cap_req_msg_v01 req = {}; struct qmi_wlanfw_host_cap_resp_msg_v01 resp = {}; @@ -2275,7 +2277,9 @@ static int ath12k_qmi_fw_ind_register_send(struct ath12k_base *ab) return ret; } -static int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab) +/* clang stack usage explodes if this is inlined */ +static noinline_for_stack +int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab) { struct qmi_wlanfw_respond_mem_req_msg_v01 *req; struct qmi_wlanfw_respond_mem_resp_msg_v01 resp = {}; @@ -2433,7 +2437,9 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab) return 0; } -static int ath12k_qmi_request_target_cap(struct ath12k_base *ab) +/* clang stack usage explodes if this is inlined */ +static noinline_for_stack +int ath12k_qmi_request_target_cap(struct ath12k_base *ab) { struct qmi_wlanfw_cap_req_msg_v01 req = {}; struct qmi_wlanfw_cap_resp_msg_v01 resp = {}; @@ -2619,8 +2625,10 @@ static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab, return ret; } -static int ath12k_qmi_load_bdf_qmi(struct ath12k_base *ab, - enum ath12k_qmi_bdf_type type) +/* clang stack usage explodes if this is inlined */ +static noinline_for_stack +int ath12k_qmi_load_bdf_qmi(struct ath12k_base *ab, + enum ath12k_qmi_bdf_type type) { struct device *dev = ab->dev; char filename[ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE]; @@ -2791,7 +2799,9 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab) return ret; } -static int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab) +/* clang stack usage explodes if this is inlined */ +static noinline_for_stack +int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab) { struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; struct qmi_wlanfw_m3_info_req_msg_v01 req = {}; @@ -3079,7 +3089,9 @@ ath12k_qmi_driver_event_post(struct ath12k_qmi *qmi, return 0; } -static int ath12k_qmi_event_server_arrive(struct ath12k_qmi *qmi) +/* clang stack usage explodes if this is inlined */ +static noinline_for_stack +int ath12k_qmi_event_server_arrive(struct ath12k_qmi *qmi) { struct ath12k_base *ab = qmi->ab; int ret; @@ -3101,7 +3113,9 @@ static int ath12k_qmi_event_server_arrive(struct ath12k_qmi *qmi) return ret; } -static int ath12k_qmi_event_mem_request(struct ath12k_qmi *qmi) +/* clang stack usage explodes if this is inlined */ +static noinline_for_stack +int ath12k_qmi_event_mem_request(struct ath12k_qmi *qmi) { struct ath12k_base *ab = qmi->ab; int ret; @@ -3115,7 +3129,9 @@ static int ath12k_qmi_event_mem_request(struct ath12k_qmi *qmi) return ret; } -static int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi) +/* clang stack usage explodes if this is inlined */ +static noinline_for_stack +int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi) { struct ath12k_base *ab = qmi->ab; int ret; --- base-commit: 8a58dcd8db9c7af1187f0236d71a99cbbe146f6a change-id: 20241025-ath12k_qmi_driver_event_work-ea9703c44ad7