Commit 07bd1c79 authored by Johannes Berg's avatar Johannes Berg

mac80211: refactor SKB queue processing a bit

This is a very long loop body, move it into its own function
instead, keeping only the kcov and free outside in the loop
body.

Link: https://lore.kernel.org/r/20210517230754.6bc6cdd68570.I28a86ebdb19601ca1965c4dc654cc49fc1064efa@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 0044cc17
...@@ -1318,30 +1318,15 @@ static void ieee80211_if_setup_no_queue(struct net_device *dev) ...@@ -1318,30 +1318,15 @@ static void ieee80211_if_setup_no_queue(struct net_device *dev)
dev->priv_flags |= IFF_NO_QUEUE; dev->priv_flags |= IFF_NO_QUEUE;
} }
static void ieee80211_iface_work(struct work_struct *work) static void ieee80211_iface_process_skb(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb)
{ {
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data, work);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct sta_info *sta;
if (!ieee80211_sdata_running(sdata))
return;
if (test_bit(SCAN_SW_SCANNING, &local->scanning))
return;
if (!ieee80211_can_run_worker(local))
return;
/* first process frames */
while ((skb = skb_dequeue(&sdata->skb_queue))) {
struct ieee80211_mgmt *mgmt = (void *)skb->data; struct ieee80211_mgmt *mgmt = (void *)skb->data;
kcov_remote_start_common(skb_get_kcov_handle(skb));
if (ieee80211_is_action(mgmt->frame_control) && if (ieee80211_is_action(mgmt->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_BACK) { mgmt->u.action.category == WLAN_CATEGORY_BACK) {
struct sta_info *sta;
int len = skb->len; int len = skb->len;
mutex_lock(&local->sta_mtx); mutex_lock(&local->sta_mtx);
...@@ -1349,8 +1334,8 @@ static void ieee80211_iface_work(struct work_struct *work) ...@@ -1349,8 +1334,8 @@ static void ieee80211_iface_work(struct work_struct *work)
if (sta) { if (sta) {
switch (mgmt->u.action.u.addba_req.action_code) { switch (mgmt->u.action.u.addba_req.action_code) {
case WLAN_ACTION_ADDBA_REQ: case WLAN_ACTION_ADDBA_REQ:
ieee80211_process_addba_request( ieee80211_process_addba_request(local, sta,
local, sta, mgmt, len); mgmt, len);
break; break;
case WLAN_ACTION_ADDBA_RESP: case WLAN_ACTION_ADDBA_RESP:
ieee80211_process_addba_resp(local, sta, ieee80211_process_addba_resp(local, sta,
...@@ -1372,6 +1357,7 @@ static void ieee80211_iface_work(struct work_struct *work) ...@@ -1372,6 +1357,7 @@ static void ieee80211_iface_work(struct work_struct *work)
case WLAN_VHT_ACTION_OPMODE_NOTIF: { case WLAN_VHT_ACTION_OPMODE_NOTIF: {
struct ieee80211_rx_status *status; struct ieee80211_rx_status *status;
enum nl80211_band band; enum nl80211_band band;
struct sta_info *sta;
u8 opmode; u8 opmode;
status = IEEE80211_SKB_RXCB(skb); status = IEEE80211_SKB_RXCB(skb);
...@@ -1382,8 +1368,7 @@ static void ieee80211_iface_work(struct work_struct *work) ...@@ -1382,8 +1368,7 @@ static void ieee80211_iface_work(struct work_struct *work)
sta = sta_info_get_bss(sdata, mgmt->sa); sta = sta_info_get_bss(sdata, mgmt->sa);
if (sta) if (sta)
ieee80211_vht_handle_opmode(sdata, sta, ieee80211_vht_handle_opmode(sdata, sta, opmode,
opmode,
band); band);
mutex_unlock(&local->sta_mtx); mutex_unlock(&local->sta_mtx);
...@@ -1403,6 +1388,8 @@ static void ieee80211_iface_work(struct work_struct *work) ...@@ -1403,6 +1388,8 @@ static void ieee80211_iface_work(struct work_struct *work)
WARN_ON(1); WARN_ON(1);
} else if (ieee80211_is_data_qos(mgmt->frame_control)) { } else if (ieee80211_is_data_qos(mgmt->frame_control)) {
struct ieee80211_hdr *hdr = (void *)mgmt; struct ieee80211_hdr *hdr = (void *)mgmt;
struct sta_info *sta;
/* /*
* So the frame isn't mgmt, but frame_control * So the frame isn't mgmt, but frame_control
* is at the right place anyway, of course, so * is at the right place anyway, of course, so
...@@ -1447,6 +1434,29 @@ static void ieee80211_iface_work(struct work_struct *work) ...@@ -1447,6 +1434,29 @@ static void ieee80211_iface_work(struct work_struct *work)
WARN(1, "frame for unexpected interface type"); WARN(1, "frame for unexpected interface type");
break; break;
} }
}
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data, work);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
if (!ieee80211_sdata_running(sdata))
return;
if (test_bit(SCAN_SW_SCANNING, &local->scanning))
return;
if (!ieee80211_can_run_worker(local))
return;
/* first process frames */
while ((skb = skb_dequeue(&sdata->skb_queue))) {
kcov_remote_start_common(skb_get_kcov_handle(skb));
ieee80211_iface_process_skb(local, sdata, skb);
kfree_skb(skb); kfree_skb(skb);
kcov_remote_stop(); kcov_remote_stop();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment