wifi: mac80211: allocate backup ieee80211_nan_sched_cfg off stack
PATCH 1/1 wifi: mac80211: allocate backup ieee80211_nan_sched_cfg off stack
From: Arnd Bergmann <[email protected]>
The ieee80211_nan_sched_cfg structure is too large to keep on the per thread stack:
net/mac80211/nan.c:251:5: error: stack frame size (1560) exceeds limit (1536) in 'ieee80211_nan_set_local_sched' [-Werror,-Wframe-larger-than]
251 | int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata,
Allocate this dynamically using kmalloc_obj() to reduce the stack usage of this function to a manageable 344 bytes for the same configuration.
Fixes 589c06e8fdee ("wifi: mac80211: add NAN local schedule support")
Signed-off-by Arnd Bergmann <[email protected]>
--- net/mac80211/nan.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-)
net/mac80211/nan.c +19 -16
@@ -253,9 +253,12 @@ int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata, {struct ieee80211_nan_channel *sched_idx_to_chan[IEEE80211_NAN_MAX_CHANNELS ] = {};struct ieee80211_nan_sched_cfg *sched_cfg = &sdata->vif.cfg.nan_sched; -struct ieee80211_nan_sched_cfg backup_sched; + struct ieee80211_nan_sched_cfg *backup_sched __free(kfree) = kmalloc_obj(*backup_sched);int ret; +if (!backup_sched) +return -ENOMEM ; +if (sched->n_channels >IEEE80211_NAN_MAX_CHANNELS )return -EOPNOTSUPP ;
@@ -275,13 +278,13 @@ int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata,bitmap_zero (sdata->u.nan.removed_channels,IEEE80211_NAN_MAX_CHANNELS ); -memcpy (backup_sched.schedule, sched_cfg->schedule, -sizeof (backup_sched.schedule)); -memcpy (backup_sched.channels, sched_cfg->channels, -sizeof (backup_sched.channels)); -memcpy (backup_sched.avail_blob, sched_cfg->avail_blob, -sizeof (backup_sched.avail_blob)); - backup_sched.avail_blob_len = sched_cfg->avail_blob_len; +memcpy (backup_sched->schedule, sched_cfg->schedule, +sizeof (backup_sched->schedule)); +memcpy (backup_sched->channels, sched_cfg->channels, +sizeof (backup_sched->channels)); +memcpy (backup_sched->avail_blob, sched_cfg->avail_blob, +sizeof (backup_sched->avail_blob)); + backup_sched->avail_blob_len = sched_cfg->avail_blob_len;memcpy (sched_cfg->avail_blob, sched->nan_avail_blob, sched->nan_avail_blob_len);
@@ -380,17 +383,17 @@ int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata,if (!chan_def->chan)continue ; -if (!cfg80211_chandef_identical (&backup_sched.channels[i].chanreq.oper, +if (!cfg80211_chandef_identical (&backup_sched->channels[i].chanreq.oper, chan_def))ieee80211_nan_remove_channel (sdata, &sched_cfg->channels[i]); }/* Re-add all backed up channels */ -for (int i =0 ; i <ARRAY_SIZE (backup_sched.channels); i++) { +for (int i =0 ; i <ARRAY_SIZE (backup_sched->channels); i++) {struct ieee80211_nan_channel *chan = &sched_cfg->channels[i]; - *chan = backup_sched.channels[i]; + *chan = backup_sched->channels[i];/* * For deferred update, no channels were removed and the channel
@@ -421,11 +424,11 @@ int ieee80211_nan_set_local_sched(struct ieee80211_sub_if_data *sdata, } } -memcpy (sched_cfg->schedule, backup_sched.schedule, -sizeof (backup_sched.schedule)); -memcpy (sched_cfg->avail_blob, backup_sched.avail_blob, -sizeof (backup_sched.avail_blob)); - sched_cfg->avail_blob_len = backup_sched.avail_blob_len; +memcpy (sched_cfg->schedule, backup_sched->schedule, +sizeof (backup_sched->schedule)); +memcpy (sched_cfg->avail_blob, backup_sched->avail_blob, +sizeof (backup_sched->avail_blob)); + sched_cfg->avail_blob_len = backup_sched->avail_blob_len; sched_cfg->deferred = false;bitmap_zero (sdata->u.nan.removed_channels,IEEE80211_NAN_MAX_CHANNELS );
Signature · 1 line
2.39.5