Skip to content

Commit

Permalink
Merge tag 'mac80211-for-net-2019-10-16' of git://git.kernel.org/pub/s…
Browse files Browse the repository at this point in the history
…cm/linux/kernel/git/jberg/mac80211

Johannes Berg says:

====================
A handful of fixes:
 * disable AQL on most drivers, addressing the iwlwifi issues
 * fix double-free on network namespace changes
 * fix TID field in frames injected through monitor interfaces
 * fix ieee80211_calc_rx_airtime()
 * fix NULL pointer dereference in rfkill (and remove BUG_ON)
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Dec 17, 2019
2 parents 95bed1a + 6fc232d commit ad125c6
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 27 deletions.
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath10k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -8958,6 +8958,7 @@ int ath10k_mac_register(struct ath10k *ar)
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
wiphy_ext_feature_set(ar->hw->wiphy,
NL80211_EXT_FEATURE_SET_SCAN_DWELL);
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_AQL);

if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map) ||
test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, ar->wmi.svc_map))
Expand Down
5 changes: 5 additions & 0 deletions include/uapi/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -5517,6 +5517,10 @@ enum nl80211_feature_flags {
* with VLAN tagged frames and separate VLAN-specific netdevs added using
* vconfig similarly to the Ethernet case.
*
* @NL80211_EXT_FEATURE_AQL: The driver supports the Airtime Queue Limit (AQL)
* feature, which prevents bufferbloat by using the expected transmission
* time to limit the amount of data buffered in the hardware.
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
Expand Down Expand Up @@ -5563,6 +5567,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_STA_TX_PWR,
NL80211_EXT_FEATURE_SAE_OFFLOAD,
NL80211_EXT_FEATURE_VLAN_OFFLOAD,
NL80211_EXT_FEATURE_AQL,

/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
Expand Down
2 changes: 1 addition & 1 deletion net/mac80211/airtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
return 0;

sband = hw->wiphy->bands[status->band];
if (!sband || status->rate_idx > sband->n_bitrates)
if (!sband || status->rate_idx >= sband->n_bitrates)
return 0;

rate = &sband->bitrates[status->rate_idx];
Expand Down
76 changes: 58 additions & 18 deletions net/mac80211/debugfs_sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,6 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
u64 rx_airtime = 0, tx_airtime = 0;
s64 deficit[IEEE80211_NUM_ACS];
u32 q_depth[IEEE80211_NUM_ACS];
u32 q_limit_l[IEEE80211_NUM_ACS], q_limit_h[IEEE80211_NUM_ACS];
ssize_t rv;
int ac;

Expand All @@ -214,19 +212,65 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
rx_airtime += sta->airtime[ac].rx_airtime;
tx_airtime += sta->airtime[ac].tx_airtime;
deficit[ac] = sta->airtime[ac].deficit;
spin_unlock_bh(&local->active_txq_lock[ac]);
}

p += scnprintf(p, bufsz + buf - p,
"RX: %llu us\nTX: %llu us\nWeight: %u\n"
"Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
rx_airtime, tx_airtime, sta->airtime_weight,
deficit[0], deficit[1], deficit[2], deficit[3]);

rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
kfree(buf);
return rv;
}

static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
size_t count, loff_t *ppos)
{
struct sta_info *sta = file->private_data;
struct ieee80211_local *local = sta->sdata->local;
int ac;

for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
spin_lock_bh(&local->active_txq_lock[ac]);
sta->airtime[ac].rx_airtime = 0;
sta->airtime[ac].tx_airtime = 0;
sta->airtime[ac].deficit = sta->airtime_weight;
spin_unlock_bh(&local->active_txq_lock[ac]);
}

return count;
}
STA_OPS_RW(airtime);

static ssize_t sta_aql_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct sta_info *sta = file->private_data;
struct ieee80211_local *local = sta->sdata->local;
size_t bufsz = 400;
char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
u32 q_depth[IEEE80211_NUM_ACS];
u32 q_limit_l[IEEE80211_NUM_ACS], q_limit_h[IEEE80211_NUM_ACS];
ssize_t rv;
int ac;

if (!buf)
return -ENOMEM;

for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
spin_lock_bh(&local->active_txq_lock[ac]);
q_limit_l[ac] = sta->airtime[ac].aql_limit_low;
q_limit_h[ac] = sta->airtime[ac].aql_limit_high;
spin_unlock_bh(&local->active_txq_lock[ac]);
q_depth[ac] = atomic_read(&sta->airtime[ac].aql_tx_pending);
}

p += scnprintf(p, bufsz + buf - p,
"RX: %llu us\nTX: %llu us\nWeight: %u\n"
"Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n"
"Q depth: VO: %u us VI: %u us BE: %u us BK: %u us\n"
"Q limit[low/high]: VO: %u/%u VI: %u/%u BE: %u/%u BK: %u/%u\n",
rx_airtime, tx_airtime, sta->airtime_weight,
deficit[0], deficit[1], deficit[2], deficit[3],
q_depth[0], q_depth[1], q_depth[2], q_depth[3],
q_limit_l[0], q_limit_h[0], q_limit_l[1], q_limit_h[1],
q_limit_l[2], q_limit_h[2], q_limit_l[3], q_limit_h[3]),
Expand All @@ -236,11 +280,10 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
return rv;
}

