]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: mark QMI driver event helpers as noinline
authorJeff Johnson <quic_jjohnson@quicinc.com>
Mon, 28 Oct 2024 14:08:40 +0000 (07:08 -0700)
committerJeff Johnson <quic_jjohnson@quicinc.com>
Wed, 6 Nov 2024 19:36:28 +0000 (11:36 -0800)
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@quicinc.com
Link: https://msgid.link/20241025223321.GA3647469@thelio-3990X
Link: https://lore.kernel.org/all/?q=f:arnd@kernel.org+Wframe-larger-than
Acked-by: Kalle Valo <kvalo@kernel.org>
Link: https://patch.msgid.link/20241028-ath12k_qmi_driver_event_work-v1-1-0d532eb593fa@quicinc.com
Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
drivers/net/wireless/ath/ath12k/qmi.c

index b93ce9f87f6129c0ed0cc6dbf79f7325004651a2..d2d9d03c7a28e9aacd6f70873f185ca694e665ac 100644 (file)
@@ -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 @@ resp_out:
        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 @@ this_chunk_done:
        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 @@ out:
        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 @@ out:
        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;