]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath11k: use kzalloc_flex for struct scan_req_params
authorRosen Penev <rosenp@gmail.com>
Tue, 28 Apr 2026 20:50:17 +0000 (13:50 -0700)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Mon, 1 Jun 2026 16:58:02 +0000 (09:58 -0700)
Convert kzalloc_obj + kcalloc to kzalloc_flex to save an allocation.

Add __counted_by to get extra runtime analysis. Move counting variable
assignment immediately after allocation before any potential accesses.
kzalloc_flex does this anyway for GCC >= 15.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260428205017.26288-1-rosenp@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath11k/mac.c
drivers/net/wireless/ath/ath11k/wmi.h

index a48b6bf1f29a850539680f6a7c083cb28e2b25c4..2d55cdc4d165dee77c0efa212db54ad216193608 100644 (file)
@@ -4227,13 +4227,14 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw,
        if (ret)
                goto exit;
 
-       arg = kzalloc_obj(*arg);
+       arg = kzalloc_flex(*arg, chan_list, req->n_channels);
 
        if (!arg) {
                ret = -ENOMEM;
                goto exit;
        }
 
+       arg->num_chan = req->n_channels;
        ath11k_wmi_start_scan_init(ar, arg);
        arg->vdev_id = arvif->vdev_id;
        arg->scan_id = ATH11K_SCAN_ID;
@@ -4261,38 +4262,27 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw,
                arg->scan_f_passive = 1;
        }
 
-       if (req->n_channels) {
-               arg->num_chan = req->n_channels;
-               arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list),
-                                        GFP_KERNEL);
+       for (i = 0; i < arg->num_chan; i++) {
+               if (test_bit(WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL,
+                            ar->ab->wmi_ab.svc_map)) {
+                       arg->chan_list[i] =
+                               u32_encode_bits(req->channels[i]->center_freq,
+                                               WMI_SCAN_CONFIG_PER_CHANNEL_MASK);
 
-               if (!arg->chan_list) {
-                       ret = -ENOMEM;
-                       goto exit;
-               }
-
-               for (i = 0; i < arg->num_chan; i++) {
-                       if (test_bit(WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL,
-                                    ar->ab->wmi_ab.svc_map)) {
-                               arg->chan_list[i] =
-                                       u32_encode_bits(req->channels[i]->center_freq,
-                                                       WMI_SCAN_CONFIG_PER_CHANNEL_MASK);
-
-                               /* If NL80211_SCAN_FLAG_COLOCATED_6GHZ is set in scan
-                                * flags, then scan all PSC channels in 6 GHz band and
-                                * those non-PSC channels where RNR IE is found during
-                                * the legacy 2.4/5 GHz scan.
-                                * If NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set,
-                                * then all channels in 6 GHz will be scanned.
-                                */
-                               if (req->channels[i]->band == NL80211_BAND_6GHZ &&
-                                   req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ &&
-                                   !cfg80211_channel_is_psc(req->channels[i]))
-                                       arg->chan_list[i] |=
-                                               WMI_SCAN_CH_FLAG_SCAN_ONLY_IF_RNR_FOUND;
-                       } else {
-                               arg->chan_list[i] = req->channels[i]->center_freq;
-                       }
+                       /* If NL80211_SCAN_FLAG_COLOCATED_6GHZ is set in scan
+                        * flags, then scan all PSC channels in 6 GHz band and
+                        * those non-PSC channels where RNR IE is found during
+                        * the legacy 2.4/5 GHz scan.
+                        * If NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set,
+                        * then all channels in 6 GHz will be scanned.
+                        */
+                       if (req->channels[i]->band == NL80211_BAND_6GHZ &&
+                           req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ &&
+                           !cfg80211_channel_is_psc(req->channels[i]))
+                               arg->chan_list[i] |=
+                                       WMI_SCAN_CH_FLAG_SCAN_ONLY_IF_RNR_FOUND;
+               } else {
+                       arg->chan_list[i] = req->channels[i]->center_freq;
                }
        }
 
@@ -4335,7 +4325,6 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw,
 
 exit:
        if (arg) {
-               kfree(arg->chan_list);
                kfree(arg->extraie.ptr);
                kfree(arg);
        }
@@ -9735,19 +9724,14 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
 
        scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
 
-       arg = kzalloc_obj(*arg);
+       arg = kzalloc_flex(*arg, chan_list, 1);
        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 free_arg;
-       }
+       ath11k_wmi_start_scan_init(ar, arg);
 
        arg->vdev_id = arvif->vdev_id;
        arg->scan_id = ATH11K_SCAN_ID;
@@ -9768,7 +9752,7 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
                spin_lock_bh(&ar->data_lock);
                ar->scan.state = ATH11K_SCAN_IDLE;
                spin_unlock_bh(&ar->data_lock);
-               goto free_chan_list;
+               goto free_arg;
        }
 
        ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
@@ -9778,7 +9762,7 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
                if (ret)
                        ath11k_warn(ar->ab, "failed to stop scan: %d\n", ret);
                ret = -ETIMEDOUT;
-               goto free_chan_list;
+               goto free_arg;
        }
 
        ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
@@ -9786,8 +9770,6 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
 
        ret = 0;
 
-free_chan_list:
-       kfree(arg->chan_list);
 free_arg:
        kfree(arg);
 exit:
index baed501b640b4ef92e08f575f3b59562e6c43d41..b2dade0516ac76320f88190bae0c93a0e08c2f54 100644 (file)
@@ -3423,7 +3423,6 @@ struct scan_req_params {
        u32 num_bssid;
        u32 num_ssids;
        u32 n_probes;
-       u32 *chan_list;
        u32 notify_scan_events;
        struct wlan_ssid ssid[WLAN_SCAN_PARAMS_MAX_SSID];
        struct wmi_mac_addr bssid_list[WLAN_SCAN_PARAMS_MAX_BSSID];
@@ -3436,6 +3435,7 @@ struct scan_req_params {
        struct hint_bssid hint_bssid[WLAN_SCAN_MAX_HINT_BSSID];
        struct wmi_mac_addr mac_addr;
        struct wmi_mac_addr mac_mask;
+       u32 chan_list[] __counted_by(num_chan);
 };
 
 struct wmi_ssid_arg {