static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
static ssize_t sta_aql_write(struct file *file, const char __user *userbuf,
size_t count, loff_t *ppos)
{
struct sta_info *sta = file->private_data;
struct ieee80211_local *local = sta->sdata->local;
u32 ac, q_limit_l, q_limit_h;
char _buf[100] = {}, *buf = _buf;

Expand All @@ -251,7 +294,7 @@ static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
return -EFAULT;

buf[sizeof(_buf) - 1] = '\0';
if (sscanf(buf, "queue limit %u %u %u", &ac, &q_limit_l, &q_limit_h)
if (sscanf(buf, "limit %u %u %u", &ac, &q_limit_l, &q_limit_h)
!= 3)
return -EINVAL;

Expand All @@ -261,17 +304,10 @@ static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
sta->airtime[ac].aql_limit_low = q_limit_l;
sta->airtime[ac].aql_limit_high = q_limit_h;

for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
spin_lock_bh(&local->active_txq_lock[ac]);
sta->airtime[ac].rx_airtime = 0;
sta->airtime[ac].tx_airtime = 0;
sta->airtime[ac].deficit = sta->airtime_weight;
spin_unlock_bh(&local->active_txq_lock[ac]);
}

return count;
}
STA_OPS_RW(airtime);
STA_OPS_RW(aql);


static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
Expand Down Expand Up @@ -996,6 +1032,10 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
DEBUGFS_ADD(airtime);

if (wiphy_ext_feature_isset(local->hw.wiphy,
NL80211_EXT_FEATURE_AQL))
DEBUGFS_ADD(aql);

debugfs_create_xul("driver_buffered_tids", 0400, sta->debugfs_dir,
&sta->driver_buffered_tids);

Expand Down
4 changes: 1 addition & 3 deletions net/mac80211/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -672,9 +672,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H;
}

local->airtime_flags = AIRTIME_USE_TX |
AIRTIME_USE_RX |
AIRTIME_USE_AQL;
local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
local->aql_threshold = IEEE80211_AQL_THRESHOLD;
atomic_set(&local->aql_total_pending_airtime, 0);

Expand Down
3 changes: 3 additions & 0 deletions net/mac80211/sta_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -1916,6 +1916,9 @@ void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
{
int tx_pending;

if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
return;

if (!tx_completed) {
if (sta)
atomic_add(tx_airtime,
Expand Down
1 change: 0 additions & 1 deletion net/mac80211/sta_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ enum ieee80211_agg_stop_reason {
/* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */
#define AIRTIME_USE_TX BIT(0)
#define AIRTIME_USE_RX BIT(1)
#define AIRTIME_USE_AQL BIT(2)

struct airtime_info {
u64 rx_airtime;
Expand Down
13 changes: 11 additions & 2 deletions net/mac80211/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2256,6 +2256,15 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
payload[7]);
}

/*
* Initialize skb->priority for QoS frames. This is put in the TID field
* of the frame before passing it to the driver.
*/
if (ieee80211_is_data_qos(hdr->frame_control)) {
u8 *p = ieee80211_get_qos_ctl(hdr);
skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
}

memset(info, 0, sizeof(*info));

info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
Expand Down Expand Up @@ -3668,7 +3677,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,

IEEE80211_SKB_CB(skb)->control.vif = vif;

if (local->airtime_flags & AIRTIME_USE_AQL) {
if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
u32 airtime;

airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
Expand Down Expand Up @@ -3790,7 +3799,7 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
struct sta_info *sta;
struct ieee80211_local *local = hw_to_local(hw);

if (!(local->airtime_flags & AIRTIME_USE_AQL))
if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
return true;

if (!txq->sta)
Expand Down
7 changes: 5 additions & 2 deletions net/rfkill/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1002,10 +1002,13 @@ static void rfkill_sync_work(struct work_struct *work)
int __must_check rfkill_register(struct rfkill *rfkill)
{
static unsigned long rfkill_no;
struct device *dev = &rfkill->dev;
struct device *dev;
int error;

BUG_ON(!rfkill);
if (!rfkill)
return -EINVAL;

dev = &rfkill->dev;

mutex_lock(&rfkill_global_mutex);

Expand Down
1 change: 1 addition & 0 deletions net/wireless/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,7 @@ static void __cfg80211_unregister_wdev(struct wireless_dev *wdev, bool sync)

#ifdef CONFIG_CFG80211_WEXT
kzfree(wdev->wext.keys);
wdev->wext.keys = NULL;
#endif
/* only initialized if we have a netdev */
if (wdev->netdev)
Expand Down

0 comments on commit ad125c6

Please sign in to comment.