wifi: nl80211: clean up coalescing rule handling
There's no need to allocate a tiny struct and then an array again, just allocate the two together and use __counted_by(). Also unify the freeing. Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com> Link: https://msgid.link/20240523120213.48a40cfb96f9.Ia02bf8f8fefbf533c64c5fa26175848d4a3a7899@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
6322e0e75a
commit
8526f8c877
@ -3566,8 +3566,8 @@ struct cfg80211_coalesce_rules {
|
|||||||
* @n_rules: number of rules
|
* @n_rules: number of rules
|
||||||
*/
|
*/
|
||||||
struct cfg80211_coalesce {
|
struct cfg80211_coalesce {
|
||||||
struct cfg80211_coalesce_rules *rules;
|
|
||||||
int n_rules;
|
int n_rules;
|
||||||
|
struct cfg80211_coalesce_rules rules[] __counted_by(n_rules);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1145,7 +1145,8 @@ void wiphy_unregister(struct wiphy *wiphy)
|
|||||||
flush_work(&rdev->background_cac_abort_wk);
|
flush_work(&rdev->background_cac_abort_wk);
|
||||||
|
|
||||||
cfg80211_rdev_free_wowlan(rdev);
|
cfg80211_rdev_free_wowlan(rdev);
|
||||||
cfg80211_rdev_free_coalesce(rdev);
|
cfg80211_free_coalesce(rdev->coalesce);
|
||||||
|
rdev->coalesce = NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(wiphy_unregister);
|
EXPORT_SYMBOL(wiphy_unregister);
|
||||||
|
|
||||||
|
@ -13897,9 +13897,8 @@ nla_put_failure:
|
|||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
|
void cfg80211_free_coalesce(struct cfg80211_coalesce *coalesce)
|
||||||
{
|
{
|
||||||
struct cfg80211_coalesce *coalesce = rdev->coalesce;
|
|
||||||
int i, j;
|
int i, j;
|
||||||
struct cfg80211_coalesce_rules *rule;
|
struct cfg80211_coalesce_rules *rule;
|
||||||
|
|
||||||
@ -13908,13 +13907,13 @@ void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
|
|||||||
|
|
||||||
for (i = 0; i < coalesce->n_rules; i++) {
|
for (i = 0; i < coalesce->n_rules; i++) {
|
||||||
rule = &coalesce->rules[i];
|
rule = &coalesce->rules[i];
|
||||||
|
if (!rule)
|
||||||
|
continue;
|
||||||
for (j = 0; j < rule->n_patterns; j++)
|
for (j = 0; j < rule->n_patterns; j++)
|
||||||
kfree(rule->patterns[j].mask);
|
kfree(rule->patterns[j].mask);
|
||||||
kfree(rule->patterns);
|
kfree(rule->patterns);
|
||||||
}
|
}
|
||||||
kfree(coalesce->rules);
|
|
||||||
kfree(coalesce);
|
kfree(coalesce);
|
||||||
rdev->coalesce = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
|
static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
|
||||||
@ -14012,17 +14011,16 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
|
|||||||
{
|
{
|
||||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||||
const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
|
const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
|
||||||
struct cfg80211_coalesce new_coalesce = {};
|
struct cfg80211_coalesce *new_coalesce;
|
||||||
struct cfg80211_coalesce *n_coalesce;
|
int err, rem_rule, n_rules = 0, i;
|
||||||
int err, rem_rule, n_rules = 0, i, j;
|
|
||||||
struct nlattr *rule;
|
struct nlattr *rule;
|
||||||
struct cfg80211_coalesce_rules *tmp_rule;
|
|
||||||
|
|
||||||
if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
|
if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
|
if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
|
||||||
cfg80211_rdev_free_coalesce(rdev);
|
cfg80211_free_coalesce(rdev->coalesce);
|
||||||
|
rdev->coalesce = NULL;
|
||||||
rdev_set_coalesce(rdev, NULL);
|
rdev_set_coalesce(rdev, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -14033,47 +14031,34 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
|
|||||||
if (n_rules > coalesce->n_rules)
|
if (n_rules > coalesce->n_rules)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
|
new_coalesce = kzalloc(struct_size(new_coalesce, rules, n_rules),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!new_coalesce.rules)
|
if (!new_coalesce)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
new_coalesce.n_rules = n_rules;
|
new_coalesce->n_rules = n_rules;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
|
nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
|
||||||
rem_rule) {
|
rem_rule) {
|
||||||
err = nl80211_parse_coalesce_rule(rdev, rule,
|
err = nl80211_parse_coalesce_rule(rdev, rule,
|
||||||
&new_coalesce.rules[i]);
|
&new_coalesce->rules[i]);
|
||||||
if (err)
|
if (err)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = rdev_set_coalesce(rdev, &new_coalesce);
|
err = rdev_set_coalesce(rdev, new_coalesce);
|
||||||
if (err)
|
if (err)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
|
cfg80211_free_coalesce(rdev->coalesce);
|
||||||
if (!n_coalesce) {
|
rdev->coalesce = new_coalesce;
|
||||||
err = -ENOMEM;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
cfg80211_rdev_free_coalesce(rdev);
|
|
||||||
rdev->coalesce = n_coalesce;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
for (i = 0; i < new_coalesce.n_rules; i++) {
|
cfg80211_free_coalesce(new_coalesce);
|
||||||
tmp_rule = &new_coalesce.rules[i];
|
|
||||||
if (!tmp_rule)
|
|
||||||
continue;
|
|
||||||
for (j = 0; j < tmp_rule->n_patterns; j++)
|
|
||||||
kfree(tmp_rule->patterns[j].mask);
|
|
||||||
kfree(tmp_rule->patterns);
|
|
||||||
}
|
|
||||||
kfree(new_coalesce.rules);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
/*
|
/*
|
||||||
* Portions of this file
|
* Portions of this file
|
||||||
* Copyright (C) 2018, 2020-2022 Intel Corporation
|
* Copyright (C) 2018, 2020-2024 Intel Corporation
|
||||||
*/
|
*/
|
||||||
#ifndef __NET_WIRELESS_NL80211_H
|
#ifndef __NET_WIRELESS_NL80211_H
|
||||||
#define __NET_WIRELESS_NL80211_H
|
#define __NET_WIRELESS_NL80211_H
|
||||||
@ -119,7 +119,7 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
|
|||||||
|
|
||||||
void nl80211_send_ap_stopped(struct wireless_dev *wdev, unsigned int link_id);
|
void nl80211_send_ap_stopped(struct wireless_dev *wdev, unsigned int link_id);
|
||||||
|
|
||||||
void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev);
|
void cfg80211_free_coalesce(struct cfg80211_coalesce *coalesce);
|
||||||
|
|
||||||
/* peer measurement */
|
/* peer measurement */
|
||||||
int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info);
|
int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info);
|
||||||
|
Loading…
Reference in New Issue
Block a user