Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mac80211: fix throughput LED trigger

The codepaths for rx with decap offload and tx with itxq were not updating
the counters for the throughput led trigger.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20211113063415.55147-1-nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Felix Fietkau and committed by
Johannes Berg
30f6cf96 6dd23603

+23 -26
+4 -4
net/mac80211/led.h
··· 72 72 #endif 73 73 74 74 static inline void 75 - ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, __le16 fc, int bytes) 75 + ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, int bytes) 76 76 { 77 77 #ifdef CONFIG_MAC80211_LEDS 78 - if (ieee80211_is_data(fc) && atomic_read(&local->tpt_led_active)) 78 + if (atomic_read(&local->tpt_led_active)) 79 79 local->tpt_led_trigger->tx_bytes += bytes; 80 80 #endif 81 81 } 82 82 83 83 static inline void 84 - ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, __le16 fc, int bytes) 84 + ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, int bytes) 85 85 { 86 86 #ifdef CONFIG_MAC80211_LEDS 87 - if (ieee80211_is_data(fc) && atomic_read(&local->tpt_led_active)) 87 + if (atomic_read(&local->tpt_led_active)) 88 88 local->tpt_led_trigger->rx_bytes += bytes; 89 89 #endif 90 90 }
+4 -3
net/mac80211/rx.c
··· 4864 4864 struct ieee80211_rate *rate = NULL; 4865 4865 struct ieee80211_supported_band *sband; 4866 4866 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 4867 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 4867 4868 4868 4869 WARN_ON_ONCE(softirq_count() == 0); 4869 4870 ··· 4961 4960 if (!(status->flag & RX_FLAG_8023)) 4962 4961 skb = ieee80211_rx_monitor(local, skb, rate); 4963 4962 if (skb) { 4964 - ieee80211_tpt_led_trig_rx(local, 4965 - ((struct ieee80211_hdr *)skb->data)->frame_control, 4966 - skb->len); 4963 + if ((status->flag & RX_FLAG_8023) || 4964 + ieee80211_is_data_present(hdr->frame_control)) 4965 + ieee80211_tpt_led_trig_rx(local, skb->len); 4967 4966 4968 4967 if (status->flag & RX_FLAG_8023) 4969 4968 __ieee80211_rx_handle_8023(hw, pubsta, skb, list);
+15 -19
net/mac80211/tx.c
··· 1721 1721 * Returns false if the frame couldn't be transmitted but was queued instead. 1722 1722 */ 1723 1723 static bool __ieee80211_tx(struct ieee80211_local *local, 1724 - struct sk_buff_head *skbs, int led_len, 1725 - struct sta_info *sta, bool txpending) 1724 + struct sk_buff_head *skbs, struct sta_info *sta, 1725 + bool txpending) 1726 1726 { 1727 1727 struct ieee80211_tx_info *info; 1728 1728 struct ieee80211_sub_if_data *sdata; 1729 1729 struct ieee80211_vif *vif; 1730 1730 struct sk_buff *skb; 1731 1731 bool result; 1732 - __le16 fc; 1733 1732 1734 1733 if (WARN_ON(skb_queue_empty(skbs))) 1735 1734 return true; 1736 1735 1737 1736 skb = skb_peek(skbs); 1738 - fc = ((struct ieee80211_hdr *)skb->data)->frame_control; 1739 1737 info = IEEE80211_SKB_CB(skb); 1740 1738 sdata = vif_to_sdata(info->control.vif); 1741 1739 if (sta && !sta->uploaded) ··· 1766 1768 } 1767 1769 1768 1770 result = ieee80211_tx_frags(local, vif, sta, skbs, txpending); 1769 - 1770 - ieee80211_tpt_led_trig_tx(local, fc, led_len); 1771 1771 1772 1772 WARN_ON_ONCE(!skb_queue_empty(skbs)); 1773 1773 ··· 1916 1920 ieee80211_tx_result res_prepare; 1917 1921 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1918 1922 bool result = true; 1919 - int led_len; 1920 1923 1921 1924 if (unlikely(skb->len < 10)) { 1922 1925 dev_kfree_skb(skb); ··· 1923 1928 } 1924 1929 1925 1930 /* initialises tx */ 1926 - led_len = skb->len; 1927 1931 res_prepare = ieee80211_tx_prepare(sdata, &tx, sta, skb); 1928 1932 1929 1933 if (unlikely(res_prepare == TX_DROP)) { ··· 1945 1951 return true; 1946 1952 1947 1953 if (!invoke_tx_handlers_late(&tx)) 1948 - result = __ieee80211_tx(local, &tx.skbs, led_len, 1949 - tx.sta, txpending); 1954 + result = __ieee80211_tx(local, &tx.skbs, tx.sta, txpending); 1950 1955 1951 1956 return result; 1952 1957 } ··· 4168 4175 struct ieee80211_local *local = sdata->local; 4169 4176 struct sta_info *sta; 4170 4177 struct sk_buff *next; 4178 + int len = skb->len; 4171 4179 4172 4180 if (unlikely(skb->len < ETH_HLEN)) { 4173 4181 kfree_skb(skb); ··· 4215 4221 } 4216 4222 } else { 4217 4223 /* we cannot process non-linear frames on this path */ 4218 - if (skb_linearize(skb)) { 4219 - kfree_skb(skb); 4220 - goto out; 4221 - } 4224 + if (skb_linearize(skb)) 4225 + goto out_free; 4222 4226 4223 4227 /* the frame could be fragmented, software-encrypted, and other 4224 4228 * things so we cannot really handle checksum offload with it - ··· 4250 4258 goto out; 4251 4259 out_free: 4252 4260 kfree_skb(skb); 4261 + len = 0; 4253 4262 out: 4263 + if (len) 4264 + ieee80211_tpt_led_trig_tx(local, len); 4254 4265 rcu_read_unlock(); 4255 4266 } 4256 4267 ··· 4391 4396 } 4392 4397 4393 4398 static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, 4394 - struct sk_buff *skb, int led_len, 4395 - struct sta_info *sta, 4399 + struct sk_buff *skb, struct sta_info *sta, 4396 4400 bool txpending) 4397 4401 { 4398 4402 struct ieee80211_local *local = sdata->local; ··· 4403 4409 4404 4410 if (sta) 4405 4411 sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift); 4412 + 4413 + ieee80211_tpt_led_trig_tx(local, skb->len); 4406 4414 4407 4415 if (ieee80211_queue_skb(local, sdata, sta, skb)) 4408 4416 return true; ··· 4494 4498 if (key) 4495 4499 info->control.hw_key = &key->conf; 4496 4500 4497 - ieee80211_tx_8023(sdata, skb, skb->len, sta, false); 4501 + ieee80211_tx_8023(sdata, skb, sta, false); 4498 4502 4499 4503 return; 4500 4504 ··· 4633 4637 if (IS_ERR(sta) || (sta && !sta->uploaded)) 4634 4638 sta = NULL; 4635 4639 4636 - result = ieee80211_tx_8023(sdata, skb, skb->len, sta, true); 4640 + result = ieee80211_tx_8023(sdata, skb, sta, true); 4637 4641 } else { 4638 4642 struct sk_buff_head skbs; 4639 4643 ··· 4643 4647 hdr = (struct ieee80211_hdr *)skb->data; 4644 4648 sta = sta_info_get(sdata, hdr->addr1); 4645 4649 4646 - result = __ieee80211_tx(local, &skbs, skb->len, sta, true); 4650 + result = __ieee80211_tx(local, &skbs, sta, true); 4647 4651 } 4648 4652 4649 4653 return result;