[PATCH] mac80211: rewrite Kconfig text for mesh
Lubomir Rintel recently pointed out a dead link for o11s.org, and repointed it to a still live, but also stale website. As far as I know, no one is updating the content at open80211s.org. Since this Kconfig text was originally written, though, the 802.11s mesh drafts were approved and ultimately rolled into 802.11 proper. Meanwhile, the implementation has converged on the final standard, so we can lose all of the text here and provide something that's a little more helpful and accurate. Signed-off-by: Bob Copeland --- net/mac80211/Kconfig | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index f869e35d0974..6b09355dfc90 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -57,14 +57,13 @@ comment "Some wireless drivers require a rate control algorithm" depends on MAC80211 && MAC80211_HAS_RC=n config MAC80211_MESH - bool "Enable mac80211 mesh networking (pre-802.11s) support" + bool "Enable mac80211 mesh networking support" depends on MAC80211 ---help--- -This options enables support of Draft 802.11s mesh networking. -The implementation is based on Draft 2.08 of the Mesh Networking -amendment. However, no compliance with that draft is claimed or even -possible, as drafts leave a number of identifiers to be defined after -ratification. For more information visit http://o11s.org/. + Select this option to enable 802.11 mesh operation in mac80211 + drivers that support it. 802.11 mesh connects multiple stations + over (possibly multi-hop) wireless links to form a single logical + LAN. config MAC80211_LEDS bool "Enable LED triggers" -- 2.11.0
Re: mac80211_hwsim: multiple antennas
On Wed, Nov 21, 2018 at 01:30:40PM +0100, Johannes Berg wrote: > On Wed, 2018-11-21 at 09:26 -0300, Ramon Fontes wrote: > > Sorry. I meant throughput. > > Yeah, well. There's no actual medium (access) simulation in hwsim, so > the actual throughput you get only depends on the performance of your > CPU. 33Mbps seems quite low, but of course I don't know where you're > running this. > > Then again, you say you're using wmediumd, so perhaps that *does* have > some sort of medium simulation these days? I didn't think it has it but > I may very well be wrong on that. wmediumd does simulate the medium, but it only ever handled simple OFDM PHY rates, not MCS or aggregation or anything else from the last decade :) -- Bob Copeland %% https://bobcopeland.com/
[PATCH] {nl,mac}80211: add rssi to mesh candidates
When peering is in userspace, some implementations may want to control which peers are accepted based on RSSI in addition to the information elements being sent today. Add signal level so that info is available to clients. Signed-off-by: Bob Copeland --- include/net/cfg80211.h| 3 ++- net/mac80211/mesh.c | 3 ++- net/mac80211/mesh.h | 3 ++- net/mac80211/mesh_plink.c | 32 ++-- net/wireless/nl80211.c| 7 +-- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1fa41b7a1be3..2e7710adacb0 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -5328,7 +5328,8 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, * cfg80211 then sends a notification to userspace. */ void cfg80211_notify_new_peer_candidate(struct net_device *dev, - const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp); + const u8 *macaddr, const u8 *ie, u8 ie_len, + int sig_dbm, gfp_t gfp); /** * DOC: RFkill integration diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 8bad414c52ad..ea76d4dbdd49 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -1191,7 +1191,8 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, if (!sdata->u.mesh.user_mpm || sdata->u.mesh.mshcfg.rssi_threshold == 0 || sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal) - mesh_neighbour_update(sdata, mgmt->sa, ); + mesh_neighbour_update(sdata, mgmt->sa, , + rx_status); } if (ifmsh->sync_ops) diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 21526630bf65..cad6592c52a1 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -273,7 +273,8 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata); /* Mesh plinks */ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, - u8 *hw_addr, struct ieee802_11_elems *ie); + u8 *hw_addr, struct ieee802_11_elems *ie, + struct ieee80211_rx_status *rx_status); bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); void mesh_plink_timer(struct timer_list *t); diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 5b5b0f95ffd1..9e8d80533562 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -513,7 +513,8 @@ __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr) static struct sta_info * mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr, - struct ieee802_11_elems *elems) + struct ieee802_11_elems *elems, + struct ieee80211_rx_status *rx_status) { struct sta_info *sta = NULL; @@ -521,11 +522,17 @@ mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr, if (sdata->u.mesh.user_mpm || sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) { if (mesh_peer_accepts_plinks(elems) && - mesh_plink_availables(sdata)) + mesh_plink_availables(sdata)) { + int sig = 0; + + if (ieee80211_hw_check(>local->hw, SIGNAL_DBM)) + sig = rx_status->signal; + cfg80211_notify_new_peer_candidate(sdata->dev, addr, elems->ie_start, elems->total_len, - GFP_KERNEL); + sig, GFP_KERNEL); + } } else sta = __mesh_sta_info_alloc(sdata, addr); @@ -538,13 +545,15 @@ mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr, * @sdata: local meshif * @addr: peer's address * @elems: IEs from beacon or mesh peering frame. + * @rx_status: rx status for the frame for signal reporting * * Return existing or newly allocated sta_info under RCU read lock. * (re)initialize with given IEs. */ static struct sta_info * mesh_sta_info_get(struct ieee80211_sub_if_data *sdata, - u8 *addr, struct ieee802_11_elems *elems) __acquires(RCU) + u8 *addr, struct ieee802_11_elems *elems, + struct ieee80211_rx_status *rx_status) __acquires(RCU) { struct sta_info *sta = NULL; @@ -555,7 +564,7 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata, } else { rcu_read_unlock(); /* can't run atomic */ - sta = mesh_sta_info_alloc(sdata, a
[PATCH v2 3/3] {nl,mac}80211: add dot11MeshConnectedToMeshGate to meshconf
When userspace is controlling mesh routing, it may have better knowledge about whether a mesh STA is connected to a mesh gate than the kernel mpath table. Add dot11MeshConnectedToMeshGate to the mesh config so that such applications can explicitly signal that a mesh STA is connected to a gate, which will then be advertised in the beacon. Signed-off-by: Bob Copeland --- v2: add policy range and type comment include/net/cfg80211.h| 5 + include/uapi/linux/nl80211.h | 8 +++- net/mac80211/cfg.c| 3 +++ net/mac80211/debugfs_netdev.c | 3 +++ net/mac80211/mesh.c | 3 ++- net/wireless/nl80211.c| 8 +++- 6 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f2cb1a3c9651..cddaa9dacb27 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1562,6 +1562,10 @@ struct bss_parameters { * @plink_timeout: If no tx activity is seen from a STA we've established * peering with for longer than this time (in seconds), then remove it * from the STA's list of peers. Default is 30 minutes. + * @dot11MeshConnectedToMeshGate: if set to true, advertise that this STA is + * connected to a mesh gate in mesh formation info. If false, the + * value in mesh formation is determined by the presence of root paths + * in the mesh path table */ struct mesh_config { u16 dot11MeshRetryTimeout; @@ -1581,6 +1585,7 @@ struct mesh_config { u16 dot11MeshHWMPperrMinInterval; u16 dot11MeshHWMPnetDiameterTraversalTime; u8 dot11MeshHWMPRootMode; + bool dot11MeshConnectedToMeshGate; u16 dot11MeshHWMPRannInterval; bool dot11MeshGateAnnouncementProtocol; bool dot11MeshForwarding; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index f2d79f9b4b5a..ba0dc0afdc29 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -3075,7 +3075,7 @@ enum nl80211_sta_bss_param { * some packets with an FCS error due to TA corruption. Hence this counter * might not be fully accurate. * @NL80211_STA_INFO_CONNECTED_TO_GATE: set to true if STA has a path to a - * mesh gate + * mesh gate (u8, 0 or 1) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute */ @@ -3898,6 +3898,11 @@ enum nl80211_mesh_power_mode { * remove it from the STA's list of peers. You may set this to 0 to disable * the removal of the STA. Default is 30 minutes. * + * @NL80211_MESHCONF_CONNECTED_TO_GATE: If set to true then this mesh STA + * will advertise that it is connected to a gate in the mesh formation + * field. If left unset then the mesh formation field will only + * advertise such if there is an active root mesh path. + * * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use */ enum nl80211_meshconf_params { @@ -3930,6 +3935,7 @@ enum nl80211_meshconf_params { NL80211_MESHCONF_POWER_MODE, NL80211_MESHCONF_AWAKE_WINDOW, NL80211_MESHCONF_PLINK_TIMEOUT, + NL80211_MESHCONF_CONNECTED_TO_GATE, /* keep last */ __NL80211_MESHCONF_ATTR_AFTER_LAST, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 51622333d460..6d1c54f28df7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2028,6 +2028,9 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, nconf->dot11MeshAwakeWindowDuration; if (_chg_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask)) conf->plink_timeout = nconf->plink_timeout; + if (_chg_mesh_attr(NL80211_MESHCONF_CONNECTED_TO_GATE, mask)) + conf->dot11MeshConnectedToMeshGate = + nconf->dot11MeshConnectedToMeshGate; ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); return 0; } diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index c813207bb123..cff0fb3578c9 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -641,6 +641,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval, IEEE80211_IF_FILE(power_mode, u.mesh.mshcfg.power_mode, DEC); IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration, u.mesh.mshcfg.dot11MeshAwakeWindowDuration, DEC); +IEEE80211_IF_FILE(dot11MeshConnectedToMeshGate, + u.mesh.mshcfg.dot11MeshConnectedToMeshGate, DEC); #endif #define DEBUGFS_ADD_MODE(name, mode) \ @@ -762,6 +764,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval); MESHPARAMS_ADD(power_mode); MESHPARAMS_ADD(dot11MeshAwakeWindowDuration); + MESHPARAMS_ADD(dot11MeshConnectedToMeshGate); #undef MESHPARAMS_ADD } #endif diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 19205c821dee..4869280a6413 100644 --- a/net/mac80211/mesh.c +++
[PATCH 1/3] mac80211: mesh: advertise gates in mesh formation
The Connected to Mesh Gate subfield (802.11-2016 9.4.2.98.7) in the Mesh Formation Info field is currently unset. This field may be useful in determining which MBSSes to join or which mesh STAs to peer with. If this mesh STA is a gate, by having turned on mesh gate announcements, or if we have a path to one (e.g. by having received RANNs) then set this bit to 1. Signed-off-by: Bob Copeland --- net/mac80211/mesh.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 8bad414c52ad..19205c821dee 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -254,6 +254,8 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_mesh *ifmsh = >u.mesh; u8 *pos, neighbors; u8 meshconf_len = sizeof(struct ieee80211_meshconf_ie); + bool is_connected_to_gate = ifmsh->num_gates > 0 || + ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol; if (skb_tailroom(skb) < 2 + meshconf_len) return -ENOMEM; @@ -278,7 +280,7 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata, /* Mesh Formation Info - number of neighbors */ neighbors = atomic_read(>estab_plinks); neighbors = min_t(int, neighbors, IEEE80211_MAX_MESH_PEERINGS); - *pos++ = neighbors << 1; + *pos++ = (neighbors << 1) | is_connected_to_gate; /* Mesh capability */ *pos = 0x00; *pos |= ifmsh->mshcfg.dot11MeshForwarding ? -- 2.11.0
[PATCH 2/3] {nl,mac}80211: report gate connectivity in station info
Capture the current state of gate connectivity from the mesh formation field in mesh config whenever we receive a beacon, and report that via GET_STATION. This allows applications doing mesh peering in userspace to make peering decisions based on peers' current upstream connectivity. Signed-off-by: Bob Copeland --- include/linux/ieee80211.h| 2 ++ include/net/cfg80211.h | 3 +++ include/uapi/linux/nl80211.h | 3 +++ net/mac80211/mesh_plink.c| 3 +++ net/mac80211/sta_info.c | 4 +++- net/mac80211/sta_info.h | 2 ++ net/wireless/nl80211.c | 1 + 7 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 0ef67f837ae1..407d6fd66fa9 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -812,6 +812,8 @@ enum mesh_config_capab_flags { IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL = 0x40, }; +#define IEEE80211_MESHCONF_FORM_CONNECTED_TO_GATE 0x1 + /** * mesh channel switch parameters element's flag indicator * diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1fa41b7a1be3..f2cb1a3c9651 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1296,6 +1296,7 @@ struct cfg80211_tid_stats { * @rx_beacon: number of beacons received from this peer * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received * from this peer + * @connected_to_gate: true if mesh STA has a path to mesh gate * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer * @pertid: per-TID statistics, see cfg80211_tid_stats, using the last * (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs. @@ -1350,6 +1351,8 @@ struct station_info { u64 rx_beacon; u64 rx_duration; u8 rx_beacon_signal_avg; + u8 connected_to_gate; + struct cfg80211_tid_stats *pertid; s8 ack_signal; s8 avg_ack_signal; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 6d610bae30a9..f2d79f9b4b5a 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -3074,6 +3074,8 @@ enum nl80211_sta_bss_param { * with an FCS error (u32, from this station). This count may not include * some packets with an FCS error due to TA corruption. Hence this counter * might not be fully accurate. + * @NL80211_STA_INFO_CONNECTED_TO_GATE: set to true if STA has a path to a + * mesh gate * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute */ @@ -3116,6 +3118,7 @@ enum nl80211_sta_info { NL80211_STA_INFO_ACK_SIGNAL_AVG, NL80211_STA_INFO_RX_MPDUS, NL80211_STA_INFO_FCS_ERROR_COUNT, + NL80211_STA_INFO_CONNECTED_TO_GATE, /* keep last */ __NL80211_STA_INFO_AFTER_LAST, diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 5b5b0f95ffd1..5f45a2b273df 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -590,6 +590,9 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, if (!sta) goto out; + sta->mesh->connected_to_gate = elems->mesh_config->meshconf_form & + IEEE80211_MESHCONF_FORM_CONNECTED_TO_GATE; + if (mesh_peer_accepts_plinks(elems) && sta->mesh->plink_state == NL80211_PLINK_LISTEN && sdata->u.mesh.accepting_plinks && diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index fb8c2252ac0e..971f06911ff8 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2267,7 +2267,8 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, BIT_ULL(NL80211_STA_INFO_PLINK_STATE) | BIT_ULL(NL80211_STA_INFO_LOCAL_PM) | BIT_ULL(NL80211_STA_INFO_PEER_PM) | -BIT_ULL(NL80211_STA_INFO_NONPEER_PM); +BIT_ULL(NL80211_STA_INFO_NONPEER_PM) | +BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_GATE); sinfo->llid = sta->mesh->llid; sinfo->plid = sta->mesh->plid; @@ -2279,6 +2280,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, sinfo->local_pm = sta->mesh->local_pm; sinfo->peer_pm = sta->mesh->peer_pm; sinfo->nonpeer_pm = sta->mesh->nonpeer_pm; + sinfo->connected_to_gate = sta->mesh->connected_to_gate; #endif } diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 9a04327d71d1..8eb29041be54 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -364,6 +364,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8) * @nonpeer_pm: STA power save mode towards non-pe
[PATCH 3/3] {nl,mac}80211: add dot11MeshConnectedToMeshGate to meshconf
When userspace is controlling mesh routing, it may have better knowledge about whether a mesh STA is connected to a mesh gate than the kernel mpath table. Add dot11MeshConnectedToMeshGate to the mesh config so that such applications can explicitly signal that a mesh STA is connected to a gate, which will then be advertised in the beacon. Signed-off-by: Bob Copeland --- include/net/cfg80211.h| 5 + include/uapi/linux/nl80211.h | 6 ++ net/mac80211/cfg.c| 3 +++ net/mac80211/debugfs_netdev.c | 3 +++ net/mac80211/mesh.c | 3 ++- net/wireless/nl80211.c| 8 +++- 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f2cb1a3c9651..cddaa9dacb27 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1562,6 +1562,10 @@ struct bss_parameters { * @plink_timeout: If no tx activity is seen from a STA we've established * peering with for longer than this time (in seconds), then remove it * from the STA's list of peers. Default is 30 minutes. + * @dot11MeshConnectedToMeshGate: if set to true, advertise that this STA is + * connected to a mesh gate in mesh formation info. If false, the + * value in mesh formation is determined by the presence of root paths + * in the mesh path table */ struct mesh_config { u16 dot11MeshRetryTimeout; @@ -1581,6 +1585,7 @@ struct mesh_config { u16 dot11MeshHWMPperrMinInterval; u16 dot11MeshHWMPnetDiameterTraversalTime; u8 dot11MeshHWMPRootMode; + bool dot11MeshConnectedToMeshGate; u16 dot11MeshHWMPRannInterval; bool dot11MeshGateAnnouncementProtocol; bool dot11MeshForwarding; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index f2d79f9b4b5a..d04391ae4acd 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -3898,6 +3898,11 @@ enum nl80211_mesh_power_mode { * remove it from the STA's list of peers. You may set this to 0 to disable * the removal of the STA. Default is 30 minutes. * + * @NL80211_MESHCONF_CONNECTED_TO_GATE: If set to true then this mesh STA + * will advertise that it is connected to a gate in the mesh formation + * field. If left unset then the mesh formation field will only + * advertise such if there is an active root mesh path. + * * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use */ enum nl80211_meshconf_params { @@ -3930,6 +3935,7 @@ enum nl80211_meshconf_params { NL80211_MESHCONF_POWER_MODE, NL80211_MESHCONF_AWAKE_WINDOW, NL80211_MESHCONF_PLINK_TIMEOUT, + NL80211_MESHCONF_CONNECTED_TO_GATE, /* keep last */ __NL80211_MESHCONF_ATTR_AFTER_LAST, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 51622333d460..6d1c54f28df7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2028,6 +2028,9 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, nconf->dot11MeshAwakeWindowDuration; if (_chg_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask)) conf->plink_timeout = nconf->plink_timeout; + if (_chg_mesh_attr(NL80211_MESHCONF_CONNECTED_TO_GATE, mask)) + conf->dot11MeshConnectedToMeshGate = + nconf->dot11MeshConnectedToMeshGate; ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); return 0; } diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index c813207bb123..cff0fb3578c9 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -641,6 +641,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval, IEEE80211_IF_FILE(power_mode, u.mesh.mshcfg.power_mode, DEC); IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration, u.mesh.mshcfg.dot11MeshAwakeWindowDuration, DEC); +IEEE80211_IF_FILE(dot11MeshConnectedToMeshGate, + u.mesh.mshcfg.dot11MeshConnectedToMeshGate, DEC); #endif #define DEBUGFS_ADD_MODE(name, mode) \ @@ -762,6 +764,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval); MESHPARAMS_ADD(power_mode); MESHPARAMS_ADD(dot11MeshAwakeWindowDuration); + MESHPARAMS_ADD(dot11MeshConnectedToMeshGate); #undef MESHPARAMS_ADD } #endif diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 19205c821dee..4869280a6413 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -255,7 +255,8 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata, u8 *pos, neighbors; u8 meshconf_len = sizeof(struct ieee80211_meshconf_ie); bool is_connected_to_gate = ifmsh->num_gates > 0 || - ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol; + ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol || + ifmsh->mshcf
[PATCH] mac80211: fix pending queue hang due to TX_DROP
In our environment running lots of mesh nodes, we are seeing the pending queue hang periodically, with the debugfs queues file showing lines such as: 00: 0x/348 i.e. there are a large number of frames but no stop reason set. One way this could happen is if queue processing from the pending tasklet exited early without processing all frames, and without having some future event (incoming frame, stop reason flag, ...) to reschedule it. Exactly this can occur today if ieee80211_tx() returns false due to packet drops or power-save buffering in the tx handlers. In the past, this function would return true in such cases, and the change to false doesn't seem to be intentional. Fix this case by reverting to the previous behavior. Fixes: bb42f2d13ffc ("mac80211: Move reorder-sensitive TX handlers to after TXQ dequeue") Signed-off-by: Bob Copeland --- net/mac80211/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e88547842239..6b83dc397c3e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1907,7 +1907,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, sdata->vif.hw_queue[skb_get_queue_mapping(skb)]; if (invoke_tx_handlers_early()) - return false; + return true; if (ieee80211_queue_skb(local, sdata, tx.sta, tx.skb)) return true; -- 2.11.0
[PATCH] nl80211: relax ht operation checks for mesh
Commit 9757235f451c, "nl80211: correct checks for NL80211_MESHCONF_HT_OPMODE value") relaxed the range for the HT operation field in meshconf, while also adding checks requiring the non-greenfield and non-ht-sta bits to be set in certain circumstances. The latter bit is actually reserved for mesh BSSes according to Table 9-168 in 802.11-2016, so in fact it should not be set. wpa_supplicant sets these bits because the mesh and AP code share the same implementation, but authsae does not. As a result, some meshconf updates from authsae which set only the NONHT_MIXED protection bits were being rejected. In order to avoid breaking userspace by changing the rules again, simply accept the values with or without the bits set, and mask off the reserved bit to match the spec. While in here, update the 802.11-2012 reference to 802.11-2016. Fixes: 9757235f451c ("nl80211: correct checks for NL80211_MESHCONF_HT_OPMODE value") Cc: Masashi Honma Signed-off-by: Bob Copeland --- net/wireless/nl80211.c | 19 +++ 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f5e36a23cae3..c9ba4edf25cc 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5837,7 +5837,7 @@ do { \ nl80211_check_s32); /* * Check HT operation mode based on -* IEEE 802.11 2012 8.4.2.59 HT Operation element. +* IEEE 802.11-2016 9.4.2.57 HT Operation element. */ if (tb[NL80211_MESHCONF_HT_OPMODE]) { ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]); @@ -5847,22 +5847,9 @@ do { \ IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT)) return -EINVAL; - if ((ht_opmode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) && - (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT)) - return -EINVAL; + /* NON_HT_STA bit is reserved, but some programs set it */ + ht_opmode &= ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT; - switch (ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION) { - case IEEE80211_HT_OP_MODE_PROTECTION_NONE: - case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ: - if (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT) - return -EINVAL; - break; - case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER: - case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED: - if (!(ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT)) - return -EINVAL; - break; - } cfg->ht_opmode = ht_opmode; mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1)); } -- 2.9.5
Re: [PATCH] ath10k: transmit queued frames after waking queues
On Fri, May 25, 2018 at 02:36:56PM +0200, Niklas Cassel wrote: > A spin lock does have the advantage of ordering: memory operations issued > before the spin_unlock_bh() will be completed before the spin_unlock_bh() > operation has completed. > > However, ath10k_htt_tx_dec_pending() was called earlier in the same function, > which decreases htt->num_pending_tx, so that write will be completed before > our read. That is the only ordering we care about here (if we should call > ath10k_mac_tx_push_pending() or not). Sure. I also understand that reading inside a lock and operating on the value outside the lock isn't really the definition of synchronization (doesn't really matter in this case though). I was just suggesting that the implicit memory barrier in the spin unlock that we are already paying for would be sufficient here too, and it matches the semantic of "tx fields under tx_lock." On the other hand, maybe it's just me, but I tend to look askance at just-in-case READ_ONCEs sprinkled about. -- Bob Copeland %% https://bobcopeland.com/
Re: [PATCH] ath10k: transmit queued frames after waking queues
On Mon, May 21, 2018 at 10:37:01PM +0200, Niklas Cassel wrote: > On Thu, May 17, 2018 at 03:26:25PM -0700, Adrian Chadd wrote: > > On Thu, 17 May 2018 at 16:16, Niklas Cassel <niklas.cas...@linaro.org> > > wrote: > > > > > diff --git a/drivers/net/wireless/ath/ath10k/txrx.c > > b/drivers/net/wireless/ath/ath10k/txrx.c > > > index cda164f6e9f6..1d3b2d2c3fee 100644 > > > --- a/drivers/net/wireless/ath/ath10k/txrx.c > > > +++ b/drivers/net/wireless/ath/ath10k/txrx.c > > > @@ -95,6 +95,9 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, > > > wake_up(>empty_tx_wq); > > > spin_unlock_bh(>tx_lock); > > > > > + if (htt->num_pending_tx <= 3 && !list_empty(>txqs)) > > > + ath10k_mac_tx_push_pending(ar); > > > + > > > > Just sanity checking - what's protecting htt->num_pending_tx? or is it > > serialised some other way? [...] > I can't see that any of the examples applies, but let's add READ_ONCE(), > to make sure that the compiler doesn't try to optimize this. Couldn't you just move the num_pending_tx read inside tx_lock which is 2 lines above? I think all the other manipulations are protected by tx_lock. -- Bob Copeland %% https://bobcopeland.com/
[PATCH] mac80211: mesh: fix premature update of rc stats
The mesh_neighbour_update() function, queued via beacon rx, can race with userspace creating the same station. If the station already exists by the time mesh_neighbour_update() is called, the function wrongly assumes rate control has been initialized and calls rate_control_rate_update(), which in turn calls into the driver. Updating the rate control before it has been initialized can cause a crash in some drivers, for example this firmware crash in ath10k due to sta->rx_nss being 0: [ 3078.088247] mesh0: Inserted STA 5c:e2:8c:f1:ab:ba [ 3078.258407] ath10k_pci :0d:00.0: firmware crashed! (uuid d6ed5961-93cc-4d61-803f-5eda55bb8643) [ 3078.258421] ath10k_pci :0d:00.0: qca988x hw2.0 target 0x4100016c chip_id 0x043202ff sub : [ 3078.258426] ath10k_pci :0d:00.0: kconfig debug 1 debugfs 1 tracing 1 dfs 0 testmode 0 [ 3078.258608] ath10k_pci :0d:00.0: firmware ver 10.2.4.70.59-2 api 5 features no-p2p,raw-mode,mfp crc32 4159f498 [ 3078.258613] ath10k_pci :0d:00.0: board_file api 1 bmi_id N/A crc32 bebc7c08 [ 3078.258617] ath10k_pci :0d:00.0: htt-ver 2.1 wmi-op 5 htt-op 2 cal otp max-sta 128 raw 0 hwcrypto 1 [ 3078.260627] ath10k_pci :0d:00.0: firmware register dump: [ 3078.260640] ath10k_pci :0d:00.0: [00]: 0x4100016C 0x15B3 0x009A31BB 0x00955B31 [ 3078.260647] ath10k_pci :0d:00.0: [04]: 0x009A31BB 0x00060130 0x0008 0x0007 [ 3078.260652] ath10k_pci :0d:00.0: [08]: 0x 0x00955B31 0x 0x0040F89E [ 3078.260656] ath10k_pci :0d:00.0: [12]: 0x0009 0x 0x009580F5 0x00958117 [ 3078.260660] ath10k_pci :0d:00.0: [16]: 0x00958080 0x0094085D 0x 0x [ 3078.260664] ath10k_pci :0d:00.0: [20]: 0x409A31BB 0x0040AA84 0x0002 0x0001 [ 3078.260669] ath10k_pci :0d:00.0: [24]: 0x809A2B8D 0x0040AAE4 0x0088 0xC09A31BB [ 3078.260673] ath10k_pci :0d:00.0: [28]: 0x809898C8 0x0040AB04 0x0043F91C 0x009C6458 [ 3078.260677] ath10k_pci :0d:00.0: [32]: 0x809B66AC 0x0040AB34 0x009C6458 0x0043F91C [ 3078.260686] ath10k_pci :0d:00.0: [36]: 0x809B2824 0x0040ADA4 0x0040 0x00416EB4 [ 3078.260692] ath10k_pci :0d:00.0: [40]: 0x809C07D9 0x0040ADE4 0x0040AE08 0x00412028 [ 3078.260696] ath10k_pci :0d:00.0: [44]: 0x809486FA 0x0040AE04 0x0001 0x [ 3078.260700] ath10k_pci :0d:00.0: [48]: 0x80948E2C 0x0040AEA4 0x0041F4F0 0x00412634 [ 3078.260704] ath10k_pci :0d:00.0: [52]: 0x809BFC39 0x0040AEC4 0x0041F4F0 0x0001 [ 3078.260709] ath10k_pci :0d:00.0: [56]: 0x80940F18 0x0040AF14 0x0010 0x00403AC0 [ 3078.284130] ath10k_pci :0d:00.0: failed to to request monitor vdev 1 stop: -108 Fix this by checking whether the sta has already initialized rate control using the flag for that purpose. We can also drop the unnecessary insert parameter here. Signed-off-by: Bob Copeland <bobcopel...@fb.com> --- net/mac80211/mesh_plink.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 0f6c9ca..5b5b0f9 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -401,7 +401,7 @@ u32 mesh_plink_deactivate(struct sta_info *sta) static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, - struct ieee802_11_elems *elems, bool insert) + struct ieee802_11_elems *elems) { struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; @@ -447,7 +447,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, sta->sta.bandwidth = IEEE80211_STA_RX_BW_20; } - if (insert) + if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) rate_control_rate_init(sta); else rate_control_rate_update(local, sband, sta, changed); @@ -551,7 +551,7 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata, rcu_read_lock(); sta = sta_info_get(sdata, addr); if (sta) { - mesh_sta_info_init(sdata, sta, elems, false); + mesh_sta_info_init(sdata, sta, elems); } else { rcu_read_unlock(); /* can't run atomic */ @@ -561,7 +561,7 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata, return NULL; } - mesh_sta_info_init(sdata, sta, elems, true); + mesh_sta_info_init(sdata, sta, elems); if (sta_info_insert_rcu(sta)) return NULL; -- 2.9.0
Re: [PATCH for-4.13] brcmfmac: fix regression in brcmf_sdio_txpkt_hdalign()
On Wed, Jul 12, 2017 at 10:32:48AM +0100, Arend van Spriel wrote: > Recent change in brcmf_sdio_txpkt_hdalign() changed the > behavior and now always returns 0. This resulted in a > regression which basically renders the device useless. Should this go via netdev as well, or just wait for Kalle (returning on Sunday)? -- Bob Copeland %% https://bobcopeland.com/
Deleting old wireless-testing tags
Hi all, wireless-testing will resume again next week when the merge window opens, and with 203 w-t tags since I started maintaining it a little over a year ago, it's about time for some house-keeping. I plan to delete some of the older tags in the kernel.org copy. Before I do so, quick straw poll of anyone using this kernel: are there specific tags I should keep, or any specific time period I should keep them around? E.g. I believe lede/openwrt are using compat-wireless builds generated from wireless-testing; it might be worth retaining those particular tags just for reference. I guess a few folks may be using it as a development tree and would want a couple of kernel release cycles maintained, and so on. -- Bob Copeland %% http://bobcopeland.com/
Re: [PATCH] mac80211: Remove invalid flag operations in mesh TSF synchronization
On Wed, Dec 07, 2016 at 09:55:41PM +0900, Masashi Honma wrote: > >It's called mesh_sync_offset_adjust_tbtt() which matches more closely > >"TBTT adjustment" than "neighbor offset synchronization"? > > I think so. Because there is not any code creating "TBTT Adjustment Request > frame" even though the frame is required by "TBTT adjustment". This mesh_sync_offset_adjust_tbtt is definitely doing offset synchronization, so probably "tbtt" should be renamed "tsf" here. > >The code > >looks more like offset synchronization though. Perhaps there's some > >confusing and it's kinda doing both? > > In theory, updating the flag with 1) looks not correct because it is not > clearly defined in spec. > > In practice, I could consider extending the meaning of the flag over the > spec to use it to avoid referring the updating TSF value by peer as Thomas > said. I have took the statistics how many TSF drift > (ifmsh->sync_offset_clockdrift_max) happens. The attached file shows the > stats. The horizontal axis shows TSF drift time(usec) and vertical axis > shows how many time the drift occurred. The graph shows almost drifts are > under 20usec. In contrast, 2) could causes more than 1000usec drift. So 1) > looks not so large enough to protect with the flag. Yes, offset synchronization is (given decent clocks) supposed to be only for small tweaks. We will do it up to .8 ms drift though -- above .8 ms, we just reset drift to zero and adopt the new timing offset. You can see this kind of large "drift" by restarting a station. Actually, looking at the code now it doesn't make a lot of sense to set this flag for offset sync because TOFFSET_KNOWN flag is completely cleared whenever that is set, so we have to be forgetting the current t_offset all the time? -- Bob Copeland %% http://bobcopeland.com/
Re: ath10k stuck in mesh mode
On Fri, Nov 18, 2016 at 10:43:06PM +0100, Matteo Grandi wrote: > So the question is: who decide if use MIMO and higher MCS hopefully on > 80MHz channel or not? Is the firmware? Is there a way to force the > interface to use 80MHz and/or MIMO? (iw provide the possibility to > choose between [HT20/HT40-/HT40+]). You can specify the channel width like so: iw dev wlan0 set freq 5745 80 5775 iw dev wlan0 mesh join mesh-vht -- Bob Copeland %% http://bobcopeland.com/
Re: [PATCH] mac80211: fix sequence number allocation regression
On Wed, Oct 12, 2016 at 08:49:45AM +0200, Johannes Berg wrote: > On Tue, 2016-10-11 at 11:28 +0200, Felix Fietkau wrote: > > The recent commit that moved around TX handlers dropped the sequence > > number allocation at the end of ieee80211_tx_dequeue and calls > > ieee80211_tx_h_sequence instead (for the non-fast-xmit case). > > However, it did not change the fast-xmit sequence allocation > > condition > > in ieee80211_xmit_fast_finish, which skipped seqno alloc if > > intermediate > > tx queues are being used. > > > > Drop the now obsolete condition. > > Hm. I don't know what tree you're looking at, but it looks like I *did* > in fact resolve this correctly; the (now) erroneous condition doesn't > exist in mac80211 nor in mac80211-next (nor net, net-next, linux). > > It does seem to exist in wireless-testing, but that's not something I > can control. Sorry about that, I should've rechecked this after Johannes did the merge. I applied this patch (to wireless-testing) and pushed tag wt-2016-10-12. Let me know of any further issues. As a check I also diffed against mac80211-next/master and found additional merge damage in the diff which I fixed up. Once the merge window closes in a few days, I'll resync to the masters of all the trees. -- Bob Copeland %% http://bobcopeland.com/
Re: Final 4.8 w-t build is wt-2016-10-03
On Mon, Oct 03, 2016 at 04:42:58PM +0200, Christian Lamparter wrote: > Thanks for the timely update. > I have a request: can you please pull Linus' kernel tags? > Currently the last tag from Linus' is v4.4-rc4 [0] and > everything between v4.4-rc5 and v4.8 is missing?! I've done this now. -- Bob Copeland %% http://bobcopeland.com/
Re: Final 4.8 w-t build is wt-2016-10-03
On Mon, Oct 03, 2016 at 04:42:58PM +0200, Christian Lamparter wrote: > Hello, > > On Monday, October 3, 2016 9:45:07 AM CEST Bob Copeland wrote: > > Per the subject, Linus released 4.8 yesterday so, unless I broke something > > in recent conflict resolutions, wireless-testing is on pause until the > > merge window closes in two weeks. Have a happy (Canadian) thanksgiving! > > > > https://git.kernel.org/cgit/linux/kernel/git/wireless/wireless-testing.git > > Thanks for the timely update. > I have a request: can you please pull Linus' kernel tags? > Currently the last tag from Linus' is v4.4-rc4 [0] and > everything between v4.4-rc5 and v4.8 is missing?! Sure, I can start including them. I stopped pushing them in 4.4 era because I thought it might be too cluttered to have these non-wt tags sitting around, but it's no problem to go back and push the old ones and do that going forward. -- Bob Copeland %% http://bobcopeland.com/
Final 4.8 w-t build is wt-2016-10-03
Per the subject, Linus released 4.8 yesterday so, unless I broke something in recent conflict resolutions, wireless-testing is on pause until the merge window closes in two weeks. Have a happy (Canadian) thanksgiving! https://git.kernel.org/cgit/linux/kernel/git/wireless/wireless-testing.git -- Bob Copeland %% http://bobcopeland.com/
Re: Using ath5k/ath9k radio for constant-tx noise source.
On Wed, Aug 19, 2015 at 12:07:50PM -0700, Ben Greear wrote: > I have a commercial AP that is using a CM9 ath5k radio (evidently, I could be > wrong) > and it has the ability to do a constant transmit of raw noise (RF probe shows > noise, but a monitor-port sniffer does not see any frames from the CM9). > > I don't know the low-level details of how it is doing this, but I suspect > it is using something like madwifi for a driver. > > Does anyone know how this can be done with modern software and > ath5k or ath9k NICs? So, see the below patch for something that might work. I only dusted off and compile-tested this, and I'm not sure if it is controllable to the extent that would be needed for things like DFS testing. Just to reiterate the disclaimer, I'm told running radio in this mode for an extended period of time can damage it, so -- good luck. Note, ath9k has another kind of tx-99 mode which just sends out packets constantly; ath5k is of course capable of doing that kind of thing too. Setup for that is mostly the same except the descriptor list is just self-linked and some of the phy tricks aren't needed. >From fd374ea31833f705d6a08bb8f8e171cfcda8c302 Mon Sep 17 00:00:00 2001 From: Bob Copeland <m...@bobcopeland.com> Date: Tue, 17 May 2016 00:24:42 -0400 Subject: [PATCH] ath5k: add continuous-wave transmit mode Continuous-wave mode is a kind of testmode in which RF is emitted on a single carrier frequency; sometimes this kind of thing is needed for FCC certification. Some Atheros devices support entering this mode for testing. This patch demonstrates (some of?) the settings needed to get the device into the mode. I don't claim to understand it and the PHY is 100% undocumented as far as I know, so a lot of this is guesswork based on what is done in some versions of madwifi. It seems to work on one radio I tried it on (monitored with ath9k's spectral scan and my own "speccy" tool) -- but it might well destroy yours, so, don't run it unless you don't care about that possibility. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- drivers/net/wireless/ath/ath5k/Makefile | 1 + drivers/net/wireless/ath/ath5k/ath5k.h | 1 + drivers/net/wireless/ath/ath5k/base.h | 3 + drivers/net/wireless/ath/ath5k/debug.c | 47 drivers/net/wireless/ath/ath5k/tx99.c | 200 5 files changed, 252 insertions(+) create mode 100644 drivers/net/wireless/ath/ath5k/tx99.c diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index 1b3a34f..afc699f 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile @@ -16,6 +16,7 @@ ath5k-y += rfkill.o ath5k-y+= ani.o ath5k-y+= sysfs.o ath5k-y+= mac80211-ops.o +ath5k-y+= tx99.o ath5k-$(CONFIG_ATH5K_DEBUG)+= debug.o ath5k-$(CONFIG_ATH5K_AHB) += ahb.o ath5k-$(CONFIG_ATH5K_PCI) += pci.o diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 67fedb6..8c86a96 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1446,6 +1446,7 @@ struct ath5k_hw { /* Calibration mask */ u8 ah_cal_mask; + booltx99_active; /* * Function pointers diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 97469d0..3e50c747 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -112,6 +112,9 @@ const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); int ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops); void ath5k_deinit_ah(struct ath5k_hw *ah); +void ath5k_tx99_cw_start(struct ath5k_hw *ah); +void ath5k_tx99_cw_stop(struct ath5k_hw *ah); + /* Check whether BSSID mask is supported */ #define ath5k_hw_hasbssidmask(_ah) (ah->ah_version == AR5K_AR5212) diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 4f8d9ed..260f061 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -991,6 +991,50 @@ static const struct file_operations fops_eeprom = { }; +static ssize_t read_file_tx99(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + char buf[3]; + struct ath5k_hw *ah = file->private_data; + + if (!ah->tx99_active) + buf[0] = '0'; + else + buf[0] = '1'; + buf[1] = '\n'; + buf[2] = '\0'; + return simple_read_from_buffer(user_buf, count, ppos, buf, 2); +} + +static ssize_t write_file_tx99(struct file *file, const char __user *use
Re: Using ath5k/ath9k radio for constant-tx noise source.
On Wed, Sep 14, 2016 at 05:22:46PM -0700, Ben Greear wrote: > On 08/20/2015 08:11 AM, Zefir Kurtisi wrote: > >On 08/19/2015 09:07 PM, Ben Greear wrote: > >>I have a commercial AP that is using a CM9 ath5k radio (evidently, I could > >>be wrong) > >>and it has the ability to do a constant transmit of raw noise (RF probe > >>shows > >>noise, but a monitor-port sniffer does not see any frames from the CM9). > >> > >>I don't know the low-level details of how it is doing this, but I suspect > >>it is using something like madwifi for a driver. > >> > >>Does anyone know how this can be done with modern software and > >>ath5k or ath9k NICs? Hi Ben, I wrote some code to do this on ath5k -- I can post a patch if you're interested in using ath5k for this. Here's a snapshot of what it looks like when running on ch.1: https://bobcopeland.com/images/speccy-testmode.png -- Bob Copeland %% http://bobcopeland.com/
[PATCH] mwifiex: fix error handling in mwifiex_create_custom_regdomain
smatch reports: sta_cmdresp.c:1053 mwifiex_create_custom_regdomain() warn: possible memory leak of 'regd' Indeed, mwifiex_create_custom_regdomain() returns NULL in the case that channel is missing in the TLV without freeing regd. Moreover, some other error paths in this function return ERR_PTR values which are assigned without checking to the regd field in the mwifiex_adapter struct. The latter is only null-checked where used. Fix by freeing regd in the error path, and only update priv->adapter->regd if the returned pointer is valid. Cc: Amitkumar Karwar <akar...@marvell.com> Cc: Nishant Sarmukadam <nisha...@marvell.com> Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- Note, compile-tested only. It might make sense to instead remove the ERR_PTR stuff if there is no plan to report them further up the call stack but I just went for the minimal patch here. --- drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c index 3344a26..8548027 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c @@ -1049,8 +1049,10 @@ mwifiex_create_custom_regdomain(struct mwifiex_private *priv, enum nl80211_band band; chan = *buf++; - if (!chan) + if (!chan) { + kfree(regd); return NULL; + } chflags = *buf++; band = (chan <= 14) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; freq = ieee80211_channel_to_frequency(chan, band); @@ -1116,6 +1118,7 @@ static int mwifiex_ret_chan_region_cfg(struct mwifiex_private *priv, u16 action = le16_to_cpu(reg->action); u16 tlv, tlv_buf_len, tlv_buf_left; struct mwifiex_ie_types_header *head; + struct ieee80211_regdomain *regd; u8 *tlv_buf; if (action != HostCmd_ACT_GEN_GET) @@ -1137,10 +1140,10 @@ static int mwifiex_ret_chan_region_cfg(struct mwifiex_private *priv, mwifiex_dbg_dump(priv->adapter, CMD_D, "CHAN:", (u8 *)head + sizeof(*head), tlv_buf_len); - priv->adapter->regd = - mwifiex_create_custom_regdomain(priv, - (u8 *)head + - sizeof(*head), tlv_buf_len); + regd = mwifiex_create_custom_regdomain(priv, + (u8 *)head + sizeof(*head), tlv_buf_len); + if (!IS_ERR(regd)) + priv->adapter->regd = regd; break; } -- 2.9.0
Re: [PATCH 3/3] mwifiex: add custom regulatory domain support
On Tue, Aug 09, 2016 at 08:20:46PM +0530, Amitkumar Karwar wrote: > This patch creates custom regulatory rules based on the information > received from firmware and enable them during wiphy registration. > > Signed-off-by: Amitkumar Karwar <akar...@marvell.com> Hi, This patch recently landed in wireless-testing but I noticed (or well, smatch noticed) some issues with the error paths: > + if (adapter->regd) { does null-check here and elsewhere... > +static struct ieee80211_regdomain * > +mwifiex_create_custom_regdomain(struct mwifiex_private *priv, > + u8 *buf, u16 buf_len) > +{ > + u16 num_chan = buf_len / 2; > + struct ieee80211_regdomain *regd; > + struct ieee80211_reg_rule *rule; > + bool new_rule; > + int regd_size, idx, freq, prev_freq = 0; > + u32 bw, prev_bw = 0; > + u8 chflags, prev_chflags = 0, valid_rules = 0; > + > + if (WARN_ON_ONCE(num_chan > NL80211_MAX_SUPP_REG_RULES)) > + return ERR_PTR(-EINVAL); > + ...returns ERR_PTR here > + regd_size = sizeof(struct ieee80211_regdomain) + > + num_chan * sizeof(struct ieee80211_reg_rule); > + > + regd = kzalloc(regd_size, GFP_KERNEL); > + if (!regd) > + return ERR_PTR(-ENOMEM); and here. > + > + for (idx = 0; idx < num_chan; idx++) { > + u8 chan; > + enum nl80211_band band; > + > + chan = *buf++; > + if (!chan) > + return NULL; ^ here, returns null, leaking regd > + chflags = *buf++; > + band = (chan <= 14) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; > + freq = ieee80211_channel_to_frequency(chan, band); > + new_rule = false; > + > + if (chflags & MWIFIEX_CHANNEL_DISABLED) > + continue; > + > + if (band == NL80211_BAND_5GHZ) { > + if (!(chflags & MWIFIEX_CHANNEL_NOHT80)) > + bw = MHZ_TO_KHZ(80); > + else if (!(chflags & MWIFIEX_CHANNEL_NOHT40)) > + bw = MHZ_TO_KHZ(40); > + else > + bw = MHZ_TO_KHZ(20); > + } else { > + if (!(chflags & MWIFIEX_CHANNEL_NOHT40)) > + bw = MHZ_TO_KHZ(40); > + else > + bw = MHZ_TO_KHZ(20); > + } > + > + if (idx == 0 || prev_chflags != chflags || prev_bw != bw || > + freq - prev_freq > 20) { > + valid_rules++; > + new_rule = true; > + } > + > + rule = >reg_rules[valid_rules - 1]; > + > + rule->freq_range.end_freq_khz = MHZ_TO_KHZ(freq + 10); > + > + prev_chflags = chflags; > + prev_freq = freq; > + prev_bw = bw; > + > + if (!new_rule) > + continue; > + > + rule->freq_range.start_freq_khz = MHZ_TO_KHZ(freq - 10); > + rule->power_rule.max_eirp = DBM_TO_MBM(19); > + > + if (chflags & MWIFIEX_CHANNEL_PASSIVE) > + rule->flags = NL80211_RRF_NO_IR; > + > + if (chflags & MWIFIEX_CHANNEL_DFS) > + rule->flags = NL80211_RRF_DFS; > + > + rule->freq_range.max_bandwidth_khz = bw; > + } > + > + regd->n_reg_rules = valid_rules; > + regd->alpha2[0] = '9'; > + regd->alpha2[1] = '9'; > + > + return regd; > +} [...] > static int mwifiex_ret_chan_region_cfg(struct mwifiex_private *priv, > struct host_cmd_ds_command *resp) > { > @@ -1050,6 +1137,10 @@ static int mwifiex_ret_chan_region_cfg(struct > mwifiex_private *priv, > mwifiex_dbg_dump(priv->adapter, CMD_D, "CHAN:", >(u8 *)head + sizeof(*head), >tlv_buf_len); > + priv->adapter->regd = > + mwifiex_create_custom_regdomain(priv, > + (u8 *)head + > + sizeof(*head), tlv_buf_len); Here regd is assigned without checking IS_ERR. -- Bob Copeland %% http://bobcopeland.com/
wireless-testing on 4.8-rc1
Hi all, Now that Linus closed the merge window for 4.8, I'm resuming near-daily wireless-testing builds at: http://git.kernel.org/cgit/linux/kernel/git/wireless/wireless-testing.git The first tag in this series is wt-2016-08-08. Let us know of any issues. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] iw: display 5/10 MHz channel widths
On Fri, Jul 22, 2016 at 07:53:35PM +1000, Julian Calaby wrote: > Hi Bob, Hi! > > --- a/interface.c > > +++ b/interface.c > > @@ -295,6 +295,10 @@ char *channel_width_name(enum nl80211_chan_width width) > > return "80+80 MHz"; > > case NL80211_CHAN_WIDTH_160: > > return "160 MHz"; > > + case NL80211_CHAN_WIDTH_5: > > + return "5 MHz"; > > + case NL80211_CHAN_WIDTH_10: > > + return "10 MHz"; > > default: > > return "unknown"; > > } > > Judging by the previous two entries, it looks like the case statements > are sorted, so should these ones therefore be at the top of the list? These are sorted by NL80211_CHAN_WIDTH_* attribute value, which makes a little more sense to me than sorting by the string or numerically by width, but sure, I can do it either way. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ath9k: fix misleading indent
Fixes smatch warning: ath9k_vif_iter_set_beacon() warn if statement not indented Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- drivers/net/wireless/ath/ath9k/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 7594650..70ca746 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -919,7 +919,7 @@ static void ath9k_vif_iter_set_beacon(struct ath9k_vif_iter_data *iter_data, } else { if (iter_data->primary_beacon_vif->type != NL80211_IFTYPE_AP && vif->type == NL80211_IFTYPE_AP) - iter_data->primary_beacon_vif = vif; + iter_data->primary_beacon_vif = vif; } iter_data->beacons = true; -- 2.9.0 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] iw: display 5/10 MHz channel widths
iw was showing 'width: unknown' for channels on OCB interfaces; teach it the values for 5/10 MHz so it will show the configured width. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- interface.c | 4 1 file changed, 4 insertions(+) diff --git a/interface.c b/interface.c index 209561d..2802235 100644 --- a/interface.c +++ b/interface.c @@ -295,6 +295,10 @@ char *channel_width_name(enum nl80211_chan_width width) return "80+80 MHz"; case NL80211_CHAN_WIDTH_160: return "160 MHz"; + case NL80211_CHAN_WIDTH_5: + return "5 MHz"; + case NL80211_CHAN_WIDTH_10: + return "10 MHz"; default: return "unknown"; } -- 2.9.0 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mac80211: End the MPSP even if EOSP frame was not received
On Wed, Jul 20, 2016 at 04:11:33PM +0900, Masashi Honma wrote: > On 2016年07月19日 19:40, Bob Copeland wrote: > > > >OK, do we need to also clear WLAN_STA_PS_STA flag for the peer in > >ieee80211_mps_sta_status_update(), or does the node completely repeer? > > > >ISTR running into a problem where rebooted peer (previously in power-save) > >would send popen but we would buffer the response due to stale PS sta > >flag. [...] > > So looks no problem. Ok, thanks for testing that - fwiw original patch Acked-by: Bob Copeland <m...@bobcopeland.com> -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/3] mac80211: mesh: improve path resolving time
On Tue, Jul 19, 2016 at 01:02:13PM +, Machani, Yaniv wrote: > On Tue, Jul 19, 2016 at 15:44:56, Bob Copeland wrote: > > > IEEE 802.11-2012 has defined dot11MeshHWMPpreqMinInterval attribute > > > to specify the minimum interval of time during which a mesh STA can > > > send only one Action frame containing a PREQ element. This is to > > > avoid flooding of broadcast PREQ frame especially when the number of > > > mesh STA is increased. > > > > Good point, according to 13.10.9.3, conditions for sending PREQ include: > > > > "The mesh STA has not sent a PREQ element for the target mesh STAs > > less than dot11MeshHWMPpreqMinInterval TUs ago. If this is the case, > > the transmission of the PREQ has to be postponed until this condition > > becomes true." > > > > As I see it, the key point here is "for the target meh STA", > Today, the code will not send a PREQ to ANY target if > dot11MeshHWMPpreqMinInterval didn't passed. > The information is saved in the 'ifmsh->last_preq', and not per path. The standard also says (which Chun-Yeow partially quoted): dot11MeshHWMPpreqMinInterval OBJECT-TYPE SYNTAX Unsigned32 (1..65535) MAX-ACCESS read-write STATUS current DESCRIPTION "This is a control variable. It is written by an external management entity. Changes take effect as soon as practical in the implementation. This attribute specifies the minimum interval of time (in TUs) during which a mesh STA can send only one Action frame containing a PREQ element." DEFVAL { 100 } ::= { dot11MeshHWMPConfigEntry 4} This wording seems to indicate that it is not per path. Perhaps this should be clarified in the standard. (If the intent turns out to be per path, then I guess we should fix it by storing last_preq per path instead.) Ignoring the standard for a second, let's explore this: can you give some idea on how many stations are in your target network, how frequently a given pair of nodes unpeer, what sort of improvements you see with the patch? It should then be pretty easy to run some simulations to see the scenarios where this helps and where it hurts. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/3] mac80211: mesh: improve path resolving time
On Tue, Jul 19, 2016 at 12:59:56AM +0800, Chun-Yeow Yeoh wrote: > > To improve that, added an 'immediate' flag to be used when the path needs > > to be resolved. > > Once set, a PREQ frame will be send w/o considering the MinInterval > > parameter. > > Suggest that you try to reduce the mesh_hwmp_preq_min_interval to your > desired value instead of introducing a new patch specific to your use > case. > > IEEE 802.11-2012 has defined dot11MeshHWMPpreqMinInterval attribute to > specify the minimum interval of time during which a mesh STA can send > only one Action frame containing a PREQ element. This is to avoid > flooding of broadcast PREQ frame especially when the number of mesh > STA is increased. Good point, according to 13.10.9.3, conditions for sending PREQ include: "The mesh STA has not sent a PREQ element for the target mesh STAs less than dot11MeshHWMPpreqMinInterval TUs ago. If this is the case, the transmission of the PREQ has to be postponed until this condition becomes true." Adopting this patch would violate that, so please disregard my suggested rewrites; we should just skip this one. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/3] mac80211: mesh: improve path resolving time
On Wed, Jul 13, 2016 at 02:45:25PM +0300, Yaniv Machani wrote: > When a packet is received for transmission, > a PREQ frame is sent to resolve the appropriate path to the desired > destination. > After path was established, any sequential PREQ will be sent only after > dot11MeshHWMPpreqMinInterval, which usually set to few seconds. > > This implementation has an impact in cases where we would like to > resolve the path quickly. > A clear example is when a peer was disconnected from us, > while he acted as a hop to our destination. > Although the path table will be cleared, the next PREQ frame will be sent > only after reaching the MinInterval. > This will cause unwanted delay, possibly of few seconds until the traffic > will resume. > > if (!(mpath->flags & MESH_PATH_RESOLVING)) > - mesh_queue_preq(mpath, PREQ_Q_F_START); > + mesh_queue_preq(mpath, PREQ_Q_F_START, true); What about something like this here instead: if (!(mpath->flags & MESH_PATH_RESOLVING)) { /* force next preq to be sent without delay */ ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; mesh_queue_preq(mpath, PREQ_Q_F_START); } Maybe a little more magic, but it has a comment explaining it and doesn't add a bool parameter everywhere. Or, maybe even just do it inside mesh_queue_preq() based on having PREQ_Q_F_START && !PREQ_Q_F_REFRESH (if those are the only cases where "true" is passed). Generally I try to avoid bool parameters where possible because when you look at a callsite, you don't know immediately what "true" and "false" mean, and also each one you add doubles the code paths through a given function. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mac80211: End the MPSP even if EOSP frame was not received
On Tue, Jul 19, 2016 at 11:16:24AM +0900, Masashi Honma wrote: > This patch does not fix starting MPSP, this patch fixes ending of MPSP. > Without this patch, local peer continues MPSP even if we lost opposite peer > accidentally. OK, do we need to also clear WLAN_STA_PS_STA flag for the peer in ieee80211_mps_sta_status_update(), or does the node completely repeer? ISTR running into a problem where rebooted peer (previously in power-save) would send popen but we would buffer the response due to stale PS sta flag. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] mac80211: mesh: fixed HT ies in beacon template
On Wed, Jul 13, 2016 at 02:45:40PM +0300, Yaniv Machani wrote: > The HT capab info field inside the HT capab IE of the mesh beacon > is incorrect (in the case of 20MHz channel width). > To fix this driver will check configuration from cfg and > will build it accordingly. > +/* determine capability flags */ > + cap = sband->ht_cap.cap; > + > +/* if channel width is 20MHz - configure HT capab accordingly*/ > + if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20) { > + cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; > + cap &= ~IEEE80211_HT_CAP_DSSSCCK40; > + } Is it required that HT capability match the HT operation in this case? > diff --git a/net/mac80211/util.c b/net/mac80211/util.c > index 42bf0b6..5375a82 100644 > --- a/net/mac80211/util.c > +++ b/net/mac80211/util.c > @@ -2349,10 +2349,7 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct > ieee80211_sta_ht_cap *ht_cap, > ht_oper->operation_mode = cpu_to_le16(prot_mode); > ht_oper->stbc_param = 0x; > > - /* It seems that Basic MCS set and Supported MCS set > -are identical for the first 10 bytes */ > memset(_oper->basic_set, 0, 16); > - memcpy(_oper->basic_set, _cap->mcs, 10); This change doesn't look right (basic mcs set will be all zeroes) but then, neither does the original code. Basic MCS set for a mesh STA should be the mandatory MCSes according to 9.7.4. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mac80211: End the MPSP even if EOSP frame was not received
On Wed, Jul 13, 2016 at 04:04:35PM +0900, Masashi Honma wrote: > The mesh STA sends QoS frame with EOSP (end of service period) > subfiled=1 to end the MPSP(mesh peer service period). Previously, if > the frame was not acked by peer, the mesh STA did not end the MPSP. > This patch ends the MPSP even if the QoS frame was no acked. Hmm, my recollection on this stuff is a little fuzzy. So we only get here if the peer sta is in doze state, but it shouldn't do that if we are in an MPSP. So, is the real problem that we don't wait for an ack from the peer before marking ourselves in a MPSP? -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] mac80211: mesh: flush stations before beacons are stopped
On Wed, Jul 13, 2016 at 10:11:25AM +, Machani, Yaniv wrote: > > > Some drivers (e.g. wl18xx) expect that the last stage in the > > > de-initialization process will be stopping the beacons, similar to ap. > > > Update ieee80211_stop_mesh() flow accordingly. > > > > > How well have you tested that with other drivers? > > > > Sorry for the delayed response (I've been out) and thanks for your comments, > I have tested it with RT3572 as well, and didn't see any issue. > I'll update the comment to reflect that. I'll give this a test on ath10k and wcn36xx as they are the ones most likely to care about ordering. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] cfg80211: Add mesh peer AID setting API
On Wed, Jul 06, 2016 at 02:42:34PM +0200, Johannes Berg wrote: > > + * @NL80211_ATTR_MESH_PEER_AID: Association ID for the mesh peer > > (u16). This is > > + * used to pull the stored data for mesh peer in power save > > state. > > > Why does this need new API all over? > > It seems to me that it could just use the regular NL80211_ATTR_STA_AID > attribute, and the cfg80211 code would already be in place, and you'd > just need to add a single line to mac80211 and > to cfg80211_check_station_change() to accept that. We are already using NL80211_ATTR_STA_AID, though -- one is for the station's AID (in our TIM, which is NL80211_ATTR_STA_AID) and the new one is for our AID in the peer's TIM. There is the NL80211_ATTR_PEER_AID but that seems specific to TDLS and also doesn't appear to be processed in the necessary way (e.g. overrides STA_AID in nl80211_new_station). -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] cfg80211: Add mesh peer AID setting API
On Thu, Jun 30, 2016 at 06:00:58PM +0900, Masashi Honma wrote: > diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h > index 7bbb00d..2fa5896 100644 > --- a/include/net/cfg80211.h > +++ b/include/net/cfg80211.h > @@ -805,6 +805,7 @@ struct station_parameters { > u32 sta_modify_mask; > int listen_interval; > u16 aid; > + u16 mesh_aid; Let's call it peer_aid or mesh_peer_aid or something like that, per my email on hostapd list. Also you probably saw kbuild robot pointed out missing documentation for the field. > diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c > index c503e96..f41fb61 100644 > --- a/net/wireless/nl80211.c > +++ b/net/wireless/nl80211.c > @@ -4410,6 +4410,9 @@ static int nl80211_set_station(struct sk_buff *skb, > struct genl_info *info) > nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); > if (params.plink_state >= NUM_NL80211_PLINK_STATES) > return -EINVAL; > + if (info->attrs[NL80211_ATTR_MESH_PEER_AID]) > + params.mesh_aid = nla_get_u16( > + info->attrs[NL80211_ATTR_MESH_PEER_AID]); We need a check against IEEE80211_MAX_AID somewhere. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/4] mac80211: mesh: fixed HT ies in beacon template
On Tue, Jun 28, 2016 at 02:13:06PM +0300, Yaniv Machani wrote: > From: Meirav Kama <meir...@ti.com> > > There are several values in HT info elements of mesh beacon (built by the > mac80211) that are incorrect. Would be good to enumerate the problems here. > To fix them: > 1. mac80211 will check configuration from cfg and will build accordingly. > 2. changes made in mesh default values. What is wrong with the defaults? > sband = local->hw.wiphy->bands[band]; > if (!sband->ht_cap.ht_supported || > @@ -431,11 +433,40 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data > *sdata, > sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10) > return 0; > > +/* determine capability flags */ > + cap = sband->ht_cap.cap; There is some weird whitespace here (space instead of tabs for the comment). -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] mac80211: sta_info: max_peers reached falsely
On Tue, Jun 28, 2016 at 02:13:07PM +0300, Yaniv Machani wrote: > From: Meirav Kama <meir...@ti.com> > > Issue happened when receiving delete_sta command without > changing plink_state from ESTAB to HOLDING before. > When receiving delete_sta command for mesh interface > verify plink_state is not ESTAB and if so, decrease > plink count and update beacon. This should be fixed already (and properly) by the patch "mac80211: Fix mesh estab links counting" -- please let us know if you have a case that's still broken with that fix. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] mac80211/cfg: mesh: fix healing time when a mesh peer is disconnecting
On Tue, Jun 28, 2016 at 02:13:05PM +0300, Yaniv Machani wrote: > From: Maital Hahn <mait...@ti.com> > > Once receiving a CLOSE action frame from the disconnecting peer, > flush all entries in the path table which has this peer as the > next hop. Please address the user-visible behavior in your commit messages. Does it crash? Does it send frames to an invalid peer? Do frames get dropped? > In addition, upon receiving a packet, if next hop is not found, > trigger PERQ immidiatly, instead of just putting it in the queue. "PREQ" Please split this into a separate patch that we can review separately (and also give the "why" in the commit log). > Signed-off-by: Maital Hahn <mait...@ti.com> > Acked-by: Yaniv Machani <yani...@ti.com> > --- > net/mac80211/cfg.c | 1 + > net/mac80211/mesh.c | 3 ++- > net/mac80211/mesh_hwmp.c | 42 +- > 3 files changed, 28 insertions(+), 18 deletions(-) > > diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c > index 0c12e40..f876ef7 100644 > --- a/net/mac80211/cfg.c > +++ b/net/mac80211/cfg.c > @@ -1011,6 +1011,7 @@ static void sta_apply_mesh_params(struct > ieee80211_local *local, > if (sta->mesh->plink_state == NL80211_PLINK_ESTAB) > changed = mesh_plink_dec_estab_count(sdata); > sta->mesh->plink_state = params->plink_state; > + mesh_path_flush_by_nexthop(sta); This isn't necessary, caller should already be doing mesh_path_flush_by_nexthop() in every case I could see. Besides it cannot be done under plink lock. > +++ b/net/mac80211/mesh.c > @@ -159,7 +159,8 @@ void mesh_sta_cleanup(struct sta_info *sta) > if (!sdata->u.mesh.user_mpm) { > changed |= mesh_plink_deactivate(sta); > del_timer_sync(>mesh->plink_timer); > - } > + } else > + mesh_path_flush_by_nexthop(sta); And this is already fixed in mac80211-next. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mac80211: use common cleanup for user/!user_mpm
We've accumulated a couple of different fixes now to mesh_sta_cleanup() due to the different paths that user_mpm and !user_mpm cases take -- one fix to flush nexthop paths and one to fix the counting. The only caller of mesh_plink_deactivate() is mesh_sta_cleanup(), so we can push the user_mpm checks down into there in order to share more code. In doing so, we can remove an extra call to mesh_path_flush_by_nexthop() and the (unnecessary) call to mesh_accept_plinks_update(). This will also ensure the powersaving state code gets called in the user_mpm case. The only cleanup tasks we need to avoid when MPM is in user-space are sending the peering frames and stopping the plink timer, so wrap those in the appropriate check. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- This applies on top of Jouni's patch, "mac80211: Fix mesh estab_plinks counting in STA removal case", so this can go for -next. net/mac80211/mesh.c | 20 +--- net/mac80211/mesh_plink.c | 16 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 6a1603b..c66411d 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -148,25 +148,7 @@ u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata) void mesh_sta_cleanup(struct sta_info *sta) { struct ieee80211_sub_if_data *sdata = sta->sdata; - u32 changed = 0; - - /* -* maybe userspace handles peer allocation and peering, but in either -* case the beacon is still generated by the kernel and we might need -* an update. -*/ - if (sdata->u.mesh.user_mpm && - sta->mesh->plink_state == NL80211_PLINK_ESTAB) - changed |= mesh_plink_dec_estab_count(sdata); - changed |= mesh_accept_plinks_update(sdata); - if (!sdata->u.mesh.user_mpm) { - changed |= mesh_plink_deactivate(sta); - del_timer_sync(>mesh->plink_timer); - } - - /* make sure no readers can access nexthop sta from here on */ - mesh_path_flush_by_nexthop(sta); - synchronize_net(); + u32 changed = mesh_plink_deactivate(sta); if (changed) ieee80211_mbss_info_change_notify(sdata, changed); diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 79f2a0a..7fcdcf6 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -370,13 +370,21 @@ u32 mesh_plink_deactivate(struct sta_info *sta) spin_lock_bh(>mesh->plink_lock); changed = __mesh_plink_deactivate(sta); - sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED; - mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE, - sta->sta.addr, sta->mesh->llid, sta->mesh->plid, - sta->mesh->reason); + + if (!sdata->u.mesh.user_mpm) { + sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED; + mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE, + sta->sta.addr, sta->mesh->llid, + sta->mesh->plid, sta->mesh->reason); + } spin_unlock_bh(>mesh->plink_lock); + if (!sdata->u.mesh.user_mpm) + del_timer_sync(>mesh->plink_timer); mesh_path_flush_by_nexthop(sta); + /* make sure no readers can access nexthop sta from here on */ + synchronize_net(); + return changed; } -- 2.9.0 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mac80211: Fix mesh estab_plinks counting in STA removal case
On Tue, Jun 21, 2016 at 06:26:02PM -0400, Bob Copeland wrote: > Looks further buggy, so perhaps this untested patch would work, i.e. (still) > @@ -370,13 +372,19 @@ u32 mesh_plink_deactivate(struct sta_info *sta) > > spin_lock_bh(>mesh->plink_lock); > changed = __mesh_plink_deactivate(sta); > - sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED; > - mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE, > - sta->sta.addr, sta->mesh->llid, sta->mesh->plid, > - sta->mesh->reason); > + > + if (sdata->u.mesh.user_mpm) { should be !sdata->u.mesh.user_mpm :) > + sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED; > + mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE, > + sta->sta.addr, sta->mesh->llid, > sta->mesh->plid, > + sta->mesh->reason); > + } > spin_unlock_bh(>mesh->plink_lock); > mesh_path_flush_by_nexthop(sta); > > + /* make sure no readers can access nexthop sta from here on */ > + synchronize_net(); > + > return changed; > } > > -- > 2.9.0 > -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mac80211: Fix mesh estab_plinks counting in STA removal case
On Tue, Jun 21, 2016 at 09:09:10PM +0200, Johannes Berg wrote: > > > */ > > - changed = mesh_accept_plinks_update(sdata); > > + if (sdata->u.mesh.user_mpm && > > + sta->mesh->plink_state == NL80211_PLINK_ESTAB) > > + changed |= mesh_plink_dec_estab_count(sdata); > > + changed |= mesh_accept_plinks_update(sdata); > > if (!sdata->u.mesh.user_mpm) { > > changed |= mesh_plink_deactivate(sta); > > del_timer_sync(>mesh->plink_timer); > > > > Does it have to be done before the mesh_accept_plinks_update()? > > If not, you should put it with the existing u.mesh.user_mpm check. If > yes, then the code is further buggy since only mesh_plink_deactivate() > will call it when the kernel MPM is used. Looks further buggy, so perhaps this untested patch would work, i.e. move the accepting-plinks change closer to the decrement, and push the user_mpm check down into mesh_plink_deactivate to just avoid sending the peering frames. [There's also a bit there for power saving that we likely want to keep for secure networks.] Then again maybe accepting_plinks flag should just be computed when used instead of tracking the state separately. --- net/mac80211/mesh.c | 18 ++ net/mac80211/mesh_plink.c | 16 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 21b1fdf..3c150f8 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -148,22 +148,8 @@ u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata) void mesh_sta_cleanup(struct sta_info *sta) { struct ieee80211_sub_if_data *sdata = sta->sdata; - u32 changed; - - /* -* maybe userspace handles peer allocation and peering, but in either -* case the beacon is still generated by the kernel and we might need -* an update. -*/ - changed = mesh_accept_plinks_update(sdata); - if (!sdata->u.mesh.user_mpm) { - changed |= mesh_plink_deactivate(sta); - del_timer_sync(>mesh->plink_timer); - } - - /* make sure no readers can access nexthop sta from here on */ - mesh_path_flush_by_nexthop(sta); - synchronize_net(); + u32 changed = mesh_plink_deactivate(sta); + del_timer_sync(>mesh->plink_timer); if (changed) ieee80211_mbss_info_change_notify(sdata, changed); diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 79f2a0a..69ac7a8 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -349,6 +349,8 @@ static u32 __mesh_plink_deactivate(struct sta_info *sta) changed = mesh_plink_dec_estab_count(sdata); sta->mesh->plink_state = NL80211_PLINK_BLOCKED; + changed |= mesh_accept_plinks_update(sdata); + ieee80211_mps_sta_status_update(sta); changed |= ieee80211_mps_set_sta_local_pm(sta, NL80211_MESH_POWER_UNKNOWN); @@ -370,13 +372,19 @@ u32 mesh_plink_deactivate(struct sta_info *sta) spin_lock_bh(>mesh->plink_lock); changed = __mesh_plink_deactivate(sta); - sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED; - mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE, - sta->sta.addr, sta->mesh->llid, sta->mesh->plid, - sta->mesh->reason); + + if (sdata->u.mesh.user_mpm) { + sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED; + mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE, + sta->sta.addr, sta->mesh->llid, sta->mesh->plid, + sta->mesh->reason); + } spin_unlock_bh(>mesh->plink_lock); mesh_path_flush_by_nexthop(sta); + /* make sure no readers can access nexthop sta from here on */ + synchronize_net(); + return changed; } -- 2.9.0 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/3] *** Mesh Path Selection Metric Calculation ***
On Mon, Jun 20, 2016 at 04:00:19PM +0300, Maxim Altshul wrote: > 2. Implements the opcode and the mechanism that reports the rates > in TI driver. Does this mean TI driver will support mesh at some point? -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ath10k: Fix a typo in spectral code commments
On Tue, Jun 14, 2016 at 11:03:54AM +0530, Mohammed Shafi Shajakhan wrote: > From: Mohammed Shafi Shajakhan <moham...@qti.qualcomm.com> > > Found this obvious typo while going through the spectral > code design in ath10k > /* TODO: As experiments with an analogue sender and various > - * configuaritions (fft-sizes of 64/128/256 and 20/40/80 Mhz) > + * configurations (fft-sizes of 64/128/256 and 20/40/80 Mhz) >* show, the particular configuration of 80 MHz/64 bins does >* not match with the other smaples at all. Until the reason >* for that is found, don't report these samples. Also "smaples" :) -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ath10k: fix potential null dereference bugs
On Tue, Jun 14, 2016 at 01:51:24PM +, Kalle Valo wrote: > > It's not clear that's the same situation, since tun->sk is very likely > > to have been an actual pointer, not an embedded thing like drv_priv. Just to follow up on that thread, I did research it a bit yesterday and came to the conclusion that it is UB even when the target is in the same struct. However, in a not very scientific survey, I didn't see either clang or gcc remove the test in a simplified test case (with -O3 and without -fno-delete-null-pointer-checks). If drv_priv were an actual pointer, gcc did remove it but clang did not. So, there's that. > > However, with all this, I think I'd simply not take any chances - the > > patch isn't exactly invasive and in some cases (for example the first > > hunk of the patch) will even improve the code to the point where the > > compiler could warn about uninitialized usage of the pointer when the > > code gets modified to use it in case of !txq->sta. > > > > I'd take it, but I guess it's Kalle's decision :) > > Yeah, I'm leaning towards Johannes. These are not really invasive. Thanks, and sorry about the checkpatch -- I did run checkpatch on it but for some reason my version only complained about some of them. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ath10k: fix potential null dereference bugs
On Mon, Jun 13, 2016 at 11:08:59AM +0200, Johannes Berg wrote: > On Mon, 2016-06-13 at 07:39 +0200, Michal Kazior wrote: > > > > FWIW all of these are false positives. I think this was already > > pointed out some time ago. The drv_priv stuff is merely an offset > > (see how ieee80211_vif and ieee80211_sta are defined) and the > > according structure is always checked beforehand. OK, fair enough, sorry for the noise. I'm daily running sparse / smatch on wireless-testing; although these had been around for a while they showed up as new "errors" because of some line number changes, but I'll squelch them going forward. > IIRC, doing something like that can (sometimes?) still get you into > undefined behaviour territory, so the compiler could potentially > "optimize" away the later NULL check. So I did just go and check the generated code for each of these cases and gcc didn't elide the subsequent if-test, at least on x86-64 and my compiler / build config. Given http://lwn.net/Articles/342330, it seems possible, though. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ath10k: fix potential null dereference bugs
Smatch warns about a number of cases in ath10k where a pointer is null-checked after it has already been dereferenced, in code involving ath10k private virtual interface pointers. Fix these by making the dereference happen later. Addresses the following smatch warnings: drivers/net/wireless/ath/ath10k/mac.c:3651 ath10k_mac_txq_init() warn: variable dereferenced before check 'txq' (see line 3649) drivers/net/wireless/ath/ath10k/mac.c:3664 ath10k_mac_txq_unref() warn: variable dereferenced before check 'txq' (see line 3659) drivers/net/wireless/ath/ath10k/htt_tx.c:70 __ath10k_htt_tx_txq_recalc() warn: variable dereferenced before check 'txq->sta' (see line 52) drivers/net/wireless/ath/ath10k/htt_tx.c:740 ath10k_htt_tx_get_vdev_id() warn: variable dereferenced before check 'cb->vif' (see line 736) drivers/net/wireless/ath/ath10k/txrx.c:86 ath10k_txrx_tx_unref() warn: variable dereferenced before check 'txq' (see line 84) drivers/net/wireless/ath/ath10k/wmi.c:1837 ath10k_wmi_op_gen_mgmt_tx() warn: variable dereferenced before check 'cb->vif' (see line 1825) Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- Although I glanced at a few cases, by and large I didn't check whether the if() tests were correct but assumed they were. Also, I only compile-tested this. drivers/net/wireless/ath/ath10k/htt_tx.c | 15 +-- drivers/net/wireless/ath/ath10k/mac.c| 6 -- drivers/net/wireless/ath/ath10k/txrx.c | 5 +++-- drivers/net/wireless/ath/ath10k/wmi.c| 8 +--- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index 6269c61..dfcc43d 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -49,7 +49,7 @@ static void __ath10k_htt_tx_txq_recalc(struct ieee80211_hw *hw, struct ieee80211_txq *txq) { struct ath10k *ar = hw->priv; - struct ath10k_sta *arsta = (void *)txq->sta->drv_priv; + struct ath10k_sta *arsta; struct ath10k_vif *arvif = (void *)txq->vif->drv_priv; unsigned long frame_cnt; unsigned long byte_cnt; @@ -67,10 +67,12 @@ static void __ath10k_htt_tx_txq_recalc(struct ieee80211_hw *hw, if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH_PULL) return; - if (txq->sta) + if (txq->sta) { + arsta = (void *)txq->sta->drv_priv; peer_id = arsta->peer_id; - else + } else { peer_id = arvif->peer_id; + } tid = txq->tid; bit = BIT(peer_id % 32); @@ -733,13 +735,14 @@ static u8 ath10k_htt_tx_get_vdev_id(struct ath10k *ar, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb); - struct ath10k_vif *arvif = (void *)cb->vif->drv_priv; + struct ath10k_vif *arvif; if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) return ar->scan.vdev_id; - else if (cb->vif) + else if (cb->vif) { + arvif = (void *)cb->vif->drv_priv; return arvif->vdev_id; - else if (ar->monitor_started) + } else if (ar->monitor_started) return ar->monitor_vdev_id; else return 0; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 6dd1d26..4eee4b9 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3646,17 +3646,18 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work) static void ath10k_mac_txq_init(struct ieee80211_txq *txq) { - struct ath10k_txq *artxq = (void *)txq->drv_priv; + struct ath10k_txq *artxq; if (!txq) return; + artxq = (void *)txq->drv_priv; INIT_LIST_HEAD(>list); } static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq) { - struct ath10k_txq *artxq = (void *)txq->drv_priv; + struct ath10k_txq *artxq; struct ath10k_skb_cb *cb; struct sk_buff *msdu; int msdu_id; @@ -3664,6 +3665,7 @@ static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq) if (!txq) return; + artxq = (void *)txq->drv_priv; spin_lock_bh(>txqs_lock); if (!list_empty(>list)) list_del_init(>list); diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c index 576e7c4..9f17863 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.c +++ b/drivers/net/wireless/ath/ath10k/txrx.c @@ -81,10 +81,11 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, skb_cb = ATH10K_SKB_CB(msdu); txq = skb_cb->txq; -
[PATCH] ath5k: fix misplaced default label in sifs switch
In this switch statement, the default case does not always assign sifs. In practice, ah->ah_bwmode cannot take values besides the other labels, so this is not an actual problem, but it looks odd and smatch complains thus: ath5k_hw_get_default_sifs() warn: missing break? reassigning 'sifs' Silence the warning by moving default label up a line. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- drivers/net/wireless/ath/ath5k/pcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index fc47b70..f23c851 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -219,8 +219,8 @@ ath5k_hw_get_default_sifs(struct ath5k_hw *ah) sifs = AR5K_INIT_SIFS_QUARTER_RATE; break; case AR5K_BWMODE_DEFAULT: - sifs = AR5K_INIT_SIFS_DEFAULT_BG; default: + sifs = AR5K_INIT_SIFS_DEFAULT_BG; if (channel->band == NL80211_BAND_5GHZ) sifs = AR5K_INIT_SIFS_DEFAULT_A; break; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: wireless-testing on 4.7
+ Luca, Emmanuel On Tue, May 31, 2016 at 10:06:57PM -0600, Reinoud Koornstra wrote: > Today I compiled 4.6+ and pulled sources today > iwlwifi isn't super smooth. I assume you mean wireless-testing, based on 4.7-rc1 (as this email is in reply to my announcement of same). > > [ 112.345457] wlp4s0: authenticate with 00:30:44:1d:cf:2b > [ 112.349002] wlp4s0: send auth to 00:30:44:1d:cf:2b (try 1/3) > [ 112.349647] wlp4s0: authenticated > [ 112.352456] wlp4s0: associate with 00:30:44:1d:cf:2b (try 1/3) > [ 112.353764] wlp4s0: RX AssocResp from 00:30:44:1d:cf:2b (capab=0x11 > status=0 aid=3) > [ 112.355035] wlp4s0: associated > [ 112.355393] IPv6: ADDRCONF(NETDEV_CHANGE): wlp4s0: link becomes ready > [ 118.616327] wlp4s0: deauthenticated from 00:30:44:1d:cf:2b (Reason: > 15=4WAY_HANDSHAKE_TIMEOUT) > [ 128.673812] wlp4s0: authenticate with 00:30:44:1d:cf:2b > [ 128.676997] wlp4s0: send auth to 00:30:44:1d:cf:2b (try 1/3) > [ 128.677648] wlp4s0: authenticated > [ 128.678691] wlp4s0: associate with 00:30:44:1d:cf:2b (try 1/3) > [ 128.679807] wlp4s0: RX AssocResp from 00:30:44:1d:cf:2b (capab=0x11 > status=0 aid=3) > [ 128.681198] wlp4s0: associated > > I never experienced the 4 way handshake 802.11i timeout in my home setup. > With other setups plenty of times, especially with mediatek drivers. :) > If you wish I can sniff and see which side is at fault. I have not noticed any problems on my laptop with iwldvm on a 6205, with latest wireless-testing. But maybe intel devs can weigh in. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
wireless-testing on 4.7
Since Linus released 4.7-rc1 today, I've resumed wireless-testing updates since its merge window hiatus, with tag wt-2016-05-29. Please test and let me know of any issues. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: "kernel: BUG: scheduling while atomic:" errors with linux kernel 4.6
+linux-wireless On Thu, May 19, 2016 at 03:11:16PM -0600, James Feeney wrote: > Arch linux 4.6-1 > wpa_supplicant 1:2.5-3 > Toshiba Satellite, circa 2011, with a Pentium Dual-Core Mobile > Error is not seen on other machines. > > kernel: BUG: scheduling while atomic: wpa_supplicant/375/0x0002 This is a kernel bug, not a wpa_supplicant bug. The linux-wireless mailing list would be a more appropriate venue for this bug report. > May 19 10:26:07 lapis kernel: BUG: scheduling while atomic: > wpa_supplicant/627/0x0002 [...] > May 19 10:26:07 lapis kernel: [] __schedule+0x899/0xad0 > May 19 10:26:07 lapis kernel: [] schedule+0x3c/0x90 > May 19 10:26:07 lapis kernel: [] > schedule_hrtimeout_range_clock+0xa2/0x120 > May 19 10:26:07 lapis kernel: [] ? hrtimer_init+0x120/0x120 > May 19 10:26:07 lapis kernel: [] ? > schedule_hrtimeout_range_clock+0x96/0x120 > May 19 10:26:07 lapis kernel: [] > schedule_hrtimeout_range+0x13/0x20 > May 19 10:26:07 lapis kernel: [] usleep_range+0x4f/0x70 > May 19 10:26:07 lapis kernel: [] rtl_rfreg_delay+0x38/0x50 > [rtlwifi] > May 19 10:26:07 lapis kernel: [] > rtl92c_phy_config_rf_with_headerfile+0xc7/0xe0 [rtl8192ce] [Probably due to this kernel change: commit 49f86ec21c01b654f6ec47f2f4567f4f9ebaa26b Author: Larry Finger <larry.fin...@lwfinger.net> Date: Mon Feb 15 16:12:07 2016 -0600 rtlwifi: Change long delays to sleeps ...apparently this function isn't in sleepable context after all.] -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: wifi driver crashes openwrt device
On Tue, May 10, 2016 at 03:17:25PM +, andy wrote: > hello, every body. > I developed an openwrt device based on git clone > git://git.openwrt.org/15.05/openwrt.git. > I found that my device rebooted during wifi initializing sometimes, maybe > one in twenty. > The wifi driver is compat-wireless-2016-01-10.tar.bz2. > Could somebody give some hint or help me to resolve this wired issue? > Thank you very much. Hi Andy, You will probably need to capture a stack trace from the device in order for someone to be able to help, otherwise we can only guess. A serial console can help with that. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] mac80211: mesh: flush mesh paths unconditionally
r_handle_frame_finish+0x3db/0x3db [bridge] [ 348.530014] [] ? resched_curr+0x19/0x37 [ 348.530014] [] ? check_preempt_wakeup+0xbf/0xfe [ 348.530014] [] ? ktime_get_with_offset+0x5c/0xfc [ 348.530014] [] __netif_receive_skb+0x47/0x55 [ 348.530014] [] netif_receive_skb_internal+0x40/0x5a [ 348.530014] [] napi_gro_receive+0x3a/0x94 [ 348.530014] [] igb_poll+0x6fd/0x9ad [igb] [ 348.530014] [] ? swake_up_locked+0x14/0x26 [ 348.530014] [] net_rx_action+0xde/0x250 [ 348.530014] [] __do_softirq+0x8a/0x163 [ 348.530014] [] ? __hrtimer_tasklet_trampoline+0x19/0x19 [ 348.530014] [] do_softirq_own_stack+0x26/0x2c [ 348.530014] [ 348.530014] [] irq_exit+0x31/0x6f [ 348.530014] [] do_IRQ+0x8d/0xa0 [ 348.530014] [] common_interrupt+0x2c/0x40 [ 348.530014] Code: e7 8c 00 66 81 ff 88 00 75 12 85 d2 75 0e b2 c3 b8 83 e9 29 f9 e8 a7 5f f9 c6 eb 74 66 81 e3 8c 005 [ 348.530014] EIP: [] ieee80211_mps_set_frame_flags+0x40/0xaa [mac80211] SS:ESP 0068:f6409a40 [ 348.530014] CR2: 00020040 [ 348.530014] ---[ end trace 48556ac26779732e ]--- [ 348.530014] Kernel panic - not syncing: Fatal exception in interrupt [ 348.530014] Kernel Offset: disabled Cc: sta...@vger.kernel.org Reported-by: Fred Veldini <fred.veld...@gmail.com> Tested-by: Fred Veldini <fred.veld...@gmail.com> Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- v1: "mac80211: mesh: flush paths early in sta destroy" v2: Dropped block_mpath bit, just do this in part2 so that sta_info_get is guaranteed not to return the to-be-deleted sta, and add a second synchronize_rcu to wait for concurrent readers. Changed title. net/mac80211/mesh.c | 4 1 file changed, 4 insertions(+) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 4c6404e1ad6e..21b1fdf5d01d 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -161,6 +161,10 @@ void mesh_sta_cleanup(struct sta_info *sta) del_timer_sync(>mesh->plink_timer); } + /* make sure no readers can access nexthop sta from here on */ + mesh_path_flush_by_nexthop(sta); + synchronize_net(); + if (changed) ieee80211_mbss_info_change_notify(sdata, changed); } -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mac80211: mesh: flush mesh paths early in sta destroy
On Sat, May 14, 2016 at 08:54:13PM +0200, Felix Fietkau wrote: > > + WLAN_STA_BLOCK_MPATH, > I think this flag needs to be added to sta_flag_names in debugfs_sta.c On further reflection, using a flag for this is racy anyway, even if quite narrow. Maybe I should just flush in part2 unconditionally and have a second synchronize_net(). -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mac80211: mesh: flush mesh paths early in sta destroy
On Sat, May 14, 2016 at 08:54:13PM +0200, Felix Fietkau wrote: > > + WLAN_STA_BLOCK_MPATH, > I think this flag needs to be added to sta_flag_names in debugfs_sta.c > > - Felix Good point. I also missed the part where mesh_path_assign_nexthop should return an error to indicate the path shouldn't be activated. So, I'll send a v2 tomorrow, additional comments welcome in the meantime. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mac80211: mesh: flush mesh paths early in sta destroy
dle_frame+0x1e6/0x240 [bridge] [ 348.530014] [] ? br_handle_local_finish+0x6a/0x6a [bridge] [ 348.530014] [] __netif_receive_skb_core+0x43a/0x66b [ 348.530014] [] ? br_handle_frame_finish+0x3db/0x3db [bridge] [ 348.530014] [] ? resched_curr+0x19/0x37 [ 348.530014] [] ? check_preempt_wakeup+0xbf/0xfe [ 348.530014] [] ? ktime_get_with_offset+0x5c/0xfc [ 348.530014] [] __netif_receive_skb+0x47/0x55 [ 348.530014] [] netif_receive_skb_internal+0x40/0x5a [ 348.530014] [] napi_gro_receive+0x3a/0x94 [ 348.530014] [] igb_poll+0x6fd/0x9ad [igb] [ 348.530014] [] ? swake_up_locked+0x14/0x26 [ 348.530014] [] net_rx_action+0xde/0x250 [ 348.530014] [] __do_softirq+0x8a/0x163 [ 348.530014] [] ? __hrtimer_tasklet_trampoline+0x19/0x19 [ 348.530014] [] do_softirq_own_stack+0x26/0x2c [ 348.530014] [ 348.530014] [] irq_exit+0x31/0x6f [ 348.530014] [] do_IRQ+0x8d/0xa0 [ 348.530014] [] common_interrupt+0x2c/0x40 [ 348.530014] Code: e7 8c 00 66 81 ff 88 00 75 12 85 d2 75 0e b2 c3 b8 83 e9 29 f9 e8 a7 5f f9 c6 eb 74 66 81 e3 8c 005 [ 348.530014] EIP: [] ieee80211_mps_set_frame_flags+0x40/0xaa [mac80211] SS:ESP 0068:f6409a40 [ 348.530014] CR2: 00020040 [ 348.530014] ---[ end trace 48556ac26779732e ]--- [ 348.530014] Kernel panic - not syncing: Fatal exception in interrupt [ 348.530014] Kernel Offset: disabled Cc: sta...@vger.kernel.org Reported-by: Fred Veldini <fred.veld...@gmail.com> Tested-by: Fred Veldini <fred.veld...@gmail.com> Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- >From git history, this appears to go back to earliest commits adding authsae support. I reproduced in a 4.4 kernel, which predates all of the mesh pathtable rework, though it is harder to hit there than in the current code. This is slightly different from the version Fred tested (CCed) -- the version I sent him didn't have the BLOCK_MPATH part, but that seems necessary to me to prevent re-adding in hwmp_route_info_get(). But I can reproduce the above crash and this patch fixes it for me. --- net/mac80211/mesh_pathtbl.c | 4 net/mac80211/sta_info.c | 10 ++ net/mac80211/sta_info.h | 2 ++ 3 files changed, 16 insertions(+) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 6db2ddfa0695..798c522b6522 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -87,6 +87,10 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta) struct ieee80211_hdr *hdr; unsigned long flags; + /* sta is being deleted, don't add back */ + if (test_sta_flag(sta, WLAN_STA_BLOCK_MPATH)) + return; + rcu_assign_pointer(mpath->next_hop, sta); spin_lock_irqsave(>frame_queue.lock, flags); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 5ccfdbd406bd..f2a1bfa53c04 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -914,6 +914,16 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta) list_del_rcu(>list); sta->removed = true; + /* +* Remove all path table references to the station (and prevent +* adding new ones) so that new mesh transmissions won't use it +* as a next hop. +*/ + if (ieee80211_vif_is_mesh(>vif)) { + set_sta_flag(sta, WLAN_STA_BLOCK_MPATH); + mesh_path_flush_by_nexthop(sta); + } + drv_sta_pre_rcu_remove(local, sta->sdata, sta); if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index c8b8ccc370eb..65ecd3746c3b 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -70,6 +70,7 @@ * @WLAN_STA_MPSP_RECIPIENT: local STA is recipient of a MPSP. * @WLAN_STA_PS_DELIVER: station woke up, but we're still blocking TX * until pending frames are delivered + * @WLAN_STA_BLOCK_MPATH: block adding this station as a mesh path * * @NUM_WLAN_STA_FLAGS: number of defined flags */ @@ -100,6 +101,7 @@ enum ieee80211_sta_info_flags { WLAN_STA_MPSP_OWNER, WLAN_STA_MPSP_RECIPIENT, WLAN_STA_PS_DELIVER, + WLAN_STA_BLOCK_MPATH, NUM_WLAN_STA_FLAGS, }; -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ath9k: remove repetitions of mask array size
The constant "123", which is the number of elements in mask_m / mask_p, is repeated several times in this function. Replace memsets with array initialization, and replace a loop conditional with ARRAY_SIZE() so that we don't repeat ourselves. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 1b271b9..8eea8d2 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -260,8 +260,8 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah, int cur_bin; int upper, lower, cur_vit_mask; int i; - int8_t mask_m[123]; - int8_t mask_p[123]; + int8_t mask_m[123] = {0}; + int8_t mask_p[123] = {0}; int8_t mask_amt; int tmp_mask; static const int pilot_mask_reg[4] = { @@ -274,9 +274,6 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah, }; static const int inc[4] = { 0, 100, 0, 0 }; - memset(_m, 0, sizeof(int8_t) * 123); - memset(_p, 0, sizeof(int8_t) * 123); - cur_bin = -6000; upper = bin + 100; lower = bin - 100; @@ -302,7 +299,7 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah, upper = bin + 120; lower = bin - 120; - for (i = 0; i < 123; i++) { + for (i = 0; i < ARRAY_SIZE(mask_m); i++) { if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { /* workaround for gcc bug #37014 */ volatile int tmp_v = abs(cur_vit_mask - bin); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ath9k: ar5008_hw_cmn_spur_mitigate: add missing mask_m & mask_p initialisation
On Sat, Apr 16, 2016 at 08:01:59AM +0200, Oleksij Rempel wrote: > > For a future patch, "sizeof(mask_m)" or even just: > > > > u8 mask_m[123] = {0}; > > > > ... would be better here. I looked at this bit and thought, no way is > > "123" actually correct. Lo and behold, that is actually the number of > > array elements, whether that has a basis in something real or not :) > > If you already on it can you please rework it on top of this patch? > This complete function can be probably reworked. I wasn't on it, but yeah I'll send a patch on top of this momentarily :) -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ath9k: ar5008_hw_cmn_spur_mitigate: add missing mask_m & mask_p initialisation
On Tue, Apr 12, 2016 at 07:37:44PM +0200, Oleksij Rempel wrote: > by moving common code to ar5008_hw_cmn_spur_mitigate i forgot to move > mask_m & mask_p initialisation. This coused a performance regression > on ar9281. > > Fixes: f911085ffa88 ("ath9k: split ar5008_hw_spur_mitigate and reuse common > code in ar9002_hw_spur_mitigate.") > Reported-by: Gustav Frederiksen <lkml2...@openmailbox.org> > Tested-by: Gustav Frederiksen <lkml2...@openmailbox.org> > Signed-off-by: Oleksij Rempel <li...@rempel-privat.de> > --- > drivers/net/wireless/ath/ath9k/ar5008_phy.c | 8 +++- > drivers/net/wireless/ath/ath9k/ar9002_phy.c | 5 - > 2 files changed, 3 insertions(+), 10 deletions(-) > > diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c > b/drivers/net/wireless/ath/ath9k/ar5008_phy.c > index 8f87930..1b271b9 100644 > --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c > +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c > @@ -274,6 +274,9 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah, > }; > static const int inc[4] = { 0, 100, 0, 0 }; > > + memset(_m, 0, sizeof(int8_t) * 123); > + memset(_p, 0, sizeof(int8_t) * 123); > + For a future patch, "sizeof(mask_m)" or even just: u8 mask_m[123] = {0}; ... would be better here. I looked at this bit and thought, no way is "123" actually correct. Lo and behold, that is actually the number of array elements, whether that has a basis in something real or not :) -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
wireless-testing updated for 4.6
Linus released 4.6-rc1 yesterday, so wireless-testing is now updated to 4.6 and resuming near-daily updates. Do let me know of any issues. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] mac80211: mesh: fix cleanup for mesh pathtable
+0x14b/0x24e [ 47.753026] [] worker_thread+0x249/0x343 [ 47.753026] [] ? process_scheduled_works+0x24/0x24 [ 47.753026] [] kthread+0x9e/0xa3 [ 47.753026] [] ret_from_kernel_thread+0x20/0x40 [ 47.753026] [] ? kthread_parkme+0x18/0x18 [ 47.753026] Code: 6b c0 85 c0 75 05 e8 fb 74 fc ff 89 f8 84 c0 75 08 8d 45 e8 e8 34 dd 33 00 83 c4 28 5b 5e 5f 5d c3 55 8b 80 10 02 00 00 89 e5 5d <8b> 40 f0 c3 55 b9 04 00 00 00 89 e5 52 8b 90 10 02 00 00 8d 45 [ 47.753026] EIP: [] kthread_data+0xa/0xe SS:ESP 0068:f6463a78 [ 47.753026] CR2: fff0 [ 47.753026] ---[ end trace 867ca0bdd0767790 ]--- Fixes: 3b302ada7f0a ("mac80211: mesh: move path tables into if_mesh") Reported-by: Fred Veldini <fred.veld...@gmail.com> Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- Just to try to make it somewhat clear, there are a total of three outstanding patches to fix bugs in my half-baked rhashtable conversion: these two, and also "mac80211: mesh: fix crash in mesh_path_timer". The other series of 5 patches, starting with: "[PATCH 1/5] mac80211: mesh: handle failed alloc for rmc cache" -- are less critical, with the possible exception of 1/5, but I've never seen that one actually happen in the wild. I don't believe these patchsets will conflict with each other, but do let me know if I need to respin for something, or if we should drop the whole thing and I should resend with patches applied. net/mac80211/iface.c | 2 +- net/mac80211/mesh.c | 7 ++- net/mac80211/mesh.h | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 453b4e741780..097ece8b5c02 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1093,7 +1093,7 @@ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) sdata->fragment_next = 0; if (ieee80211_vif_is_mesh(>vif)) - mesh_rmc_free(sdata); + ieee80211_mesh_teardown_sdata(sdata); } static void ieee80211_uninit(struct net_device *dev) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 1a2aaf461e98..dcc1facc807c 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -905,7 +905,6 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) /* flush STAs and mpaths on this iface */ sta_info_flush(sdata); mesh_path_flush_by_iface(sdata); - mesh_pathtbl_unregister(sdata); /* free all potentially still buffered group-addressed frames */ local->total_ps_buffered -= skb_queue_len(>ps.bc_buf); @@ -1403,3 +1402,9 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) sdata->vif.bss_conf.bssid = zero_addr; } + +void ieee80211_mesh_teardown_sdata(struct ieee80211_sub_if_data *sdata) +{ + mesh_rmc_free(sdata); + mesh_pathtbl_unregister(sdata); +} diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index f298987228c9..26b9ccbe1fce 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -219,6 +219,7 @@ void ieee80211s_init(void); void ieee80211s_update_metric(struct ieee80211_local *local, struct sta_info *sta, struct sk_buff *skb); void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); +void ieee80211_mesh_teardown_sdata(struct ieee80211_sub_if_data *sdata); int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh); -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFCv2 0/3] mac80211: implement fq codel
On Wed, Mar 16, 2016 at 11:36:31AM -0700, Dave Taht wrote: > That is the sanest 802.11e queue behavior I have ever seen! (at both > 6 and 300mbit! in the ath10k patched mac test) Out of curiosity, why does BE have larger latency than BK in that chart? I'd have expected the opposite. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFCv2 0/3] mac80211: implement fq codel
On Thu, Mar 17, 2016 at 09:55:03AM +0100, Michal Kazior wrote: > If you consider Wi-Fi is half-duplex and latency in the entire stack > (for processing ICMP and UDP_RR) is greater than 11e contention window > timings you can get your BE flow responses with extra delay (since > other queues might have responses ready quicker). Got it, that makes sense. Thanks for the explanation! -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/5] mac80211: mesh: reorder structure members
Reduce padding waste in struct mesh_table and struct rmc_entry by moving the smaller fields to the end. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- net/mac80211/mesh.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 46b540a25d9d..4a59c034cc6d 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -133,11 +133,10 @@ struct mesh_path { * @rhash: the rhashtable containing struct mesh_paths, keyed by dest addr */ struct mesh_table { - atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ struct hlist_head known_gates; spinlock_t gates_lock; - struct rhashtable rhead; + atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ }; /* Recent multicast cache */ @@ -159,8 +158,8 @@ struct mesh_table { */ struct rmc_entry { struct hlist_node list; - u32 seqnum; unsigned long exp_time; + u32 seqnum; u8 sa[ETH_ALEN]; }; -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/5] mesh struct cleanups
This series makes a few minor mesh cleanups after the rhashtable rework -- mostly some reductions in padding and allocation waste. Bob Copeland (5): mac80211: mesh: handle failed alloc for rmc cache mac80211: mesh: use hlist for rmc cache mac80211: mesh: embed gates hlist head directly mac80211: mesh: reorder structure members mac80211: mesh: fix mesh path kerneldoc net/mac80211/mesh.c | 21 + net/mac80211/mesh.h | 31 +-- net/mac80211/mesh_pathtbl.c | 18 -- 3 files changed, 34 insertions(+), 36 deletions(-) -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
wireless-testing paused for merge window
With the release of 4.5, I did one last tag today in wireless-testing.git with the current state of the wireless trees (wt-2016-03-14). As I did for most of the last merge window, I plan to sit out the chaos and wait for 4.6-rc1 to resume the near-daily wireless-testing builds. See you in a couple of weeks... -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/RFT] mac80211: implement fq_codel for software queuing
On Tue, Mar 08, 2016 at 08:12:21AM +0100, Michal Kazior wrote: > However other drivers (e.g. ath10k) have offloaded rate control on > device. There's currently no way of doing this calculation. I was > thinking of drivers exporting tx_rate to mac80211 in some way - either > via a simple sta->tx_rate scalar that the driver is responsible for > updating, or a EWMA that driver updates (hopefully) periodically and > often enough. This should in theory at least allow an estimate how > much data on average you can fit into given time frame (e.g. txop, or > hardcoded 1ms). What about implementing ops->get_expected_throughput? This would be useful for mesh (both 11s and batman) as well since they need to estimate link quality to pick a path. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mac80211: mesh: fix crash in mesh_path_timer
The mesh_path_reclaim() function, called from an rcu callback, cancels the mesh_path_timer associated with a mesh path. Unfortunately, this call can happen much later, perhaps after the hash table itself is destroyed. Such a situation led to the following crash in mesh_path_send_to_gates() when dereferencing the tbl pointer: [ 23.901661] BUG: unable to handle kernel NULL pointer dereference at 0008 [ 23.905516] IP: [] mesh_path_send_to_gates+0x2b/0x740 [ 23.908757] PGD 99ca067 PUD 99c4067 PMD 0 [ 23.910789] Oops: [#1] PREEMPT SMP DEBUG_PAGEALLOC [ 23.913485] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.5.0-rc6-wt+ #43 [ 23.916675] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Debian-1.8.2-1 04/01/2014 [ 23.920471] task: 81685500 ti: 81678000 task.ti: 81678000 [ 23.922619] RIP: 0010:[] [] mesh_path_send_to_gates+0x2b/0x740 [ 23.925237] RSP: 0018:88000b403d30 EFLAGS: 00010286 [ 23.926739] RAX: RBX: 880009bc0d20 RCX: 0102 [ 23.928796] RDX: 002e RSI: 0001 RDI: 880009bc0d20 [ 23.930895] RBP: 88000b403e18 R08: 0001 R09: 0001 [ 23.932917] R10: R11: 0001 R12: 880009c20940 [ 23.936370] R13: 880009bc0e70 R14: 880009c21c40 R15: 880009bc0d20 [ 23.939823] FS: () GS:88000b40() knlGS: [ 23.943688] CS: 0010 DS: ES: CR0: 8005003b [ 23.946429] CR2: 0008 CR3: 099c5000 CR4: 06b0 [ 23.949861] Stack: [ 23.950840] 002e 880009c20940 88000b403da8 8109e551 [ 23.954467] 82711be2 002e 8166a5f5 [ 23.958141] 00685ce8 0246 880009bc0d20 880009c20940 [ 23.961801] Call Trace: [ 23.962987] [ 23.963963] [] ? vprintk_emit+0x351/0x5e0 [ 23.966782] [] ? vprintk_default+0x1f/0x30 [ 23.969529] [] ? printk+0x48/0x50 [ 23.971956] [] mesh_path_timer+0x133/0x160 [ 23.974707] [] ? mesh_nexthop_resolve+0x230/0x230 [ 23.95] [] call_timer_fn+0xce/0x330 [ 23.980448] [] ? call_timer_fn+0x5/0x330 [ 23.983126] [] ? mesh_nexthop_resolve+0x230/0x230 [ 23.986091] [] run_timer_softirq+0x22c/0x390 Instead of cancelling in the RCU callback, set a new flag to prevent the timer from being rearmed, and then cancel the timer synchronously when freeing the mesh path. This leaves mesh_path_reclaim() doing nothing but kfree, so switch to kfree_rcu(). Fixes: 3b302ada7f0a ("mac80211: mesh: move path tables into if_mesh") Reported-by: Jouni Malinen <j...@w1.fi> Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- net/mac80211/mesh.h | 3 +++ net/mac80211/mesh_hwmp.c| 2 ++ net/mac80211/mesh_pathtbl.c | 34 +++--- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index cc6854db156e..e1415c952e9c 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -32,6 +32,8 @@ * @MESH_PATH_RESOLVED: the mesh path can has been resolved * @MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination * already queued up, waiting for the discovery process to start. + * @MESH_PATH_DELETED: the mesh path has been deleted and should no longer + * be used * * MESH_PATH_RESOLVED is used by the mesh path timer to * decide when to stop or cancel the mesh path discovery. @@ -43,6 +45,7 @@ enum mesh_path_flags { MESH_PATH_FIXED = BIT(3), MESH_PATH_RESOLVED =BIT(4), MESH_PATH_REQ_QUEUED = BIT(5), + MESH_PATH_DELETED = BIT(6), }; /** diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index c6be0b4f4058..bdf4647c158c 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -1012,6 +1012,8 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) goto enddiscovery; spin_lock_bh(>state_lock); + if (mpath->flags & MESH_PATH_DELETED) + goto enddiscovery; mpath->flags &= ~MESH_PATH_REQ_QUEUED; if (preq_node->flags & PREQ_Q_F_START) { if (mpath->flags & MESH_PATH_RESOLVING) { diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 7455397f8c3b..2c2c81e1d7c9 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -18,6 +18,9 @@ #include "ieee80211_i.h" #include "mesh.h" +static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath); +static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath); + static u32 mesh_table_hash(const void *addr, u32 len, u32 seed) { /* Use last four bytes of hw addr as hash index */ @@ -40,18 +43,12 @@ static inline
refcnt fix in wireless-testing
Just a quick note that if you are using a recent wireless-testing, there's a reference counting bug which was fixed in net-next: https://git.kernel.org/davem/net-next/c/799977d9aaf I've cherry-picked this commit for today's build and will keep doing so for the 4.5.x series or until no longer needed. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] rhashtable: accept GFP flags in rhashtable_walk_init
On Thu, Mar 03, 2016 at 04:26:19PM +0100, Johannes Berg wrote: > On Wed, 2016-03-02 at 10:09 -0500, Bob Copeland wrote: > > In certain cases, the 802.11 mesh pathtable code wants to > > iterate over all of the entries in the forwarding table from > > the receive path, which is inside an RCU read-side critical > > section. Enable walks inside atomic sections by allowing > > GFP_ATOMIC allocations for the walker state. > > > > Change all existing callsites to pass in GFP_KERNEL. > > Applied both. You missed 3 callsites, I've fixed those. I hope I got > them all :) Ouch, thanks for the catch, I must've grepped only in net. And now I added those files to my build config. :) -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] rhashtable: accept GFP flags in rhashtable_walk_init
In certain cases, the 802.11 mesh pathtable code wants to iterate over all of the entries in the forwarding table from the receive path, which is inside an RCU read-side critical section. Enable walks inside atomic sections by allowing GFP_ATOMIC allocations for the walker state. Change all existing callsites to pass in GFP_KERNEL. Cc: Thomas Graf <tg...@suug.ch> Cc: net...@vger.kernel.org Acked-by: Thomas Graf <tg...@suug.ch> Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- (-RFC, +Thomas's Ack) include/linux/rhashtable.h | 3 ++- lib/rhashtable.c | 6 -- net/ipv6/ila/ila_xlat.c| 3 ++- net/netfilter/nft_hash.c | 4 ++-- net/netlink/af_netlink.c | 3 ++- net/sctp/proc.c| 3 ++- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 63bd7601b6de..3eef0802a0cd 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -346,7 +346,8 @@ struct bucket_table *rhashtable_insert_slow(struct rhashtable *ht, struct bucket_table *old_tbl); int rhashtable_insert_rehash(struct rhashtable *ht, struct bucket_table *tbl); -int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter); +int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter, +gfp_t gfp); void rhashtable_walk_exit(struct rhashtable_iter *iter); int rhashtable_walk_start(struct rhashtable_iter *iter) __acquires(RCU); void *rhashtable_walk_next(struct rhashtable_iter *iter); diff --git a/lib/rhashtable.c b/lib/rhashtable.c index cc808707d1cf..5d845ffd7982 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -487,6 +487,7 @@ EXPORT_SYMBOL_GPL(rhashtable_insert_slow); * rhashtable_walk_init - Initialise an iterator * @ht:Table to walk over * @iter: Hash table Iterator + * @gfp: GFP flags for allocations * * This function prepares a hash table walk. * @@ -504,14 +505,15 @@ EXPORT_SYMBOL_GPL(rhashtable_insert_slow); * You must call rhashtable_walk_exit if this function returns * successfully. */ -int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter) +int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter, +gfp_t gfp) { iter->ht = ht; iter->p = NULL; iter->slot = 0; iter->skip = 0; - iter->walker = kmalloc(sizeof(*iter->walker), GFP_KERNEL); + iter->walker = kmalloc(sizeof(*iter->walker), gfp); if (!iter->walker) return -ENOMEM; diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c index 295ca29a23c3..0b03533453e4 100644 --- a/net/ipv6/ila/ila_xlat.c +++ b/net/ipv6/ila/ila_xlat.c @@ -501,7 +501,8 @@ static int ila_nl_dump_start(struct netlink_callback *cb) struct ila_net *ilan = net_generic(net, ila_net_id); struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args; - return rhashtable_walk_init(>rhash_table, >rhiter); + return rhashtable_walk_init(>rhash_table, >rhiter, + GFP_KERNEL); } static int ila_nl_dump_done(struct netlink_callback *cb) diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c index 3f9d45d3d9b7..6fa016564f90 100644 --- a/net/netfilter/nft_hash.c +++ b/net/netfilter/nft_hash.c @@ -192,7 +192,7 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set, u8 genmask = nft_genmask_cur(read_pnet(>pnet)); int err; - err = rhashtable_walk_init(>ht, ); + err = rhashtable_walk_init(>ht, , GFP_KERNEL); iter->err = err; if (err) return; @@ -248,7 +248,7 @@ static void nft_hash_gc(struct work_struct *work) priv = container_of(work, struct nft_hash, gc_work.work); set = nft_set_container_of(priv); - err = rhashtable_walk_init(>ht, ); + err = rhashtable_walk_init(>ht, , GFP_KERNEL); if (err) goto schedule; diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index c8416792cce0..6e0cbdeb21d3 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2335,7 +2335,8 @@ static int netlink_walk_start(struct nl_seq_iter *iter) { int err; - err = rhashtable_walk_init(_table[iter->link].hash, >hti); + err = rhashtable_walk_init(_table[iter->link].hash, >hti, + GFP_KERNEL); if (err) { iter->link = MAX_LINKS; return err; diff --git a/net/sctp/proc.c b/net/sctp/proc.c index cfc3c7101a38..c5991e5e5daf 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -319,7 +319,8 @@ static int sctp_transport_walk_start(struct seq_file *seq) struct sctp_ht_iter *iter = seq->private
[PATCH 2/2] mac80211: mesh: convert path table to rhashtable
In the time since the mesh path table was implemented as an RCU-traversable, dynamically growing hash table, a generic RCU hashtable implementation was added to the kernel. Switch the mesh path table over to rhashtable to remove some code and also gain some features like automatic shrinking. Cc: Thomas Graf <tg...@suug.ch> Cc: net...@vger.kernel.org Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- net/mac80211/ieee80211_i.h | 11 +- net/mac80211/mesh.c | 6 - net/mac80211/mesh.h | 31 +- net/mac80211/mesh_pathtbl.c | 786 ++-- 4 files changed, 259 insertions(+), 575 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index db7f0dbebc4b..c8945e2d8a86 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -697,17 +697,10 @@ struct ieee80211_if_mesh { /* offset from skb->data while building IE */ int meshconf_offset; - struct mesh_table __rcu *mesh_paths; - struct mesh_table __rcu *mpp_paths; /* Store paths for MPP */ + struct mesh_table *mesh_paths; + struct mesh_table *mpp_paths; /* Store paths for MPP */ int mesh_paths_generation; int mpp_paths_generation; - - /* Protects assignment of the mesh_paths/mpp_paths table -* pointer for resize against reading it for add/delete -* of individual paths. Pure readers (lookups) just use -* RCU. -*/ - rwlock_t pathtbl_resize_lock; }; #ifdef CONFIG_MAC80211_MESH diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index c92af2a7714d..a216c439b6f2 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -1347,12 +1347,6 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval))) mesh_path_start_discovery(sdata); - if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, >wrkq_flags)) - mesh_mpath_table_grow(sdata); - - if (test_and_clear_bit(MESH_WORK_GROW_MPP_TABLE, >wrkq_flags)) - mesh_mpp_table_grow(sdata); - if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, >wrkq_flags)) ieee80211_mesh_housekeeping(sdata); diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index f3cc3917e048..cc6854db156e 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -51,10 +51,6 @@ enum mesh_path_flags { * * * @MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks - * @MESH_WORK_GROW_MPATH_TABLE: the mesh path table is full and needs - * to grow. - * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to - * grow * @MESH_WORK_ROOT: the mesh root station needs to send a frame * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other * mesh nodes @@ -62,8 +58,6 @@ enum mesh_path_flags { */ enum mesh_deferred_task_flags { MESH_WORK_HOUSEKEEPING, - MESH_WORK_GROW_MPATH_TABLE, - MESH_WORK_GROW_MPP_TABLE, MESH_WORK_ROOT, MESH_WORK_DRIFT_ADJUST, MESH_WORK_MBSS_CHANGED, @@ -105,6 +99,7 @@ enum mesh_deferred_task_flags { struct mesh_path { u8 dst[ETH_ALEN]; u8 mpp[ETH_ALEN]; /* used for MPP or MAP */ + struct rhash_head rhash; struct hlist_node gate_list; struct ieee80211_sub_if_data *sdata; struct sta_info __rcu *next_hop; @@ -129,34 +124,17 @@ struct mesh_path { /** * struct mesh_table * - * @hash_buckets: array of hash buckets of the table - * @hashwlock: array of locks to protect write operations, one per bucket - * @hash_mask: 2^size_order - 1, used to compute hash idx - * @hash_rnd: random value used for hash computations * @entries: number of entries in the table - * @free_node: function to free nodes of the table - * @copy_node: function to copy nodes of the table - * @size_order: determines size of the table, there will be 2^size_order hash - * buckets * @known_gates: list of known mesh gates and their mpaths by the station. The * gate's mpath may or may not be resolved and active. - * - * rcu_head: RCU head to free the table + * @rhash: the rhashtable containing struct mesh_paths, keyed by dest addr */ struct mesh_table { - /* Number of buckets will be 2^N */ - struct hlist_head *hash_buckets; - spinlock_t *hashwlock; /* One per bucket, for add/del */ - unsigned int hash_mask; /* (2^size_order) - 1 */ - __u32 hash_rnd; /* Used for hash generation */ atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ - void (*free_node) (struct hlist_node *p, bool free_leafs); - int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); - int size_order; struct hlist_head *known_gates; spinlock_t gates_lock; - struct rcu_head rcu_head; +
Re: [PATCH RFC 1/2] rhashtable: accept GFP flags in rhashtable_walk_init
On Tue, Mar 01, 2016 at 02:54:16PM +0100, Johannes Berg wrote: > On Sun, 2016-02-28 at 20:06 -0500, Bob Copeland wrote: > > In certain cases, the 802.11 mesh pathtable code wants to > > iterate over all of the entries in the forwarding table from > > the receive path, which is inside an RCU read-side critical > > section. Enable walks inside atomic sections by allowing > > GFP_ATOMIC allocations for the walker state. > > > > Change all existing callsites to pass in GFP_KERNEL. > > Both look fine to me. > > I see you have more patches for mesh, so this probably can't go through > net-next tree directly. Yeah, these two are on top of the other mesh path table changes. So either both of these could go via mac80211-next or we could do the 1/2 in net-next and wait to apply 2/2 in mac80211-next. Whatever works for you guys. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] ath9k: fix a misleading indentation
These lines belong inside the if-statement above, not in the main body of the switch. Found by smatch. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 201425e7f9cb..3e011f84211f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1332,11 +1332,11 @@ skip_ws_det: chan->channel, aniState->mrcCCK ? "on" : "off", is_on ? "on" : "off"); - if (is_on) - ah->stats.ast_ani_ccklow++; - else - ah->stats.ast_ani_cckhigh++; - aniState->mrcCCK = is_on; + if (is_on) + ah->stats.ast_ani_ccklow++; + else + ah->stats.ast_ani_cckhigh++; + aniState->mrcCCK = is_on; } break; } -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] ath9k_htc: fix up indents with spaces
Use tabs here. Found by smatch. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 8647ab77c019..c2249ad54085 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -262,11 +262,11 @@ static void ath9k_multi_regread(void *hw_priv, u32 *addr, __be32 tmpval[8]; int i, ret; - for (i = 0; i < count; i++) { - tmpaddr[i] = cpu_to_be32(addr[i]); - } + for (i = 0; i < count; i++) { + tmpaddr[i] = cpu_to_be32(addr[i]); + } - ret = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID, + ret = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID, (u8 *)tmpaddr , sizeof(u32) * count, (u8 *)tmpval, sizeof(u32) * count, 100); @@ -275,9 +275,9 @@ static void ath9k_multi_regread(void *hw_priv, u32 *addr, "Multiple REGISTER READ FAILED (count: %d)\n", count); } - for (i = 0; i < count; i++) { - val[i] = be32_to_cpu(tmpval[i]); - } + for (i = 0; i < count; i++) { + val[i] = be32_to_cpu(tmpval[i]); + } } static void ath9k_regwrite_multi(struct ath_common *common) -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 1/2] rhashtable: accept GFP flags in rhashtable_walk_init
In certain cases, the 802.11 mesh pathtable code wants to iterate over all of the entries in the forwarding table from the receive path, which is inside an RCU read-side critical section. Enable walks inside atomic sections by allowing GFP_ATOMIC allocations for the walker state. Change all existing callsites to pass in GFP_KERNEL. Cc: Thomas Graf <tg...@suug.ch> Cc: net...@vger.kernel.org Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- include/linux/rhashtable.h | 3 ++- lib/rhashtable.c | 6 -- net/ipv6/ila/ila_xlat.c| 3 ++- net/netfilter/nft_hash.c | 4 ++-- net/netlink/af_netlink.c | 3 ++- net/sctp/proc.c| 3 ++- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 63bd7601b6de..3eef0802a0cd 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -346,7 +346,8 @@ struct bucket_table *rhashtable_insert_slow(struct rhashtable *ht, struct bucket_table *old_tbl); int rhashtable_insert_rehash(struct rhashtable *ht, struct bucket_table *tbl); -int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter); +int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter, +gfp_t gfp); void rhashtable_walk_exit(struct rhashtable_iter *iter); int rhashtable_walk_start(struct rhashtable_iter *iter) __acquires(RCU); void *rhashtable_walk_next(struct rhashtable_iter *iter); diff --git a/lib/rhashtable.c b/lib/rhashtable.c index cc808707d1cf..5d845ffd7982 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -487,6 +487,7 @@ EXPORT_SYMBOL_GPL(rhashtable_insert_slow); * rhashtable_walk_init - Initialise an iterator * @ht:Table to walk over * @iter: Hash table Iterator + * @gfp: GFP flags for allocations * * This function prepares a hash table walk. * @@ -504,14 +505,15 @@ EXPORT_SYMBOL_GPL(rhashtable_insert_slow); * You must call rhashtable_walk_exit if this function returns * successfully. */ -int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter) +int rhashtable_walk_init(struct rhashtable *ht, struct rhashtable_iter *iter, +gfp_t gfp) { iter->ht = ht; iter->p = NULL; iter->slot = 0; iter->skip = 0; - iter->walker = kmalloc(sizeof(*iter->walker), GFP_KERNEL); + iter->walker = kmalloc(sizeof(*iter->walker), gfp); if (!iter->walker) return -ENOMEM; diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c index 295ca29a23c3..0b03533453e4 100644 --- a/net/ipv6/ila/ila_xlat.c +++ b/net/ipv6/ila/ila_xlat.c @@ -501,7 +501,8 @@ static int ila_nl_dump_start(struct netlink_callback *cb) struct ila_net *ilan = net_generic(net, ila_net_id); struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args; - return rhashtable_walk_init(>rhash_table, >rhiter); + return rhashtable_walk_init(>rhash_table, >rhiter, + GFP_KERNEL); } static int ila_nl_dump_done(struct netlink_callback *cb) diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c index 3f9d45d3d9b7..6fa016564f90 100644 --- a/net/netfilter/nft_hash.c +++ b/net/netfilter/nft_hash.c @@ -192,7 +192,7 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set, u8 genmask = nft_genmask_cur(read_pnet(>pnet)); int err; - err = rhashtable_walk_init(>ht, ); + err = rhashtable_walk_init(>ht, , GFP_KERNEL); iter->err = err; if (err) return; @@ -248,7 +248,7 @@ static void nft_hash_gc(struct work_struct *work) priv = container_of(work, struct nft_hash, gc_work.work); set = nft_set_container_of(priv); - err = rhashtable_walk_init(>ht, ); + err = rhashtable_walk_init(>ht, , GFP_KERNEL); if (err) goto schedule; diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index c8416792cce0..6e0cbdeb21d3 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2335,7 +2335,8 @@ static int netlink_walk_start(struct nl_seq_iter *iter) { int err; - err = rhashtable_walk_init(_table[iter->link].hash, >hti); + err = rhashtable_walk_init(_table[iter->link].hash, >hti, + GFP_KERNEL); if (err) { iter->link = MAX_LINKS; return err; diff --git a/net/sctp/proc.c b/net/sctp/proc.c index cfc3c7101a38..c5991e5e5daf 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -319,7 +319,8 @@ static int sctp_transport_walk_start(struct seq_file *seq) struct sctp_ht_iter *iter = seq->private; int err; - err = rhashtable_walk_init(
[PATCH RFC 2/2] mac80211: mesh: convert path table to rhashtable
In the time since the mesh path table was implemented as an RCU-traversable, dynamically growing hash table, a generic RCU hashtable implementation was added to the kernel. Switch the mesh path table over to rhashtable to remove some code and also gain some features like automatic shrinking. Cc: Thomas Graf <tg...@suug.ch> Cc: net...@vger.kernel.org Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- net/mac80211/ieee80211_i.h | 11 +- net/mac80211/mesh.c | 6 - net/mac80211/mesh.h | 31 +- net/mac80211/mesh_pathtbl.c | 786 ++-- 4 files changed, 259 insertions(+), 575 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 597f1b6260f4..a2857cd6d479 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -697,17 +697,10 @@ struct ieee80211_if_mesh { /* offset from skb->data while building IE */ int meshconf_offset; - struct mesh_table __rcu *mesh_paths; - struct mesh_table __rcu *mpp_paths; /* Store paths for MPP */ + struct mesh_table *mesh_paths; + struct mesh_table *mpp_paths; /* Store paths for MPP */ int mesh_paths_generation; int mpp_paths_generation; - - /* Protects assignment of the mesh_paths/mpp_paths table -* pointer for resize against reading it for add/delete -* of individual paths. Pure readers (lookups) just use -* RCU. -*/ - rwlock_t pathtbl_resize_lock; }; #ifdef CONFIG_MAC80211_MESH diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index c92af2a7714d..a216c439b6f2 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -1347,12 +1347,6 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval))) mesh_path_start_discovery(sdata); - if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, >wrkq_flags)) - mesh_mpath_table_grow(sdata); - - if (test_and_clear_bit(MESH_WORK_GROW_MPP_TABLE, >wrkq_flags)) - mesh_mpp_table_grow(sdata); - if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, >wrkq_flags)) ieee80211_mesh_housekeeping(sdata); diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index f3cc3917e048..cc6854db156e 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -51,10 +51,6 @@ enum mesh_path_flags { * * * @MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks - * @MESH_WORK_GROW_MPATH_TABLE: the mesh path table is full and needs - * to grow. - * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to - * grow * @MESH_WORK_ROOT: the mesh root station needs to send a frame * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other * mesh nodes @@ -62,8 +58,6 @@ enum mesh_path_flags { */ enum mesh_deferred_task_flags { MESH_WORK_HOUSEKEEPING, - MESH_WORK_GROW_MPATH_TABLE, - MESH_WORK_GROW_MPP_TABLE, MESH_WORK_ROOT, MESH_WORK_DRIFT_ADJUST, MESH_WORK_MBSS_CHANGED, @@ -105,6 +99,7 @@ enum mesh_deferred_task_flags { struct mesh_path { u8 dst[ETH_ALEN]; u8 mpp[ETH_ALEN]; /* used for MPP or MAP */ + struct rhash_head rhash; struct hlist_node gate_list; struct ieee80211_sub_if_data *sdata; struct sta_info __rcu *next_hop; @@ -129,34 +124,17 @@ struct mesh_path { /** * struct mesh_table * - * @hash_buckets: array of hash buckets of the table - * @hashwlock: array of locks to protect write operations, one per bucket - * @hash_mask: 2^size_order - 1, used to compute hash idx - * @hash_rnd: random value used for hash computations * @entries: number of entries in the table - * @free_node: function to free nodes of the table - * @copy_node: function to copy nodes of the table - * @size_order: determines size of the table, there will be 2^size_order hash - * buckets * @known_gates: list of known mesh gates and their mpaths by the station. The * gate's mpath may or may not be resolved and active. - * - * rcu_head: RCU head to free the table + * @rhash: the rhashtable containing struct mesh_paths, keyed by dest addr */ struct mesh_table { - /* Number of buckets will be 2^N */ - struct hlist_head *hash_buckets; - spinlock_t *hashwlock; /* One per bucket, for add/del */ - unsigned int hash_mask; /* (2^size_order) - 1 */ - __u32 hash_rnd; /* Used for hash generation */ atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ - void (*free_node) (struct hlist_node *p, bool free_leafs); - int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); - int size_order; struct hlist_head *known_gates; spinlock_t gates_lock; - struct rcu_head rcu_head; +
[PATCH 4/4] mac80211: mesh: embed known gates list in struct mesh_path
The mesh path table uses a struct mesh_node in its hlists in order to support a resizable hash table: the mesh_node provides an indirection to the actual mesh path so that two different bucket lists can point to the same path entry. However, for the known gates list, we don't need this indirection because there is ever only one list. So we can just embed the hlist_node in the mesh path itself, which simplifies things a bit and saves a linear search whenever we need to find an item in the list. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- net/mac80211/mesh.h | 1 + net/mac80211/mesh_pathtbl.c | 100 +++- 2 files changed, 45 insertions(+), 56 deletions(-) diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 601992b6cd8a..f3cc3917e048 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -105,6 +105,7 @@ enum mesh_deferred_task_flags { struct mesh_path { u8 dst[ETH_ALEN]; u8 mpp[ETH_ALEN]; /* used for MPP or MAP */ + struct hlist_node gate_list; struct ieee80211_sub_if_data *sdata; struct sta_info __rcu *next_hop; struct timer_list timer; diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 4794240e8f94..e4daf4b94eaf 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -119,10 +119,18 @@ static void mesh_table_free(struct mesh_table *tbl, bool free_leafs) { struct hlist_head *mesh_hash; struct hlist_node *p, *q; - struct mpath_node *gate; + struct mesh_path *gate; int i; mesh_hash = tbl->hash_buckets; + if (free_leafs) { + spin_lock_bh(>gates_lock); + hlist_for_each_entry_safe(gate, q, + tbl->known_gates, gate_list) + hlist_del(>gate_list); + kfree(tbl->known_gates); + spin_unlock_bh(>gates_lock); + } for (i = 0; i <= tbl->hash_mask; i++) { spin_lock_bh(>hashwlock[i]); hlist_for_each_safe(p, q, _hash[i]) { @@ -131,16 +139,6 @@ static void mesh_table_free(struct mesh_table *tbl, bool free_leafs) } spin_unlock_bh(>hashwlock[i]); } - if (free_leafs) { - spin_lock_bh(>gates_lock); - hlist_for_each_entry_safe(gate, q, -tbl->known_gates, list) { - hlist_del(>list); - kfree(gate); - } - kfree(tbl->known_gates); - spin_unlock_bh(>gates_lock); - } __mesh_table_free(tbl); } @@ -431,30 +429,26 @@ mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) int mesh_path_add_gate(struct mesh_path *mpath) { struct mesh_table *tbl; - struct mpath_node *gate, *new_gate; int err; rcu_read_lock(); tbl = rcu_dereference(mpath->sdata->u.mesh.mesh_paths); - hlist_for_each_entry_rcu(gate, tbl->known_gates, list) - if (gate->mpath == mpath) { - err = -EEXIST; - goto err_rcu; - } - - new_gate = kzalloc(sizeof(struct mpath_node), GFP_ATOMIC); - if (!new_gate) { - err = -ENOMEM; + spin_lock_bh(>state_lock); + if (mpath->is_gate) { + err = -EEXIST; + spin_unlock_bh(>state_lock); goto err_rcu; } - mpath->is_gate = true; mpath->sdata->u.mesh.num_gates++; - new_gate->mpath = mpath; - spin_lock_bh(>gates_lock); - hlist_add_head_rcu(_gate->list, tbl->known_gates); - spin_unlock_bh(>gates_lock); + + spin_lock(>gates_lock); + hlist_add_head_rcu(>gate_list, tbl->known_gates); + spin_unlock(>gates_lock); + + spin_unlock_bh(>state_lock); + mpath_dbg(mpath->sdata, "Mesh path: Recorded new gate: %pM. %d known gates\n", mpath->dst, mpath->sdata->u.mesh.num_gates); @@ -468,28 +462,22 @@ err_rcu: * mesh_gate_del - remove a mesh gate from the list of known gates * @tbl: table which holds our list of known gates * @mpath: gate mpath - * - * Locking: must be called inside rcu_read_lock() section */ static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath) { - struct mpath_node *gate; - struct hlist_node *q; + lockdep_assert_held(>state_lock); + if (!mpath->is_gate) + return; - hlist_for_each_entry_safe(gate, q, tbl->known_gates, list) { - if (gate->mpath != mpath) - continue; - spin_lock_bh(>gates_lock); - hlist_del_rcu(>list); -
[PATCH 1/4] mac80211: mesh: move path tables into if_mesh
The mesh path and mesh gate hashtables are global, containing all of the mpaths for every mesh interface, but the paths are all tied logically to a single interface. The common case is just a single mesh interface, so optimize for that by moving the global hashtable into the per-interface struct. Doing so allows us to drop sdata pointer comparisons inside the lookups and also saves a few bytes of BSS and data. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- net/mac80211/cfg.c | 4 +- net/mac80211/ieee80211_i.h | 12 +++ net/mac80211/mesh.c | 10 ++- net/mac80211/mesh.h | 10 +-- net/mac80211/mesh_pathtbl.c | 181 +++- net/mac80211/tx.c | 2 +- 6 files changed, 104 insertions(+), 115 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index fe1704c4e8fb..b37adb60c9cb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1499,7 +1499,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, memset(pinfo, 0, sizeof(*pinfo)); - pinfo->generation = mesh_paths_generation; + pinfo->generation = mpath->sdata->u.mesh.mesh_paths_generation; pinfo->filled = MPATH_INFO_FRAME_QLEN | MPATH_INFO_SN | @@ -1577,7 +1577,7 @@ static void mpp_set_pinfo(struct mesh_path *mpath, u8 *mpp, memset(pinfo, 0, sizeof(*pinfo)); memcpy(mpp, mpath->mpp, ETH_ALEN); - pinfo->generation = mpp_paths_generation; + pinfo->generation = mpath->sdata->u.mesh.mpp_paths_generation; } static int ieee80211_get_mpp(struct wiphy *wiphy, struct net_device *dev, diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 1630975c89f1..597f1b6260f4 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -696,6 +696,18 @@ struct ieee80211_if_mesh { /* offset from skb->data while building IE */ int meshconf_offset; + + struct mesh_table __rcu *mesh_paths; + struct mesh_table __rcu *mpp_paths; /* Store paths for MPP */ + int mesh_paths_generation; + int mpp_paths_generation; + + /* Protects assignment of the mesh_paths/mpp_paths table +* pointer for resize against reading it for add/delete +* of individual paths. Pure readers (lookups) just use +* RCU. +*/ + rwlock_t pathtbl_resize_lock; }; #ifdef CONFIG_MAC80211_MESH diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index d32cefcb63b0..c92af2a7714d 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -25,7 +25,6 @@ bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt) void ieee80211s_init(void) { - mesh_pathtbl_init(); mesh_allocated = 1; rm_cache = kmem_cache_create("mesh_rmc", sizeof(struct rmc_entry), 0, 0, NULL); @@ -35,7 +34,6 @@ void ieee80211s_stop(void) { if (!mesh_allocated) return; - mesh_pathtbl_unregister(); kmem_cache_destroy(rm_cache); } @@ -902,6 +900,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) /* flush STAs and mpaths on this iface */ sta_info_flush(sdata); mesh_path_flush_by_iface(sdata); + mesh_pathtbl_unregister(sdata); /* free all potentially still buffered group-addressed frames */ local->total_ps_buffered -= skb_queue_len(>ps.bc_buf); @@ -1349,10 +1348,10 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) mesh_path_start_discovery(sdata); if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, >wrkq_flags)) - mesh_mpath_table_grow(); + mesh_mpath_table_grow(sdata); if (test_and_clear_bit(MESH_WORK_GROW_MPP_TABLE, >wrkq_flags)) - mesh_mpp_table_grow(); + mesh_mpp_table_grow(sdata); if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, >wrkq_flags)) ieee80211_mesh_housekeeping(sdata); @@ -1388,6 +1387,9 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) /* Allocate all mesh structures when creating the first mesh interface. */ if (!mesh_allocated) ieee80211s_init(); + + mesh_pathtbl_init(sdata); + setup_timer(>mesh_path_timer, ieee80211_mesh_path_timer, (unsigned long) sdata); diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 87c017a3b1ce..601992b6cd8a 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -300,8 +300,8 @@ void mesh_sta_cleanup(struct sta_info *sta); /* Private interfaces */ /* Mesh tables */ -void mesh_mpath_table_grow(void); -void mesh_mpp_table_grow(void); +void mesh_mpath_table_grow(struct ieee80211_sub_if_data *sdata); +void mesh_mpp_table_grow(struct ieee80211_sub_if_data *sdata); /* Mesh p
[PATCH 2/4] mac80211: mesh: don't hash sdata in mpath tables
Now that the sdata pointer is the same for all entries of a path table, hashing it is pointless, so hash only the address. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- net/mac80211/mesh_pathtbl.c | 18 -- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 0508b37b0471..fc3cc350df8c 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -177,12 +177,10 @@ errcopy: return -ENOMEM; } -static u32 mesh_table_hash(const u8 *addr, struct ieee80211_sub_if_data *sdata, - struct mesh_table *tbl) +static u32 mesh_table_hash(const u8 *addr, struct mesh_table *tbl) { - /* Use last four bytes of hw addr and interface index as hash index */ - return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, - tbl->hash_rnd) & tbl->hash_mask; + /* Use last four bytes of hw addr as hash index */ + return jhash_1word(*(u32 *)(addr+2), tbl->hash_rnd) & tbl->hash_mask; } @@ -331,7 +329,7 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst, struct hlist_head *bucket; struct mpath_node *node; - bucket = >hash_buckets[mesh_table_hash(dst, sdata, tbl)]; + bucket = >hash_buckets[mesh_table_hash(dst, tbl)]; hlist_for_each_entry_rcu(node, bucket, list) { mpath = node->mpath; if (ether_addr_equal(dst, mpath->dst)) { @@ -538,7 +536,7 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata, read_lock_bh(>u.mesh.pathtbl_resize_lock); tbl = resize_dereference_mesh_paths(sdata); - hash_idx = mesh_table_hash(dst, sdata, tbl); + hash_idx = mesh_table_hash(dst, tbl); bucket = >hash_buckets[hash_idx]; spin_lock(>hashwlock[hash_idx]); @@ -687,7 +685,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata, tbl = resize_dereference_mpp_paths(sdata); - hash_idx = mesh_table_hash(dst, sdata, tbl); + hash_idx = mesh_table_hash(dst, tbl); bucket = >hash_buckets[hash_idx]; spin_lock(>hashwlock[hash_idx]); @@ -905,7 +903,7 @@ static int table_path_del(struct mesh_table __rcu *rcu_tbl, int err = 0; tbl = resize_dereference_paths(sdata, rcu_tbl); - hash_idx = mesh_table_hash(addr, sdata, tbl); + hash_idx = mesh_table_hash(addr, tbl); bucket = >hash_buckets[hash_idx]; spin_lock(>hashwlock[hash_idx]); @@ -1107,7 +1105,7 @@ static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl) node = hlist_entry(p, struct mpath_node, list); mpath = node->mpath; new_node->mpath = mpath; - hash_idx = mesh_table_hash(mpath->dst, mpath->sdata, newtbl); + hash_idx = mesh_table_hash(mpath->dst, newtbl); hlist_add_head(_node->list, >hash_buckets[hash_idx]); return 0; -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] mesh: factor out common mesh path allocation code
Remove duplicate code to allocate and initialize a mesh path or mesh proxy path. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- net/mac80211/mesh_pathtbl.c | 51 + 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index fc3cc350df8c..4794240e8f94 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -501,6 +501,31 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata) return sdata->u.mesh.num_gates; } +static +struct mesh_path *mesh_path_new(struct ieee80211_sub_if_data *sdata, + const u8 *dst, gfp_t gfp_flags) +{ + struct mesh_path *new_mpath; + + new_mpath = kzalloc(sizeof(struct mesh_path), gfp_flags); + if (!new_mpath) + return NULL; + + memcpy(new_mpath->dst, dst, ETH_ALEN); + eth_broadcast_addr(new_mpath->rann_snd_addr); + new_mpath->is_root = false; + new_mpath->sdata = sdata; + new_mpath->flags = 0; + skb_queue_head_init(_mpath->frame_queue); + new_mpath->timer.data = (unsigned long) new_mpath; + new_mpath->timer.function = mesh_path_timer; + new_mpath->exp_time = jiffies; + spin_lock_init(_mpath->state_lock); + init_timer(_mpath->timer); + + return new_mpath; +} + /** * mesh_path_add - allocate and add a new path to the mesh path table * @dst: destination address of the path (ETH_ALEN length) @@ -548,7 +573,7 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata, } err = -ENOMEM; - new_mpath = kzalloc(sizeof(struct mesh_path), GFP_ATOMIC); + new_mpath = mesh_path_new(sdata, dst, GFP_ATOMIC); if (!new_mpath) goto err_path_alloc; @@ -556,19 +581,7 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata, if (!new_node) goto err_node_alloc; - memcpy(new_mpath->dst, dst, ETH_ALEN); - eth_broadcast_addr(new_mpath->rann_snd_addr); - new_mpath->is_root = false; - new_mpath->sdata = sdata; - new_mpath->flags = 0; - skb_queue_head_init(_mpath->frame_queue); new_node->mpath = new_mpath; - new_mpath->timer.data = (unsigned long) new_mpath; - new_mpath->timer.function = mesh_path_timer; - new_mpath->exp_time = jiffies; - spin_lock_init(_mpath->state_lock); - init_timer(_mpath->timer); - hlist_add_head_rcu(_node->list, bucket); if (atomic_inc_return(>entries) >= MEAN_CHAIN_LEN * (tbl->hash_mask + 1)) @@ -664,7 +677,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata, return -ENOTSUPP; err = -ENOMEM; - new_mpath = kzalloc(sizeof(struct mesh_path), GFP_ATOMIC); + new_mpath = mesh_path_new(sdata, dst, GFP_ATOMIC); if (!new_mpath) goto err_path_alloc; @@ -672,17 +685,9 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata, if (!new_node) goto err_node_alloc; - read_lock_bh(>u.mesh.pathtbl_resize_lock); - memcpy(new_mpath->dst, dst, ETH_ALEN); memcpy(new_mpath->mpp, mpp, ETH_ALEN); - new_mpath->sdata = sdata; - new_mpath->flags = 0; - skb_queue_head_init(_mpath->frame_queue); new_node->mpath = new_mpath; - init_timer(_mpath->timer); - new_mpath->exp_time = jiffies; - spin_lock_init(_mpath->state_lock); - + read_lock_bh(>u.mesh.pathtbl_resize_lock); tbl = resize_dereference_mpp_paths(sdata); hash_idx = mesh_table_hash(dst, tbl); -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: obtain commit list
On Wed, Feb 17, 2016 at 11:40:26AM +0100, Arend Van Spriel wrote: > Hi Bob, > > With the old wireless testing I used to provide a list of commits that > were merged from wireless-testing into our internal repo. I am trying to > determine the strategy to produce that list with the new > wireless-testing using rebase stategy. Do you have a good suggestion for > that? Hi Arend, So I suppose it depends somewhat on how you are using the tree, whether you are merging w-t still or rebasing your own tree, but here's a couple of barely tested ideas. [Corrections welcome, I just tried a few things that looked "close enough", but I suppose some cases where the downstream trees rebase could muck up the result somewhat.] Suppose I want to see which commits have been added between two wireless-testing tags, I can do, for example: git log wt-2016-02-17 ^wt-2016-02-15 -- net drivers/net/wireless | \ git shortlog You'll see a handful of merge commits from me that don't end up in the upstream, but otherwise should see a reasonable set of commits that got merged, in this case a few iwlwifi patches. Now suppose you're rebasing your internal tree on top of w-t/master periodically, e.g., you have: wt-oldbase -- A -- B -- C -- D And rebase onto a new w-t tag to get (suppose A is merged upstream): wt-newbase -- B' -- C' -- D' wt-oldbase and wt-newbase actually have dated tags associated with them, but perhaps it is too much work to look them up and you just use "wireless-testing/master" in your rebase script. Then you could do the same thing but first get the base of the tree: wt_oldbase=$(git merge-base --fork-point wireless-testing/master D) wt_newbase=$(git merge-base --fork-point wireless-testing/master D') git log $wt_newbase ^$wt_oldbase Hope that helps, Bob -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 0/3] mac80211: add cleanup path for MPP table entries
On Wed, Feb 03, 2016 at 01:58:35PM +0100, Henning Rogge wrote: > Henning Rogge (3): > mac80211: Remove MPP table entries with MPath > mac80211: let unused MPP table entries timeout > mac80211: Unify mesh and mpp path removal function > > net/mac80211/mesh_pathtbl.c | 102 > +++- > net/mac80211/rx.c | 1 + > net/mac80211/tx.c | 5 ++- > 3 files changed, 97 insertions(+), 11 deletions(-) Thanks for the revisions. For what it's worth, series: Acked-by: Bob Copeland <m...@bobcopeland.com> -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] mac80211: mesh: drop constant field mean_chain_len
The mean_chain_len field in struct mesh_table is copied whenever a new mesh table is allocated, but only ever has the value 2 and is never otherwise updated, so just remove it and use the related define instead. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- v2: Upon rereading the commit log, noticed some lies. Reworded. v1: Sending this by itself as it's pretty trivial and doesn't conflict with other outstanding patches. net/mac80211/mesh.h | 3 --- net/mac80211/mesh_pathtbl.c | 9 +++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 4a8019f..87c017a 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -137,8 +137,6 @@ struct mesh_path { * @copy_node: function to copy nodes of the table * @size_order: determines size of the table, there will be 2^size_order hash * buckets - * @mean_chain_len: maximum average length for the hash buckets' list, if it is - * reached, the table will grow * @known_gates: list of known mesh gates and their mpaths by the station. The * gate's mpath may or may not be resolved and active. * @@ -154,7 +152,6 @@ struct mesh_table { void (*free_node) (struct hlist_node *p, bool free_leafs); int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); int size_order; - int mean_chain_len; struct hlist_head *known_gates; spinlock_t gates_lock; diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index dadf8dc..c95bdb8 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -160,11 +160,10 @@ static int mesh_table_grow(struct mesh_table *oldtbl, int i; if (atomic_read(>entries) - < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1)) + < MEAN_CHAIN_LEN * (oldtbl->hash_mask + 1)) return -EAGAIN; newtbl->free_node = oldtbl->free_node; - newtbl->mean_chain_len = oldtbl->mean_chain_len; newtbl->copy_node = oldtbl->copy_node; newtbl->known_gates = oldtbl->known_gates; atomic_set(>entries, atomic_read(>entries)); @@ -585,7 +584,7 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata, hlist_add_head_rcu(_node->list, bucket); if (atomic_inc_return(>entries) >= - tbl->mean_chain_len * (tbl->hash_mask + 1)) + MEAN_CHAIN_LEN * (tbl->hash_mask + 1)) grow = 1; mesh_paths_generation++; @@ -714,7 +713,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata, hlist_add_head_rcu(_node->list, bucket); if (atomic_inc_return(>entries) >= - tbl->mean_chain_len * (tbl->hash_mask + 1)) + MEAN_CHAIN_LEN * (tbl->hash_mask + 1)) grow = 1; spin_unlock(>hashwlock[hash_idx]); @@ -1076,7 +1075,6 @@ int mesh_pathtbl_init(void) return -ENOMEM; tbl_path->free_node = _path_node_free; tbl_path->copy_node = _path_node_copy; - tbl_path->mean_chain_len = MEAN_CHAIN_LEN; tbl_path->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC); if (!tbl_path->known_gates) { ret = -ENOMEM; @@ -1092,7 +1090,6 @@ int mesh_pathtbl_init(void) } tbl_mpp->free_node = _path_node_free; tbl_mpp->copy_node = _path_node_copy; - tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN; tbl_mpp->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC); if (!tbl_mpp->known_gates) { ret = -ENOMEM; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mac80211: mesh: drop write-only var mean_chain_len
On Thu, Jan 28, 2016 at 09:24:12AM -0500, Bob Copeland wrote: > mean_chain_len is copied into mesh path table > structures, but only ever has the value 2 and > is never read, so just remove it. Disregard, I sent a v2 (under a different subject) where the commit log actually makes sense. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] mac80211: Unify mesh and mpp path removal function
On Fri, Jan 29, 2016 at 11:08:58AM +0100, Henning Rogge wrote: > @@ -951,37 +974,14 @@ enddel: > */ > static int mpp_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) > { > - struct mesh_table *tbl; > - struct mesh_path *mpath; > - struct mpath_node *node; > - struct hlist_head *bucket; > - int hash_idx; > - int err = 0; > - > - /* flush relevant mpp entries first */ > - mpp_flush_by_proxy(sdata, addr); > - Is it intentional that mpp_path_del no longer calls mpp_flush_by_proxy() while mesh_path_del does? -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/2] mac80211: add cleanup path for MPP table entries
On Tue, Jan 19, 2016 at 09:04:30AM +0100, Henning Rogge wrote: > Currently MPP table entries are only removed from memory when their > 802.11s mesh interface goes down. This can make the kernel to remember > a growing list of proxied mac addresses which are not relevant or even > reachable anymore. Just so I know what to do with my series: do you plan to resend these with comments addressed? Or I could adopt the patches if you want. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mac80211: mesh: drop write-only var mean_chain_len
mean_chain_len is copied into mesh path table structures, but only ever has the value 2 and is never read, so just remove it. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- Sending this by itself as it's pretty trivial and doesn't conflict with other outstanding patches. net/mac80211/mesh.h | 3 --- net/mac80211/mesh_pathtbl.c | 9 +++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 4a8019f..87c017a 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -137,8 +137,6 @@ struct mesh_path { * @copy_node: function to copy nodes of the table * @size_order: determines size of the table, there will be 2^size_order hash * buckets - * @mean_chain_len: maximum average length for the hash buckets' list, if it is - * reached, the table will grow * @known_gates: list of known mesh gates and their mpaths by the station. The * gate's mpath may or may not be resolved and active. * @@ -154,7 +152,6 @@ struct mesh_table { void (*free_node) (struct hlist_node *p, bool free_leafs); int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); int size_order; - int mean_chain_len; struct hlist_head *known_gates; spinlock_t gates_lock; diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index dadf8dc..c95bdb8 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -160,11 +160,10 @@ static int mesh_table_grow(struct mesh_table *oldtbl, int i; if (atomic_read(>entries) - < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1)) + < MEAN_CHAIN_LEN * (oldtbl->hash_mask + 1)) return -EAGAIN; newtbl->free_node = oldtbl->free_node; - newtbl->mean_chain_len = oldtbl->mean_chain_len; newtbl->copy_node = oldtbl->copy_node; newtbl->known_gates = oldtbl->known_gates; atomic_set(>entries, atomic_read(>entries)); @@ -585,7 +584,7 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata, hlist_add_head_rcu(_node->list, bucket); if (atomic_inc_return(>entries) >= - tbl->mean_chain_len * (tbl->hash_mask + 1)) + MEAN_CHAIN_LEN * (tbl->hash_mask + 1)) grow = 1; mesh_paths_generation++; @@ -714,7 +713,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata, hlist_add_head_rcu(_node->list, bucket); if (atomic_inc_return(>entries) >= - tbl->mean_chain_len * (tbl->hash_mask + 1)) + MEAN_CHAIN_LEN * (tbl->hash_mask + 1)) grow = 1; spin_unlock(>hashwlock[hash_idx]); @@ -1076,7 +1075,6 @@ int mesh_pathtbl_init(void) return -ENOMEM; tbl_path->free_node = _path_node_free; tbl_path->copy_node = _path_node_copy; - tbl_path->mean_chain_len = MEAN_CHAIN_LEN; tbl_path->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC); if (!tbl_path->known_gates) { ret = -ENOMEM; @@ -1092,7 +1090,6 @@ int mesh_pathtbl_init(void) } tbl_mpp->free_node = _path_node_free; tbl_mpp->copy_node = _path_node_copy; - tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN; tbl_mpp->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC); if (!tbl_mpp->known_gates) { ret = -ENOMEM; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/2] mac80211: add cleanup path for MPP table entries
On Thu, Jan 28, 2016 at 04:07:52PM +0100, Henning Rogge wrote: > > Just so I know what to do with my series: do you plan to resend these > > with comments addressed? Or I could adopt the patches if you want. > > What would be easier for you? > > I can easily resend a "v2" tomorrow, depends on how much work it would > be for you to integrate them (or adapt them) to your patch set. It's roughly the same amount of work, so whatever works for you is fine by me. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/4] ath10k: rename mesh and add abstraction layer
On Wed, Jan 27, 2016 at 10:55:53AM -0800, Peter Oh wrote: > Split Mesh service to 11s Mesh and non-11s Mesh according to > firmware service bit to help users distinguish 11s Mesh from > non 11s Mesh. > And add abstraction layer for vdev subtype to solve subtype mismatch > and to give flexible compatibility among different firmware revisions. Out of curiosity, which non-11s mesh, if you can share? -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] mac80211: Remove connected MPP table entries with MPath
On Tue, Jan 26, 2016 at 12:41:25PM +0100, Johannes Berg wrote: > > + mpp = node->mpath; > > + if (ether_addr_equal(mpp->mpp, proxy)) { > > + spin_lock(>hashwlock[i]); > > + __mesh_path_del(tbl, node); > > + spin_unlock(>hashwlock[i]); > > It also doesn't seem like for_each_mesh_entry() can deal with "node" > getting deleted from underneath it? It accesses it through > hlist_next_rcu() after the deletion, so you have a use-after-free here > afaict. But __mesh_path_del() doesn't free it immediately: it does: hlist_del_rcu(>list); call_rcu(>rcu, mesh_path_node_reclaim); ...so this should be ok if in an rcu read-side critical section, right? -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] mac80211: Remove connected MPP table entries with MPath
On Tue, Jan 26, 2016 at 09:53:33PM +0100, Johannes Berg wrote: > Oh. Interesting. Yeah, I guess that should be OK then. > > It's not *nice*, since that's pretty much unexpected, and you then do > need the rcu_read_lock() ... hmm. Yeah, I puzzled over that a bit last week as well -- I rewrote it like this in the series I haven't posted yet: void mesh_path_flush_by_nexthop(struct sta_info *sta) { [...] rhashtable_walk_start(); while ((mpath = rhashtable_walk_next())) { if (IS_ERR(mpath) && PTR_ERR(mpath) == -EAGAIN) continue; if (IS_ERR(mpath)) break; if (rcu_access_pointer(mpath->next_hop) == sta) __mesh_path_del(tbl, mpath); } rhashtable_walk_stop(); [...] } ...this still relies on the rcu read lock inside _walk_start and _walk_stop, though. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] mac80211: Remove connected MPP table entries with MPath
On Tue, Jan 26, 2016 at 10:32:23PM +0100, Johannes Berg wrote: > On Tue, 2016-01-26 at 22:31 +0100, Johannes Berg wrote: > > On Tue, 2016-01-26 at 16:22 -0500, Bob Copeland wrote: > > > > > > void mesh_path_flush_by_nexthop(struct sta_info *sta) > > > { > > > [...] > > > rhashtable_walk_start(); > > > > It seems you need to check the return value here? > > > > Actually, maybe not. Not sure I understand the return to beginning > though. I'll RFC that patch, it doesn't work right now anyway as rhashtable_walk_init() does a GFP_KERNEL allocation and we want to call it from the RX path (maybe not a good idea, but that's what the code currently does). -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] mac80211: let unused MPP table entries timeout
On Tue, Jan 19, 2016 at 09:04:32AM +0100, Henning Rogge wrote: > err = -ENXIO; > -enddel: > +enddelpath: Concur about it being better to leave this label alone, also the diff looks weird because it continues: > + mesh_paths_generation++; > + spin_unlock(>hashwlock[hash_idx]); > + read_unlock_bh(_resize_lock); > + return err; > +} [...] > + err = -ENXIO; > +enddelmpp: > mesh_paths_generation++; > spin_unlock(>hashwlock[hash_idx]); > read_unlock_bh(_resize_lock); At first I wondered why the last half of the function was changed, but then I saw that. Shouldn't the above be "mpp_paths_generation++;"? In general I'd like to merge these two into one function; the only thing different is the initial table pointer that gets dereferenced and the generation counter (and now the labels). So something like this should be doable: static int mesh_table_delete(struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl, const u8 *addr) { /* basically what mesh_path_del is today */ } int mesh_path_del(...) { tbl = resize_dereference_mesh_paths(); ret = mesh_table_delete(sdata, tbl, addr); mesh_paths_generation++; return ret; } int mpp_path_del(...) { tbl = resize_dereference_mpp_paths(); ret = mesh_table_delete(sdata, tbl, addr); mpp_paths_generation++; return ret; } -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] mac80211: let unused MPP table entries timeout
On Sat, Jan 23, 2016 at 10:39:04AM +0100, Henning Rogge wrote: > > FYI I have a patch set I'm testing which rewrites a big chunk of > > the path table stuff. > > Does it include some cleanup paths for the MPP table? At the moment > the "missing cleanup" still allows remote users to make the Linux > kernel to allocate as much memory as it wants... with no way to free > it except for shutting down the interface. No, it needs these patches too. I did harmonize them a little bit, so that e.g. the expiry check will be done during lookup, but I didn't add an equivalent to flush-by-proxy. One issue it does address is that the path table can eventually shrink by virtue of the rhashtable, whereas now the bucket size is ever-growing. > > Let me know if you want me to base on top. > > I would like them to go in first... my experience of the kernel code > (outside some parts of the wifi stack) is not that good, so I don't > know how long I would need to adapt the patches to your new data > structures. Ok, sounds good, I'll just rebase on top of yours. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] mac80211: let unused MPP table entries timeout
On Tue, Jan 19, 2016 at 09:04:32AM +0100, Henning Rogge wrote: > Remember the last time when a mpp table entry is used for > rx or tx and remove them after MESH_PATH_EXPIRE time. FYI I have a patch set I'm testing which rewrites a big chunk of the path table stuff. As I haven't posted it yet, I guess it doesn't matter if this goes in first or not, I can adjust -- but it will conflict as-is. I was hoping to post it early next week after a few fixes. Let me know if you want me to base on top. Shortlog looks like: Bob Copeland (6): mac80211: mesh: move path tables into ieee82011_if_mesh mac80211: mesh: don't hash subif data in mesh path tables mac80211: mesh: factor out common mesh path allocation code mac80211: mesh: embed known gates list in struct mesh_path mac80211: mesh: convert path table to rhashtable mac80211: mesh: get rid of write-only field mean_chain_len -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Revert "mac80211_hwsim: support any address in userspace"
This reverts commit cd37a90b2a417e5882414e19954eeed174aa4d29. Different userspace programs interpreted HWSIM_ATTR_ADDR_TRANSMITTER and HWSIM_ATTR_ADDR_RECEIVER differently: some expected it to be an unchanging hardware address that is tied to the radio despite which address is configured on the interface, while others expected to be a copy of the address in the frame (the configured address). The intent of the original authors is unclear. The latter interpretation doesn't really work properly with multiple vifs and broadcast frames. Also, as the TA is already in the frame, userspace programs can actually support configured addresses in the former interpretation by mapping between them and the supplied HWSIM_ATTR_ADDR_TRANSMITTER. So, in the interest of API stability, revert to the previous mode of operation and going forward use the former interpretation. Signed-off-by: Bob Copeland <m...@bobcopeland.com> --- I made minimal changes to wmediumd and it works fine so far with the revert. I've a little more to do there, but it is good enough that hostapd test case passes with the new wmediumd binary, with or without this patch. drivers/net/wireless/mac80211_hwsim.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index c32889a1e39c..a28414c50edf 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -991,7 +991,8 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, goto nla_put_failure; } - if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, ETH_ALEN, hdr->addr2)) + if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, + ETH_ALEN, data->addresses[1].addr)) goto nla_put_failure; /* We get the skb->data */ @@ -2736,7 +2737,7 @@ static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(const u8 *addr) spin_lock_bh(_radio_lock); list_for_each_entry(data, _radios, list) { - if (mac80211_hwsim_addr_match(data, addr)) { + if (memcmp(data->addresses[1].addr, addr, ETH_ALEN) == 0) { _found = true; break; } -- 2.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: question on "mac80211_hwsim: support any address in userspace"
On Wed, Dec 16, 2015 at 02:14:18PM -0800, Ben Greear wrote: > On 12/16/2015 09:30 AM, Adam R. Welle wrote: > > > >>Well, it was always rather awkward since it was the *second* address :) > > > >Could somebody provide background information on why the decision was > >made to use a second address for the netlink frames instead of the same > >address as was used for the non-netlink frames? > > I would be fine with always using the first address instead of the second, > in case that helps someone. It doesn't really, that would break old wmediumd. > We could also set the address at creation time easily enough. Then it > could still be unique across many machines if you managed it. We already have a way to change mac addresses; adding a new API to change the default address seems pointless to me. -- Bob Copeland %% http://bobcopeland.com/ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html