On 9/25/2023 5:46 AM, Dmitry Antipov wrote:
> When compiling with clang 16.0.6, I've noticed the following:
>
> drivers/net/wireless/ath/ath11k/mac.c:8903:12: warning: stack frame
> size (1032) exceeds limit (1024) in 'ath11k_mac_op_remain_on_channel'
> [-Wframe-larger-than]
> static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
> ^
> 68/1032 (6.59%) spills, 964/1032 (93.41%) variables
>
> So switch to kzalloc()'ed instance of 'struct scan_req_params' like
> it's done in 'ath11k_mac_op_hw_scan()'. Compile tested only.
>
> Signed-off-by: Dmitry Antipov <[email protected]>
> ---
> drivers/net/wireless/ath/ath11k/mac.c | 43 +++++++++++++++------------
> 1 file changed, 24 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
> index 6ed036b51dba..c7d51f6aeede 100644
> --- a/drivers/net/wireless/ath/ath11k/mac.c
> +++ b/drivers/net/wireless/ath/ath11k/mac.c
> @@ -8908,7 +8908,7 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
> {
> struct ath11k *ar = hw->priv;
> struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
> - struct scan_req_params arg;
> + struct scan_req_params *arg = NULL;
> int ret;
> u32 scan_time_msec;
>
> @@ -8940,27 +8940,31 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
>
> scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
>
> - memset(&arg, 0, sizeof(arg));
> - ath11k_wmi_start_scan_init(ar, &arg);
> - arg.num_chan = 1;
> - arg.chan_list = kcalloc(arg.num_chan, sizeof(*arg.chan_list),
> - GFP_KERNEL);
> - if (!arg.chan_list) {
> + arg = kzalloc(sizeof(*arg), GFP_KERNEL);
> + if (!arg) {
> + ret = -ENOMEM;
> + goto exit;
> + }
> + ath11k_wmi_start_scan_init(ar, arg);
> + arg->num_chan = 1;
> + arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list),
> + GFP_KERNEL);
> + if (!arg->chan_list) {
> ret = -ENOMEM;
> goto exit;
> }
>
> - arg.vdev_id = arvif->vdev_id;
> - arg.scan_id = ATH11K_SCAN_ID;
> - arg.chan_list[0] = chan->center_freq;
> - arg.dwell_time_active = scan_time_msec;
> - arg.dwell_time_passive = scan_time_msec;
> - arg.max_scan_time = scan_time_msec;
> - arg.scan_flags |= WMI_SCAN_FLAG_PASSIVE;
> - arg.scan_flags |= WMI_SCAN_FILTER_PROBE_REQ;
> - arg.burst_duration = duration;
> -
> - ret = ath11k_start_scan(ar, &arg);
> + arg->vdev_id = arvif->vdev_id;
> + arg->scan_id = ATH11K_SCAN_ID;
> + arg->chan_list[0] = chan->center_freq;
> + arg->dwell_time_active = scan_time_msec;
> + arg->dwell_time_passive = scan_time_msec;
> + arg->max_scan_time = scan_time_msec;
> + arg->scan_flags |= WMI_SCAN_FLAG_PASSIVE;
> + arg->scan_flags |= WMI_SCAN_FILTER_PROBE_REQ;
> + arg->burst_duration = duration;
> +
> + ret = ath11k_start_scan(ar, arg);
> if (ret) {
> ath11k_warn(ar->ab, "failed to start roc scan: %d\n", ret);
>
> @@ -8986,8 +8990,9 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
> ret = 0;
>
> free_chan_list:
> - kfree(arg.chan_list);
> + kfree(arg->chan_list);
> exit:
> + kfree(arg);
consider adding a free_arg: label which you'd goto if the chan_list
allocation fails. exit: would continue to just have the mutex_unlock()
with that change you no longer need the arg = NULL initializer
> mutex_unlock(&ar->conf_mutex);
> return ret;
> }