mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-06-21 15:43:21 +02:00
wifi: mac80211: fold tid_ampdu_rx allocations into a flexible array
Convert the separately-allocated reorder_buf pointer to a C99 flexible array member at the end of struct tid_ampdu_rx, with both the sk_buff_head and the jiffies timestamp in each array element. This collapses three allocations into one and removes the corresponding kfree() pairs from the error and free paths. Assisted-by: opencode:big-pickle Signed-off-by: Rosen Penev <rosenp@gmail.com> Link: https://patch.msgid.link/20260605005627.317194-1-rosenp@gmail.com [fix kernel-doc] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
committed by
Johannes Berg
parent
c52b144225
commit
b978c424cb
+3
-19
@@ -49,9 +49,7 @@ static void ieee80211_free_tid_rx(struct rcu_head *h)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tid_rx->buf_size; i++)
|
||||
__skb_queue_purge(&tid_rx->reorder_buf[i]);
|
||||
kfree(tid_rx->reorder_buf);
|
||||
kfree(tid_rx->reorder_time);
|
||||
__skb_queue_purge(&tid_rx->reorder[i].buf);
|
||||
kfree(tid_rx);
|
||||
}
|
||||
|
||||
@@ -412,7 +410,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||
}
|
||||
|
||||
/* prepare A-MPDU MLME for Rx aggregation */
|
||||
tid_agg_rx = kzalloc_obj(*tid_agg_rx);
|
||||
tid_agg_rx = kzalloc_flex(*tid_agg_rx, reorder, buf_size);
|
||||
if (!tid_agg_rx)
|
||||
goto end;
|
||||
|
||||
@@ -426,27 +424,13 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||
timer_setup(&tid_agg_rx->reorder_timer,
|
||||
sta_rx_agg_reorder_timer_expired, 0);
|
||||
|
||||
/* prepare reordering buffer */
|
||||
tid_agg_rx->reorder_buf =
|
||||
kzalloc_objs(struct sk_buff_head, buf_size);
|
||||
tid_agg_rx->reorder_time =
|
||||
kcalloc(buf_size, sizeof(unsigned long), GFP_KERNEL);
|
||||
if (!tid_agg_rx->reorder_buf || !tid_agg_rx->reorder_time) {
|
||||
kfree(tid_agg_rx->reorder_buf);
|
||||
kfree(tid_agg_rx->reorder_time);
|
||||
kfree(tid_agg_rx);
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i = 0; i < buf_size; i++)
|
||||
__skb_queue_head_init(&tid_agg_rx->reorder_buf[i]);
|
||||
__skb_queue_head_init(&tid_agg_rx->reorder[i].buf);
|
||||
|
||||
ret = drv_ampdu_action(local, sta->sdata, ¶ms);
|
||||
ht_dbg(sta->sdata, "Rx A-MPDU request on %pM tid %d result %d\n",
|
||||
sta->sta.addr, tid, ret);
|
||||
if (ret) {
|
||||
kfree(tid_agg_rx->reorder_buf);
|
||||
kfree(tid_agg_rx->reorder_time);
|
||||
kfree(tid_agg_rx);
|
||||
goto end;
|
||||
}
|
||||
|
||||
+7
-7
@@ -1188,7 +1188,7 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
|
||||
static inline bool ieee80211_rx_reorder_ready(struct tid_ampdu_rx *tid_agg_rx,
|
||||
int index)
|
||||
{
|
||||
struct sk_buff_head *frames = &tid_agg_rx->reorder_buf[index];
|
||||
struct sk_buff_head *frames = &tid_agg_rx->reorder[index].buf;
|
||||
struct sk_buff *tail = skb_peek_tail(frames);
|
||||
struct ieee80211_rx_status *status;
|
||||
|
||||
@@ -1211,7 +1211,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
|
||||
int index,
|
||||
struct sk_buff_head *frames)
|
||||
{
|
||||
struct sk_buff_head *skb_list = &tid_agg_rx->reorder_buf[index];
|
||||
struct sk_buff_head *skb_list = &tid_agg_rx->reorder[index].buf;
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_rx_status *status;
|
||||
|
||||
@@ -1290,14 +1290,14 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
|
||||
continue;
|
||||
}
|
||||
if (skipped &&
|
||||
!time_after(jiffies, tid_agg_rx->reorder_time[j] +
|
||||
!time_after(jiffies, tid_agg_rx->reorder[j].time +
|
||||
HT_RX_REORDER_BUF_TIMEOUT))
|
||||
goto set_release_timer;
|
||||
|
||||
/* don't leave incomplete A-MSDUs around */
|
||||
for (i = (index + 1) % tid_agg_rx->buf_size; i != j;
|
||||
i = (i + 1) % tid_agg_rx->buf_size)
|
||||
__skb_queue_purge(&tid_agg_rx->reorder_buf[i]);
|
||||
__skb_queue_purge(&tid_agg_rx->reorder[i].buf);
|
||||
|
||||
ht_dbg_ratelimited(sdata,
|
||||
"release an RX reorder frame due to timeout on earlier frames\n");
|
||||
@@ -1331,7 +1331,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
if (!tid_agg_rx->removed)
|
||||
mod_timer(&tid_agg_rx->reorder_timer,
|
||||
tid_agg_rx->reorder_time[j] + 1 +
|
||||
tid_agg_rx->reorder[j].time + 1 +
|
||||
HT_RX_REORDER_BUF_TIMEOUT);
|
||||
} else {
|
||||
timer_delete(&tid_agg_rx->reorder_timer);
|
||||
@@ -1426,9 +1426,9 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
|
||||
}
|
||||
|
||||
/* put the frame in the reordering buffer */
|
||||
__skb_queue_tail(&tid_agg_rx->reorder_buf[index], skb);
|
||||
__skb_queue_tail(&tid_agg_rx->reorder[index].buf, skb);
|
||||
if (!(status->flag & RX_FLAG_AMSDU_MORE)) {
|
||||
tid_agg_rx->reorder_time[index] = jiffies;
|
||||
tid_agg_rx->reorder[index].time = jiffies;
|
||||
tid_agg_rx->stored_mpdu_num++;
|
||||
ieee80211_sta_reorder_release(sdata, tid_agg_rx, frames);
|
||||
}
|
||||
|
||||
@@ -207,11 +207,8 @@ struct tid_ampdu_tx {
|
||||
/**
|
||||
* struct tid_ampdu_rx - TID aggregation information (Rx).
|
||||
*
|
||||
* @reorder_buf: buffer to reorder incoming aggregated MPDUs. An MPDU may be an
|
||||
* A-MSDU with individually reported subframes.
|
||||
* @reorder_buf_filtered: bitmap indicating where there are filtered frames in
|
||||
* the reorder buffer that should be ignored when releasing frames
|
||||
* @reorder_time: jiffies when skb was added
|
||||
* @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
|
||||
* @reorder_timer: releases expired frames from the reorder buffer.
|
||||
* @sta: station we are attached to
|
||||
@@ -228,6 +225,10 @@ struct tid_ampdu_tx {
|
||||
* and ssn.
|
||||
* @removed: this session is removed (but might have been found due to RCU)
|
||||
* @started: this session has started (head ssn or higher was received)
|
||||
* @reorder: reorder buffer entries
|
||||
* @reorder.buf: &struct sk_buff_head for the frames, since there could be
|
||||
* multiple at each entry from an A-MSDU reported as individual subframes
|
||||
* @reorder.time: time when this entry was filled (jiffies)
|
||||
*
|
||||
* This structure's lifetime is managed by RCU, assignments to
|
||||
* the array holding it must hold the aggregation mutex.
|
||||
@@ -241,8 +242,6 @@ struct tid_ampdu_rx {
|
||||
struct rcu_head rcu_head;
|
||||
spinlock_t reorder_lock;
|
||||
u64 reorder_buf_filtered;
|
||||
struct sk_buff_head *reorder_buf;
|
||||
unsigned long *reorder_time;
|
||||
struct sta_info *sta;
|
||||
struct timer_list session_timer;
|
||||
struct timer_list reorder_timer;
|
||||
@@ -256,6 +255,10 @@ struct tid_ampdu_rx {
|
||||
u8 auto_seq:1,
|
||||
removed:1,
|
||||
started:1;
|
||||
struct {
|
||||
struct sk_buff_head buf;
|
||||
unsigned long time;
|
||||
} reorder[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user