From efad8396e906d095521791e0408293c101543e50 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 8 May 2017 21:36:37 -0700 Subject: wcn36xx: Close SMD channel on device removal The SMD channel is not the primary WCNSS channel and must explicitly be closed as the device is removed, or the channel will already by open on a subsequent probe call in e.g. the case of reloading the kernel module. This issue was introduced because I simplified the underlying SMD implementation while the SMD adaptions of the driver sat on the mailing list, but missed to update these patches. The patch does however only apply back to the transition to rpmsg, hence the limited Fixes. Fixes: 5052de8deff5 ("soc: qcom: smd: Transition client drivers from smd to rpmsg") Reported-by: Eyal Ilsar Signed-off-by: Bjorn Andersson Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wcn36xx/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index d5e993dc9b23..517a315e259b 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -1271,6 +1271,8 @@ static int wcn36xx_remove(struct platform_device *pdev) qcom_smem_state_put(wcn->tx_enable_state); qcom_smem_state_put(wcn->tx_rings_empty_state); + rpmsg_destroy_ept(wcn->smd_channel); + iounmap(wcn->dxe_base); iounmap(wcn->ccu_base); -- cgit v1.2.3 From f3c0eb05e258c6a48c2d1ef2fa71ffb6ff63cd18 Mon Sep 17 00:00:00 2001 From: Davide Caratti Date: Thu, 18 May 2017 18:01:43 +0200 Subject: netfilter: conntrack: fix false CRC32c mismatch using paged skb sctp_compute_cksum() implementation assumes that at least the SCTP header is in the linear part of skb: modify conntrack error callback to avoid false CRC32c mismatch, if the transport header is partially/entirely paged. Fixes: cf6e007eef83 ("netfilter: conntrack: validate SCTP crc32c in PREROUTING") Signed-off-by: Davide Caratti Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_sctp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 13875d599a85..1c5b14a6cab3 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -512,16 +512,19 @@ static int sctp_error(struct net *net, struct nf_conn *tpl, struct sk_buff *skb, u8 pf, unsigned int hooknum) { const struct sctphdr *sh; - struct sctphdr _sctph; const char *logmsg; - sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph); - if (!sh) { + if (skb->len < dataoff + sizeof(struct sctphdr)) { logmsg = "nf_ct_sctp: short packet "; goto out_invalid; } if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && skb->ip_summed == CHECKSUM_NONE) { + if (!skb_make_writable(skb, dataoff + sizeof(struct sctphdr))) { + logmsg = "nf_ct_sctp: failed to read header "; + goto out_invalid; + } + sh = (const struct sctphdr *)(skb->data + dataoff); if (sh->checksum != sctp_compute_cksum(skb, dataoff)) { logmsg = "nf_ct_sctp: bad CRC "; goto out_invalid; -- cgit v1.2.3 From d2df92e98a34a5619dadd29c6291113c009181e7 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 21 May 2017 00:37:10 +0200 Subject: netfilter: nft_set_rbtree: handle element re-addition after deletion The existing code selects no next branch to be inspected when re-inserting an inactive element into the rb-tree, looping endlessly. This patch restricts the check for active elements to the EEXIST case only. Fixes: e701001e7cbe ("netfilter: nft_rbtree: allow adjacent intervals with dynamic updates") Reported-by: Wolfgang Bumiller Tested-by: Wolfgang Bumiller Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nft_set_rbtree.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c index e97e2fb53f0a..fbdbaa00dd5f 100644 --- a/net/netfilter/nft_set_rbtree.c +++ b/net/netfilter/nft_set_rbtree.c @@ -116,17 +116,17 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, else if (d > 0) p = &parent->rb_right; else { - if (nft_set_elem_active(&rbe->ext, genmask)) { - if (nft_rbtree_interval_end(rbe) && - !nft_rbtree_interval_end(new)) - p = &parent->rb_left; - else if (!nft_rbtree_interval_end(rbe) && - nft_rbtree_interval_end(new)) - p = &parent->rb_right; - else { - *ext = &rbe->ext; - return -EEXIST; - } + if (nft_rbtree_interval_end(rbe) && + !nft_rbtree_interval_end(new)) { + p = &parent->rb_left; + } else if (!nft_rbtree_interval_end(rbe) && + nft_rbtree_interval_end(new)) { + p = &parent->rb_right; + } else if (nft_set_elem_active(&rbe->ext, genmask)) { + *ext = &rbe->ext; + return -EEXIST; + } else { + p = &parent->rb_left; } } } -- cgit v1.2.3 From 124dffea9e8e372509e055aebd118e85518fd644 Mon Sep 17 00:00:00 2001 From: Liping Zhang Date: Sun, 21 May 2017 22:38:11 +0800 Subject: netfilter: nat: use atomic bit op to clear the _SRC_NAT_DONE_BIT We need to clear the IPS_SRC_NAT_DONE_BIT to indicate that the ct has been removed from nat_bysource table. But unfortunately, we use the non-atomic bit operation: "ct->status &= ~IPS_NAT_DONE_MASK". So there's a race condition that we may clear the _DYING_BIT set by another CPU unexpectedly. Since we don't care about the IPS_DST_NAT_DONE_BIT, so just using clear_bit to clear the IPS_SRC_NAT_DONE_BIT is enough. Also note, this is the last user which use the non-atomic bit operation to update the confirmed ct->status. Reported-by: Florian Westphal Signed-off-by: Liping Zhang Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_nat_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index ef0be325a0c6..6c72922d20ca 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c @@ -566,7 +566,7 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data) * Else, when the conntrack is destoyed, nf_nat_cleanup_conntrack() * will delete entry from already-freed table. */ - ct->status &= ~IPS_NAT_DONE_MASK; + clear_bit(IPS_SRC_NAT_DONE_BIT, &ct->status); rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource, nf_nat_bysource_params); -- cgit v1.2.3 From fefa92679dbe0c613e62b6c27235dcfbe9640ad1 Mon Sep 17 00:00:00 2001 From: Liping Zhang Date: Sun, 21 May 2017 07:22:49 +0800 Subject: netfilter: ctnetlink: fix incorrect nf_ct_put during hash resize If nf_conntrack_htable_size was adjusted by the user during the ct dump operation, we may invoke nf_ct_put twice for the same ct, i.e. the "last" ct. This will cause the ct will be freed but still linked in hash buckets. It's very easy to reproduce the problem by the following commands: # while : ; do echo $RANDOM > /proc/sys/net/netfilter/nf_conntrack_buckets done # while : ; do conntrack -L done # iperf -s 127.0.0.1 & # iperf -c 127.0.0.1 -P 60 -t 36000 After a while, the system will hang like this: NMI watchdog: BUG: soft lockup - CPU#1 stuck for 22s! [bash:20184] NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [iperf:20382] ... So at last if we find cb->args[1] is equal to "last", this means hash resize happened, then we can set cb->args[1] to 0 to fix the above issue. Fixes: d205dc40798d ("[NETFILTER]: ctnetlink: fix deadlock in table dumping") Signed-off-by: Liping Zhang Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_netlink.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 9799a50bc604..a8be9b72e6cd 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -890,8 +890,13 @@ restart: } out: local_bh_enable(); - if (last) + if (last) { + /* nf ct hash resize happened, now clear the leftover. */ + if ((struct nf_conn *)cb->args[1] == last) + cb->args[1] = 0; + nf_ct_put(last); + } while (i) { i--; -- cgit v1.2.3 From 6c713a3a23154f4f0c2217ea39811ebe443dafaa Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Fri, 26 May 2017 01:44:43 +0200 Subject: net: dsa: mv88e6xxx: Add eeprom-length to binding The binding documentation for the mv88e6xxx switch is missing the eeprom-length property, which has been implemented since May 2016, commit f8cd8753def0 ("dsa: mv88e6xxx: Handle eeprom-length property") Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/dsa/marvell.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/net/dsa/marvell.txt b/Documentation/devicetree/bindings/net/dsa/marvell.txt index 7ef9dbb08957..1d4d0f49c9d0 100644 --- a/Documentation/devicetree/bindings/net/dsa/marvell.txt +++ b/Documentation/devicetree/bindings/net/dsa/marvell.txt @@ -26,6 +26,10 @@ Optional properties: - interrupt-controller : Indicates the switch is itself an interrupt controller. This is used for the PHY interrupts. #interrupt-cells = <2> : Controller uses two cells, number and flag +- eeprom-length : Set to the length of an EEPROM connected to the + switch. Must be set if the switch can not detect + the presence and/or size of a connected EEPROM, + otherwise optional. - mdio : Container of PHY and devices on the switches MDIO bus. - mdio? : Container of PHYs and devices on the external MDIO -- cgit v1.2.3 From fb3ce90b7d7761b6f7f28f0ff5c456ef6b5229a1 Mon Sep 17 00:00:00 2001 From: Firo Yang Date: Fri, 26 May 2017 22:37:38 +0800 Subject: hdlcdrv: Fix divide by zero in hdlcdrv_ioctl syszkaller fuzzer triggered a divide by zero, when set calibration through ioctl(). To fix it, test 'bitrate' if it is negative or 0, just return -EINVAL. Reported-by: Andrey Konovalov Signed-off-by: Firo Yang Signed-off-by: David S. Miller --- drivers/net/hamradio/hdlcdrv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index 8c3633c1d078..97e3bc60c3e7 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c @@ -576,6 +576,8 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case HDLCDRVCTL_CALIBRATE: if(!capable(CAP_SYS_RAWIO)) return -EPERM; + if (s->par.bitrate <= 0) + return -EINVAL; if (bi.data.calibrate > INT_MAX / s->par.bitrate) return -EINVAL; s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16; -- cgit v1.2.3 From c21fbe29f8588991b4fbf209ad4f6ecd4b550cdb Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 28 May 2017 17:25:14 +0200 Subject: net: dsa: mv88e6xxx: Add missing static to stub functions Stub functions in header files need to be static, or we can have multiple definitions errors. Reported-by: kbuild test robot Fixes: 6335e9f2446b ("net: dsa: mv88e6xxx: mv88e6390X SERDES support") Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/global2.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h index 96046bb12ca1..d8d3c5abb2a1 100644 --- a/drivers/net/dsa/mv88e6xxx/global2.h +++ b/drivers/net/dsa/mv88e6xxx/global2.h @@ -114,13 +114,13 @@ static inline int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip, return -EOPNOTSUPP; } -int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev, - int src_port, u16 data) +static int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev, + int src_port, u16 data) { return -EOPNOTSUPP; } -int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip) +static int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip) { return -EOPNOTSUPP; } -- cgit v1.2.3 From 7a7c0a6438b8e7636d5a22e572892cc234f68297 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 27 May 2017 00:27:25 +0200 Subject: mac80211: fix TX aggregation start/stop callback race When starting or stopping an aggregation session, one of the steps is that the driver calls back to mac80211 that the start/stop can proceed. This is handled by queueing up a fake SKB and processing it from the normal iface/sdata work. Since this isn't flushed when disassociating, the following race is possible: * associate * start aggregation session * driver callback * disassociate * associate again to the same AP * callback processing runs, leading to a WARN_ON() that the TID hadn't requested aggregation If the second association isn't to the same AP, there would only be a message printed ("Could not find station: "), but the same race could happen. Fix this by not going the whole detour with a fake SKB etc. but simply looking up the aggregation session in the driver callback, marking it with a START_CB/STOP_CB bit and then scheduling the regular aggregation work that will now process these bits as well. This also simplifies the code and gets rid of the whole problem with allocation failures of said skb, which could have left the session in limbo. Reported-by: Jouni Malinen Signed-off-by: Johannes Berg --- net/mac80211/agg-tx.c | 128 ++++++++++++++++++--------------------------- net/mac80211/ht.c | 16 ++++-- net/mac80211/ieee80211_i.h | 14 ++--- net/mac80211/iface.c | 11 +--- net/mac80211/sta_info.h | 2 + 5 files changed, 71 insertions(+), 100 deletions(-) diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 60e2a62f7bef..cf2392b2ac71 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -7,7 +7,7 @@ * Copyright 2006-2007 Jiri Benc * Copyright 2007, Michael Wu * Copyright 2007-2010, Intel Corporation - * Copyright(c) 2015 Intel Deutschland GmbH + * Copyright(c) 2015-2017 Intel Deutschland GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -741,46 +741,43 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, ieee80211_agg_start_txq(sta, tid, true); } -void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) +void ieee80211_start_tx_ba_cb(struct sta_info *sta, int tid, + struct tid_ampdu_tx *tid_tx) { - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); + struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_local *local = sdata->local; - struct sta_info *sta; - struct tid_ampdu_tx *tid_tx; - trace_api_start_tx_ba_cb(sdata, ra, tid); + if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))) + return; + + if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) + ieee80211_agg_tx_operational(local, sta, tid); +} + +static struct tid_ampdu_tx * +ieee80211_lookup_tid_tx(struct ieee80211_sub_if_data *sdata, + const u8 *ra, u16 tid, struct sta_info **sta) +{ + struct tid_ampdu_tx *tid_tx; if (tid >= IEEE80211_NUM_TIDS) { ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", tid, IEEE80211_NUM_TIDS); - return; + return NULL; } - mutex_lock(&local->sta_mtx); - sta = sta_info_get_bss(sdata, ra); - if (!sta) { - mutex_unlock(&local->sta_mtx); + *sta = sta_info_get_bss(sdata, ra); + if (!*sta) { ht_dbg(sdata, "Could not find station: %pM\n", ra); - return; + return NULL; } - mutex_lock(&sta->ampdu_mlme.mtx); - tid_tx = rcu_dereference_protected_tid_tx(sta, tid); + tid_tx = rcu_dereference((*sta)->ampdu_mlme.tid_tx[tid]); - if (WARN_ON(!tid_tx)) { + if (WARN_ON(!tid_tx)) ht_dbg(sdata, "addBA was not requested!\n"); - goto unlock; - } - if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))) - goto unlock; - - if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) - ieee80211_agg_tx_operational(local, sta, tid); - - unlock: - mutex_unlock(&sta->ampdu_mlme.mtx); - mutex_unlock(&local->sta_mtx); + return tid_tx; } void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, @@ -788,19 +785,20 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, { struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_local *local = sdata->local; - struct ieee80211_ra_tid *ra_tid; - struct sk_buff *skb = dev_alloc_skb(0); + struct sta_info *sta; + struct tid_ampdu_tx *tid_tx; - if (unlikely(!skb)) - return; + trace_api_start_tx_ba_cb(sdata, ra, tid); - ra_tid = (struct ieee80211_ra_tid *) &skb->cb; - memcpy(&ra_tid->ra, ra, ETH_ALEN); - ra_tid->tid = tid; + rcu_read_lock(); + tid_tx = ieee80211_lookup_tid_tx(sdata, ra, tid, &sta); + if (!tid_tx) + goto out; - skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_START; - skb_queue_tail(&sdata->skb_queue, skb); - ieee80211_queue_work(&local->hw, &sdata->work); + set_bit(HT_AGG_STATE_START_CB, &tid_tx->state); + ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work); + out: + rcu_read_unlock(); } EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); @@ -860,37 +858,18 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) } EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); -void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) +void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid, + struct tid_ampdu_tx *tid_tx) { - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); - struct ieee80211_local *local = sdata->local; - struct sta_info *sta; - struct tid_ampdu_tx *tid_tx; + struct ieee80211_sub_if_data *sdata = sta->sdata; bool send_delba = false; - trace_api_stop_tx_ba_cb(sdata, ra, tid); - - if (tid >= IEEE80211_NUM_TIDS) { - ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", - tid, IEEE80211_NUM_TIDS); - return; - } - - ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n", ra, tid); - - mutex_lock(&local->sta_mtx); - - sta = sta_info_get_bss(sdata, ra); - if (!sta) { - ht_dbg(sdata, "Could not find station: %pM\n", ra); - goto unlock; - } + ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n", + sta->sta.addr, tid); - mutex_lock(&sta->ampdu_mlme.mtx); spin_lock_bh(&sta->lock); - tid_tx = rcu_dereference_protected_tid_tx(sta, tid); - if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { + if (!test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { ht_dbg(sdata, "unexpected callback to A-MPDU stop for %pM tid %d\n", sta->sta.addr, tid); @@ -906,12 +885,8 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) spin_unlock_bh(&sta->lock); if (send_delba) - ieee80211_send_delba(sdata, ra, tid, + ieee80211_send_delba(sdata, sta->sta.addr, tid, WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); - - mutex_unlock(&sta->ampdu_mlme.mtx); - unlock: - mutex_unlock(&local->sta_mtx); } void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, @@ -919,19 +894,20 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, { struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_local *local = sdata->local; - struct ieee80211_ra_tid *ra_tid; - struct sk_buff *skb = dev_alloc_skb(0); + struct sta_info *sta; + struct tid_ampdu_tx *tid_tx; - if (unlikely(!skb)) - return; + trace_api_stop_tx_ba_cb(sdata, ra, tid); - ra_tid = (struct ieee80211_ra_tid *) &skb->cb; - memcpy(&ra_tid->ra, ra, ETH_ALEN); - ra_tid->tid = tid; + rcu_read_lock(); + tid_tx = ieee80211_lookup_tid_tx(sdata, ra, tid, &sta); + if (!tid_tx) + goto out; - skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_STOP; - skb_queue_tail(&sdata->skb_queue, skb); - ieee80211_queue_work(&local->hw, &sdata->work); + set_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state); + ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work); + out: + rcu_read_unlock(); } EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe); diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index f4a528773563..6ca5442b1e03 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -7,6 +7,7 @@ * Copyright 2006-2007 Jiri Benc * Copyright 2007, Michael Wu * Copyright 2007-2010, Intel Corporation + * Copyright 2017 Intel Deutschland GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -289,8 +290,6 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, { int i; - cancel_work_sync(&sta->ampdu_mlme.work); - for (i = 0; i < IEEE80211_NUM_TIDS; i++) { __ieee80211_stop_tx_ba_session(sta, i, reason); __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, @@ -298,6 +297,9 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, reason != AGG_STOP_DESTROY_STA && reason != AGG_STOP_PEER_REQUEST); } + + /* stopping might queue the work again - so cancel only afterwards */ + cancel_work_sync(&sta->ampdu_mlme.work); } void ieee80211_ba_session_work(struct work_struct *work) @@ -352,10 +354,16 @@ void ieee80211_ba_session_work(struct work_struct *work) spin_unlock_bh(&sta->lock); tid_tx = rcu_dereference_protected_tid_tx(sta, tid); - if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP, - &tid_tx->state)) + if (!tid_tx) + continue; + + if (test_and_clear_bit(HT_AGG_STATE_START_CB, &tid_tx->state)) + ieee80211_start_tx_ba_cb(sta, tid, tid_tx); + if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state)) ___ieee80211_stop_tx_ba_session(sta, tid, AGG_STOP_LOCAL_REQUEST); + if (test_and_clear_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state)) + ieee80211_stop_tx_ba_cb(sta, tid, tid_tx); } mutex_unlock(&sta->ampdu_mlme.mtx); } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f8f6c148f554..665501ac358f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1036,8 +1036,6 @@ struct ieee80211_rx_agg { enum sdata_queue_type { IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, - IEEE80211_SDATA_QUEUE_AGG_START = 1, - IEEE80211_SDATA_QUEUE_AGG_STOP = 2, IEEE80211_SDATA_QUEUE_RX_AGG_START = 3, IEEE80211_SDATA_QUEUE_RX_AGG_STOP = 4, }; @@ -1427,12 +1425,6 @@ ieee80211_get_sband(struct ieee80211_sub_if_data *sdata) return local->hw.wiphy->bands[band]; } -/* this struct represents 802.11n's RA/TID combination */ -struct ieee80211_ra_tid { - u8 ra[ETH_ALEN]; - u16 tid; -}; - /* this struct holds the value parsing from channel switch IE */ struct ieee80211_csa_ie { struct cfg80211_chan_def chandef; @@ -1794,8 +1786,10 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, enum ieee80211_agg_stop_reason reason); int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, enum ieee80211_agg_stop_reason reason); -void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); -void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); +void ieee80211_start_tx_ba_cb(struct sta_info *sta, int tid, + struct tid_ampdu_tx *tid_tx); +void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid, + struct tid_ampdu_tx *tid_tx); void ieee80211_ba_session_work(struct work_struct *work); void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid); void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 3bd5b81f5d81..8fae1a72e6a7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1237,7 +1237,6 @@ static void ieee80211_iface_work(struct work_struct *work) struct ieee80211_local *local = sdata->local; struct sk_buff *skb; struct sta_info *sta; - struct ieee80211_ra_tid *ra_tid; struct ieee80211_rx_agg *rx_agg; if (!ieee80211_sdata_running(sdata)) @@ -1253,15 +1252,7 @@ static void ieee80211_iface_work(struct work_struct *work) while ((skb = skb_dequeue(&sdata->skb_queue))) { struct ieee80211_mgmt *mgmt = (void *)skb->data; - if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) { - ra_tid = (void *)&skb->cb; - ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra, - ra_tid->tid); - } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) { - ra_tid = (void *)&skb->cb; - ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra, - ra_tid->tid); - } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) { + if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) { rx_agg = (void *)&skb->cb; mutex_lock(&local->sta_mtx); sta = sta_info_get_bss(sdata, rx_agg->addr); diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 5609cacb20d5..ea0747d6a6da 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -116,6 +116,8 @@ enum ieee80211_sta_info_flags { #define HT_AGG_STATE_STOPPING 3 #define HT_AGG_STATE_WANT_START 4 #define HT_AGG_STATE_WANT_STOP 5 +#define HT_AGG_STATE_START_CB 6 +#define HT_AGG_STATE_STOP_CB 7 enum ieee80211_agg_stop_reason { AGG_STOP_DECLINED, -- cgit v1.2.3 From 025d0973a0ec2121c6fd0da59e8cc3829fbb221e Mon Sep 17 00:00:00 2001 From: "Guilherme G. Piccoli" Date: Sun, 28 May 2017 23:07:01 -0300 Subject: cxgb4: avoid crash on PCI error recovery path During PCI error recovery process, specifically on eeh_err_detected() we might have a NULL netdev struct, hence a direct dereference will lead to a kernel oops. This was observed with latest upstream kernel (v4.12-rc2) on Chelsio adapter T422-CR in PowerPC machines. This patch checks for NULL pointer and avoids the crash, both in eeh_err_detected() and eeh_resume(). Also, we avoid to trigger a fatal error or to try disabling interrupts on FW during PCI error recovery, because: (a) driver might not be able to accurately access PCI regions in this case, and (b) trigger a fatal error _during_ the recovery steps is a mistake that could prevent the recovery path to complete successfully. Reported-by: Harsha Thyagaraja Signed-off-by: Guilherme G. Piccoli Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 21 +++++++++++++-------- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 9 +++++++-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 38a5c6764bb5..b512149684fd 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -2771,6 +2771,9 @@ void t4_fatal_err(struct adapter *adap) { int port; + if (pci_channel_offline(adap->pdev)) + return; + /* Disable the SGE since ULDs are going to free resources that * could be exposed to the adapter. RDMA MWs for example... */ @@ -3882,9 +3885,10 @@ static pci_ers_result_t eeh_err_detected(struct pci_dev *pdev, spin_lock(&adap->stats_lock); for_each_port(adap, i) { struct net_device *dev = adap->port[i]; - - netif_device_detach(dev); - netif_carrier_off(dev); + if (dev) { + netif_device_detach(dev); + netif_carrier_off(dev); + } } spin_unlock(&adap->stats_lock); disable_interrupts(adap); @@ -3963,12 +3967,13 @@ static void eeh_resume(struct pci_dev *pdev) rtnl_lock(); for_each_port(adap, i) { struct net_device *dev = adap->port[i]; - - if (netif_running(dev)) { - link_start(dev); - cxgb_set_rxmode(dev); + if (dev) { + if (netif_running(dev)) { + link_start(dev); + cxgb_set_rxmode(dev); + } + netif_device_attach(dev); } - netif_device_attach(dev); } rtnl_unlock(); } diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index aded42b96f6d..3a34aa629f7d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -4557,8 +4557,13 @@ void t4_intr_enable(struct adapter *adapter) */ void t4_intr_disable(struct adapter *adapter) { - u32 whoami = t4_read_reg(adapter, PL_WHOAMI_A); - u32 pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ? + u32 whoami, pf; + + if (pci_channel_offline(adapter->pdev)) + return; + + whoami = t4_read_reg(adapter, PL_WHOAMI_A); + pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ? SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami); t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE_A), 0); -- cgit v1.2.3 From 5ee6842cd8aff517701549463927cb1e5eb50b01 Mon Sep 17 00:00:00 2001 From: Madalin Bucur Date: Mon, 29 May 2017 09:22:06 +0300 Subject: Documentation: networking: add DPAA Ethernet document Signed-off-by: Madalin Bucur Signed-off-by: Camelia Groza Signed-off-by: David S. Miller --- Documentation/networking/dpaa.txt | 194 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 Documentation/networking/dpaa.txt diff --git a/Documentation/networking/dpaa.txt b/Documentation/networking/dpaa.txt new file mode 100644 index 000000000000..76e016d4d344 --- /dev/null +++ b/Documentation/networking/dpaa.txt @@ -0,0 +1,194 @@ +The QorIQ DPAA Ethernet Driver +============================== + +Authors: +Madalin Bucur +Camelia Groza + +Contents +======== + + - DPAA Ethernet Overview + - DPAA Ethernet Supported SoCs + - Configuring DPAA Ethernet in your kernel + - DPAA Ethernet Frame Processing + - DPAA Ethernet Features + - Debugging + +DPAA Ethernet Overview +====================== + +DPAA stands for Data Path Acceleration Architecture and it is a +set of networking acceleration IPs that are available on several +generations of SoCs, both on PowerPC and ARM64. + +The Freescale DPAA architecture consists of a series of hardware blocks +that support Ethernet connectivity. The Ethernet driver depends upon the +following drivers in the Linux kernel: + + - Peripheral Access Memory Unit (PAMU) (* needed only for PPC platforms) + drivers/iommu/fsl_* + - Frame Manager (FMan) + drivers/net/ethernet/freescale/fman + - Queue Manager (QMan), Buffer Manager (BMan) + drivers/soc/fsl/qbman + +A simplified view of the dpaa_eth interfaces mapped to FMan MACs: + + dpaa_eth /eth0\ ... /ethN\ + driver | | | | + ------------- ---- ----------- ---- ------------- + -Ports / Tx Rx \ ... / Tx Rx \ + FMan | | | | + -MACs | MAC0 | | MACN | + / dtsec0 \ ... / dtsecN \ (or tgec) + / \ / \(or memac) + --------- -------------- --- -------------- --------- + FMan, FMan Port, FMan SP, FMan MURAM drivers + --------------------------------------------------------- + FMan HW blocks: MURAM, MACs, Ports, SP + --------------------------------------------------------- + +The dpaa_eth relation to the QMan, BMan and FMan: + ________________________________ + dpaa_eth / eth0 \ + driver / \ + --------- -^- -^- -^- --- --------- + QMan driver / \ / \ / \ \ / | BMan | + |Rx | |Rx | |Tx | |Tx | | driver | + --------- |Dfl| |Err| |Cnf| |FQs| | | + QMan HW |FQ | |FQ | |FQs| | | | | + / \ / \ / \ \ / | | + --------- --- --- --- -v- --------- + | FMan QMI | | + | FMan HW FMan BMI | BMan HW | + ----------------------- -------- + +where the acronyms used above (and in the code) are: +DPAA = Data Path Acceleration Architecture +FMan = DPAA Frame Manager +QMan = DPAA Queue Manager +BMan = DPAA Buffers Manager +QMI = QMan interface in FMan +BMI = BMan interface in FMan +FMan SP = FMan Storage Profiles +MURAM = Multi-user RAM in FMan +FQ = QMan Frame Queue +Rx Dfl FQ = default reception FQ +Rx Err FQ = Rx error frames FQ +Tx Cnf FQ = Tx confirmation FQs +Tx FQs = transmission frame queues +dtsec = datapath three speed Ethernet controller (10/100/1000 Mbps) +tgec = ten gigabit Ethernet controller (10 Gbps) +memac = multirate Ethernet MAC (10/100/1000/10000) + +DPAA Ethernet Supported SoCs +============================ + +The DPAA drivers enable the Ethernet controllers present on the following SoCs: + +# PPC +P1023 +P2041 +P3041 +P4080 +P5020 +P5040 +T1023 +T1024 +T1040 +T1042 +T2080 +T4240 +B4860 + +# ARM +LS1043A +LS1046A + +Configuring DPAA Ethernet in your kernel +======================================== + +To enable the DPAA Ethernet driver, the following Kconfig options are required: + +# common for arch/arm64 and arch/powerpc platforms +CONFIG_FSL_DPAA=y +CONFIG_FSL_FMAN=y +CONFIG_FSL_DPAA_ETH=y +CONFIG_FSL_XGMAC_MDIO=y + +# for arch/powerpc only +CONFIG_FSL_PAMU=y + +# common options needed for the PHYs used on the RDBs +CONFIG_VITESSE_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_AQUANTIA_PHY=y + +DPAA Ethernet Frame Processing +============================== + +On Rx, buffers for the incoming frames are retrieved from one of the three +existing buffers pools. The driver initializes and seeds these, each with +buffers of different sizes: 1KB, 2KB and 4KB. + +On Tx, all transmitted frames are returned to the driver through Tx +confirmation frame queues. The driver is then responsible for freeing the +buffers. In order to do this properly, a backpointer is added to the buffer +before transmission that points to the skb. When the buffer returns to the +driver on a confirmation FQ, the skb can be correctly consumed. + +DPAA Ethernet Features +====================== + +Currently the DPAA Ethernet driver enables the basic features required for +a Linux Ethernet driver. The support for advanced features will be added +gradually. + +The driver has Rx and Tx checksum offloading for UDP and TCP. Currently the Rx +checksum offload feature is enabled by default and cannot be controlled through +ethtool. + +The driver has support for multiple prioritized Tx traffic classes. Priorities +range from 0 (lowest) to 3 (highest). These are mapped to HW workqueues with +strict priority levels. Each traffic class contains NR_CPU TX queues. By +default, only one traffic class is enabled and the lowest priority Tx queues +are used. Higher priority traffic classes can be enabled with the mqprio +qdisc. For example, all four traffic classes are enabled on an interface with +the following command. Furthermore, skb priority levels are mapped to traffic +classes as follows: + + * priorities 0 to 3 - traffic class 0 (low priority) + * priorities 4 to 7 - traffic class 1 (medium-low priority) + * priorities 8 to 11 - traffic class 2 (medium-high priority) + * priorities 12 to 15 - traffic class 3 (high priority) + +tc qdisc add dev root handle 1: \ + mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 hw 1 + +Debugging +========= + +The following statistics are exported for each interface through ethtool: + + - interrupt count per CPU + - Rx packets count per CPU + - Tx packets count per CPU + - Tx confirmed packets count per CPU + - Tx S/G frames count per CPU + - Tx error count per CPU + - Rx error count per CPU + - Rx error count per type + - congestion related statistics: + - congestion status + - time spent in congestion + - number of time the device entered congestion + - dropped packets count per cause + +The driver also exports the following information in sysfs: + + - the FQ IDs for each FQ type + /sys/devices/platform/dpaa-ethernet.0/net//fqids + + - the IDs of the buffer pools in use + /sys/devices/platform/dpaa-ethernet.0/net//bpids -- cgit v1.2.3 From 512c7840cd692fdac0333684249753ebf3c819f9 Mon Sep 17 00:00:00 2001 From: "Mintz, Yuval" Date: Mon, 29 May 2017 11:24:49 +0300 Subject: qed: Don't log missing periodic stats by default Current implementation lacks the logic for providing management firmware with RDMA-related statistics; [much] worse than that - it logs such events by default to system logs. Since the statistics' gathering is done periodically, using sufficiently new management firmware the system logs would get filled with these unnecessary prints. For now, reduce the verbosity of the log so that it would not be logged by default. Fixes: 6c75424612a7 ("qed: Add support for NCSI statistics") Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 537d1236a4fe..715b3aaf83ac 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -1730,7 +1730,8 @@ void qed_get_protocol_stats(struct qed_dev *cdev, qed_get_protocol_stats_iscsi(cdev, &stats->iscsi_stats); break; default: - DP_ERR(cdev, "Invalid protocol type = %d\n", type); + DP_VERBOSE(cdev, QED_MSG_SP, + "Invalid protocol type = %d\n", type); return; } } -- cgit v1.2.3 From 59b2c3140f329e5817197f84860f3fa61a742fdf Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 29 May 2017 14:56:01 +0200 Subject: net: dsa: mv88e6xxx: Add missing static to stub functions 'static' was not enough, the helpers must be 'static inline' net/dsa/mv88e6xxx/global2.h:123:12: error: 'mv88e6xxx_g2_misc_4_bit_port' defined but not used [-Werror=unused-function] net/dsa/mv88e6xxx/global2.h:117:12: error: 'mv88e6xxx_g2_pvt_write' defined but not used [-Werror=unused-function] Fixes: c21fbe29f858 ("net: dsa: mv88e6xxx: Add missing static to stub functions") Signed-off-by: Arnd Bergmann Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/global2.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h index d8d3c5abb2a1..14c0be98e0a4 100644 --- a/drivers/net/dsa/mv88e6xxx/global2.h +++ b/drivers/net/dsa/mv88e6xxx/global2.h @@ -114,13 +114,13 @@ static inline int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip, return -EOPNOTSUPP; } -static int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev, - int src_port, u16 data) +static inline int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, + int src_dev, int src_port, u16 data) { return -EOPNOTSUPP; } -static int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip) +static inline int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip) { return -EOPNOTSUPP; } -- cgit v1.2.3 From f0d7ae95fff4ab444b8433f07afc4b077ef1a285 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 29 May 2017 15:00:17 +0200 Subject: net/mlx5: avoid build warning for uniprocessor Building the driver with CONFIG_SMP disabled results in a harmless warning: ethernet/mellanox/mlx5/core/main.c: In function 'mlx5_irq_set_affinity_hint': ethernet/mellanox/mlx5/core/main.c:615:6: error: unused variable 'irq' [-Werror=unused-variable] It's better to express the conditional compilation using IS_ENABLED() here, as that lets the compiler see what the intented use for the variable is, and that it can be silently discarded. Fixes: b665d98edc9a ("net/mlx5: Tolerate irq_set_affinity_hint() failures") Signed-off-by: Arnd Bergmann Acked-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index fe5546bb4153..af945edfee19 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -621,10 +621,9 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node), priv->irq_info[i].mask); -#ifdef CONFIG_SMP - if (irq_set_affinity_hint(irq, priv->irq_info[i].mask)) + if (IS_ENABLED(CONFIG_SMP) && + irq_set_affinity_hint(irq, priv->irq_info[i].mask)) mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq); -#endif return 0; } -- cgit v1.2.3 From 5a1d08726230ead4817e9c22f2736b9ff21bf6af Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Tue, 30 May 2017 11:44:04 +0300 Subject: MAINTAINERS: Update MELLANOX MLX4 core VPI driver maintainer Add myself as a maintainer for mlx4 core driver, replacing Yishai Hadas. Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 9e984645c4b0..d9d5398d0a49 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8508,7 +8508,7 @@ S: Odd Fixes F: drivers/media/radio/radio-miropcm20* MELLANOX MLX4 core VPI driver -M: Yishai Hadas +M: Tariq Toukan L: netdev@vger.kernel.org L: linux-rdma@vger.kernel.org W: http://www.mellanox.com -- cgit v1.2.3 From 39acf4e242621bd2b5d992a7ef2fd3358065d576 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Tue, 30 May 2017 11:44:05 +0300 Subject: MAINTAINERS: Move mlx4 rdma header file to IB driver charge It belongs there, should not be under mlx4 Core driver. Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index d9d5398d0a49..0dbc20c963c4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8516,7 +8516,6 @@ Q: http://patchwork.ozlabs.org/project/netdev/list/ S: Supported F: drivers/net/ethernet/mellanox/mlx4/ F: include/linux/mlx4/ -F: include/uapi/rdma/mlx4-abi.h MELLANOX MLX4 IB driver M: Yishai Hadas @@ -8526,6 +8525,7 @@ Q: http://patchwork.kernel.org/project/linux-rdma/list/ S: Supported F: drivers/infiniband/hw/mlx4/ F: include/linux/mlx4/ +F: include/uapi/rdma/mlx4-abi.h MELLANOX MLX5 core VPI driver M: Saeed Mahameed -- cgit v1.2.3 From 177567580aa1c3ec6e900b25280a52f02f93469f Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Tue, 30 May 2017 11:44:06 +0300 Subject: MAINTAINERS: Move mlx5 rdma header file to IB driver charge It belongs there, should not be under mlx5 Core driver. Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 0dbc20c963c4..0f92a2ff4b12 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8538,7 +8538,6 @@ Q: http://patchwork.ozlabs.org/project/netdev/list/ S: Supported F: drivers/net/ethernet/mellanox/mlx5/core/ F: include/linux/mlx5/ -F: include/uapi/rdma/mlx5-abi.h MELLANOX MLX5 IB driver M: Matan Barak @@ -8549,6 +8548,7 @@ Q: http://patchwork.kernel.org/project/linux-rdma/list/ S: Supported F: drivers/infiniband/hw/mlx5/ F: include/linux/mlx5/ +F: include/uapi/rdma/mlx5-abi.h MELEXIS MLX90614 DRIVER M: Crt Mori -- cgit v1.2.3 From 15e5651525c2e580a523568ed207e4a3fb11cc33 Mon Sep 17 00:00:00 2001 From: Douglas Caetano dos Santos Date: Fri, 26 May 2017 14:28:00 -0300 Subject: tcp: reinitialize MTU probing when setting MSS in a TCP repair MTU probing initialization occurred only at connect() and at SYN or SYN-ACK reception, but the former sets MSS to either the default or the user set value (through TCP_MAXSEG sockopt) and the latter never happens with repaired sockets. The result was that, with MTU probing enabled and unless TCP_MAXSEG sockopt was used before connect(), probing would be stuck at tcp_base_mss value until tcp_probe_interval seconds have passed. Signed-off-by: Douglas Caetano dos Santos Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 59792d283ff8..b5ea036ca781 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2381,9 +2381,10 @@ static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int l return 0; } -static int tcp_repair_options_est(struct tcp_sock *tp, +static int tcp_repair_options_est(struct sock *sk, struct tcp_repair_opt __user *optbuf, unsigned int len) { + struct tcp_sock *tp = tcp_sk(sk); struct tcp_repair_opt opt; while (len >= sizeof(opt)) { @@ -2396,6 +2397,7 @@ static int tcp_repair_options_est(struct tcp_sock *tp, switch (opt.opt_code) { case TCPOPT_MSS: tp->rx_opt.mss_clamp = opt.opt_val; + tcp_mtup_init(sk); break; case TCPOPT_WINDOW: { @@ -2555,7 +2557,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, if (!tp->repair) err = -EINVAL; else if (sk->sk_state == TCP_ESTABLISHED) - err = tcp_repair_options_est(tp, + err = tcp_repair_options_est(sk, (struct tcp_repair_opt __user *)optval, optlen); else -- cgit v1.2.3 From 898805e0cdf7fd860ec21bf661d3a0285a3defbd Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 30 May 2017 16:21:51 +0100 Subject: net: phy: fix marvell phy status reading The Marvell driver incorrectly provides phydev->lp_advertising as the logical and of the link partner's advert and our advert. This is incorrect - this field is supposed to store the link parter's unmodified advertisment. This allows ethtool to report the correct link partner auto-negotiation status. Fixes: be937f1f89ca ("Marvell PHY m88e1111 driver fix") Signed-off-by: Russell King Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/marvell.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 9097e42bec2e..57297ba23987 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -1127,8 +1127,6 @@ static int marvell_read_status_page(struct phy_device *phydev, int page) if (adv < 0) return adv; - lpa &= adv; - if (status & MII_M1011_PHY_STATUS_FULLDUPLEX) phydev->duplex = DUPLEX_FULL; else -- cgit v1.2.3 From 1b8f8694bb4992135dac150bf44a6c139e573970 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 30 May 2017 21:38:18 +0100 Subject: net: fix auto-loading of Marvell DSA driver Auto-loading of the Marvell DSA driver has stopped working with recent kernels. This seems to be due to the change of binding for DSA devices, moving them from the platform bus to the MDIO bus. In order for module auto-loading to work, we need to provide a MODALIAS string in the uevent file for the device. However, the device core does not automatically provide this, and needs each bus_type to implement a uevent method to generate these strings. The MDIO bus does not provide such a method, so no MODALIAS string is provided: .# cat /sys/bus/mdio_bus/devices/f1072004.mdio-mii\:04/uevent DRIVER=mv88e6085 OF_NAME=switch OF_FULLNAME=/soc/internal-regs/mdio@72004/switch@4 OF_COMPATIBLE_0=marvell,mv88e6085 OF_COMPATIBLE_N=1 In the case of OF-based devices, the solution is easy - of_device_uevent_modalias() does the work for us. After this is done, the uevent file looks like this: .# cat /sys/bus/mdio_bus/devices/f1072004.mdio-mii\:04/uevent DRIVER=mv88e6085 OF_NAME=switch OF_FULLNAME=/soc/internal-regs/mdio@72004/switch@4 OF_COMPATIBLE_0=marvell,mv88e6085 OF_COMPATIBLE_N=1 MODALIAS=of:NswitchTCmarvell,mv88e6085 which results in auto-loading of the Marvell DSA driver on Clearfog platforms. Fixes: c0405563a613 ("ARM: dts: armada-388-clearfog: Utilize new DSA binding") Signed-off-by: Russell King Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/phy/mdio_bus.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 8e73f5f36e71..f99c21f78b63 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -658,6 +658,18 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv) return 0; } +static int mdio_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + int rc; + + /* Some devices have extra OF data and an OF-style MODALIAS */ + rc = of_device_uevent_modalias(dev, env); + if (rc != -ENODEV) + return rc; + + return 0; +} + #ifdef CONFIG_PM static int mdio_bus_suspend(struct device *dev) { @@ -708,6 +720,7 @@ static const struct dev_pm_ops mdio_bus_pm_ops = { struct bus_type mdio_bus_type = { .name = "mdio_bus", .match = mdio_bus_match, + .uevent = mdio_uevent, .pm = MDIO_BUS_PM_OPS, }; EXPORT_SYMBOL(mdio_bus_type); -- cgit v1.2.3 From 06d2d6431bc8d41ef5ffd8bd4b52cea9f72aed22 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 30 May 2017 17:38:43 -0500 Subject: net: freescale: fix potential null pointer dereference Add NULL check before dereferencing pointer _id_ in order to avoid a potential NULL pointer dereference. Addresses-Coverity-ID: 1397995 Signed-off-by: Gustavo A. R. Silva Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fsl_pq_mdio.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c index 446c7b374ff5..a10de1e9c157 100644 --- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c +++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c @@ -381,7 +381,7 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev) { const struct of_device_id *id = of_match_device(fsl_pq_mdio_match, &pdev->dev); - const struct fsl_pq_mdio_data *data = id->data; + const struct fsl_pq_mdio_data *data; struct device_node *np = pdev->dev.of_node; struct resource res; struct device_node *tbi; @@ -389,6 +389,13 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev) struct mii_bus *new_bus; int err; + if (!id) { + dev_err(&pdev->dev, "Failed to match device\n"); + return -ENODEV; + } + + data = id->data; + dev_dbg(&pdev->dev, "found %s compatible node\n", id->compatible); new_bus = mdiobus_alloc_size(sizeof(*priv)); -- cgit v1.2.3 From e8f4ae85439f34bec3b0ab69223a41809dab28c9 Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Wed, 31 May 2017 09:40:11 +0800 Subject: isdn: Fix a sleep-in-atomic bug The driver may sleep under a spin lock, the function call path is: isdn_ppp_mp_receive (acquire the lock) isdn_ppp_mp_reassembly isdn_ppp_push_higher isdn_ppp_decompress isdn_ppp_ccp_reset_trans isdn_ppp_ccp_reset_alloc_state kzalloc(GFP_KERNEL) --> may sleep To fixed it, the "GFP_KERNEL" is replaced with "GFP_ATOMIC". Signed-off-by: Jia-Ju Bai Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_ppp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index d07dd5196ffc..8aa158a09180 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -2364,7 +2364,7 @@ static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_s id); return NULL; } else { - rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_KERNEL); + rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_ATOMIC); if (!rs) return NULL; rs->state = CCPResetIdle; -- cgit v1.2.3 From c2e8471d98f072f0f18acdd7df5b401ed0d29a2c Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 30 May 2017 23:50:36 -0700 Subject: mpls: fix clearing of dead nh_flags on link up recent fixes to use WRITE_ONCE for nh_flags on link up, accidently ended up leaving the deadflags on a nh. This patch fixes the WRITE_ONCE to use freshly evaluated nh_flags. Fixes: 39eb8cd17588 ("net: mpls: rt_nhn_alive and nh_flags should be accessed using READ_ONCE") Reported-by: Satish Ashok Signed-off-by: Roopa Prabhu Acked-by: David Ahern Signed-off-by: David S. Miller --- net/mpls/af_mpls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 257ec66009da..7b05fd1497ce 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -1418,7 +1418,7 @@ static void mpls_ifup(struct net_device *dev, unsigned int flags) continue; alive++; nh_flags &= ~flags; - WRITE_ONCE(nh->nh_flags, flags); + WRITE_ONCE(nh->nh_flags, nh_flags); } endfor_nexthops(rt); WRITE_ONCE(rt->rt_nhn_alive, alive); -- cgit v1.2.3 From 1dbf647f31751a4e94fa0435c34f0f5ad5ce0adc Mon Sep 17 00:00:00 2001 From: Arend Van Spriel Date: Fri, 26 May 2017 13:02:55 +0200 Subject: brcmfmac: fix alignment configuration on host using 64-bit DMA For SDIO the alignment requirement for transfers from device to host is configured in firmware. This configuration is limited to minimum of 4-byte alignment. However, this is not correct for platforms using 64-bit DMA when the minimum alignment should be 8 bytes. This issue appeared when the ALIGNMENT definition was set according the DMA configuration. The configuration in firmware was not using that macro defintion, but a hardcoded value of 4. Hence the driver reported alignment failures for data coming from the device and causing transfers to fail. Fixes: 6e84ab604bde ("brcmfmac: properly align buffers on certain platforms Reported-by: Hans de Goede Tested-by: Hans de Goede Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: Hans de Goede Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index fc64b8913aa6..e03450059b06 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -3422,7 +3422,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev) /* otherwise, set txglomalign */ value = sdiodev->settings->bus.sdio.sd_sgentry_align; /* SDIO ADMA requires at least 32 bit alignment */ - value = max_t(u32, value, 4); + value = max_t(u32, value, ALIGNMENT); err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, sizeof(u32)); } -- cgit v1.2.3 From 5ea6d691aac6c93b790f0905e3460d44cc4c449b Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Thu, 1 Jun 2017 16:18:10 +0800 Subject: qlcnic: Fix a sleep-in-atomic bug in qlcnic_82xx_hw_write_wx_2M and qlcnic_82xx_hw_read_wx_2M The driver may sleep under a write spin lock, and the function call path is: qlcnic_82xx_hw_write_wx_2M (acquire the lock by write_lock_irqsave) crb_win_lock qlcnic_pcie_sem_lock usleep_range qlcnic_82xx_hw_read_wx_2M (acquire the lock by write_lock_irqsave) crb_win_lock qlcnic_pcie_sem_lock usleep_range To fix it, the usleep_range is replaced with udelay. Signed-off-by: Jia-Ju Bai Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 838cc0ceafd8..7848cf04b29a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -341,7 +341,7 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg) } return -EIO; } - usleep_range(1000, 1500); + udelay(1200); } if (id_reg) -- cgit v1.2.3 From 7212462fa6fdae61f7f40a4ead048def45bb23cb Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Thu, 1 Jun 2017 10:00:07 +0200 Subject: netlink: don't send unknown nsid The NETLINK_F_LISTEN_ALL_NSID otion enables to listen all netns that have a nsid assigned into the netns where the netlink socket is opened. The nsid is sent as metadata to userland, but the existence of this nsid is checked only for netns that are different from the socket netns. Thus, if no nsid is assigned to the socket netns, NETNSA_NSID_NOT_ASSIGNED is reported to the userland. This value is confusing and useless. After this patch, only valid nsid are sent to userland. Reported-by: Flavio Leitner Signed-off-by: Nicolas Dichtel Signed-off-by: David S. Miller --- net/netlink/af_netlink.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index ee841f00a6ec..7586d446d7dc 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include @@ -1415,7 +1416,8 @@ static void do_one_broadcast(struct sock *sk, goto out; } NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net); - NETLINK_CB(p->skb2).nsid_is_set = true; + if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED) + NETLINK_CB(p->skb2).nsid_is_set = true; val = netlink_broadcast_deliver(sk, p->skb2); if (val < 0) { netlink_overrun(sk); -- cgit v1.2.3 From 2b7ea64f94347b72235e563fedd6ef1ead4d11ec Mon Sep 17 00:00:00 2001 From: Ganesh Goudar Date: Thu, 1 Jun 2017 17:11:30 +0530 Subject: cxgb4: update latest firmware version supported Change t4fw_version.h to update latest firmware version number to 1.16.45.0. Signed-off-by: Ganesh Goudar Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h index 3549d3876278..f2d623a7aee0 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h @@ -37,7 +37,7 @@ #define T4FW_VERSION_MAJOR 0x01 #define T4FW_VERSION_MINOR 0x10 -#define T4FW_VERSION_MICRO 0x2B +#define T4FW_VERSION_MICRO 0x2D #define T4FW_VERSION_BUILD 0x00 #define T4FW_MIN_VERSION_MAJOR 0x01 @@ -46,7 +46,7 @@ #define T5FW_VERSION_MAJOR 0x01 #define T5FW_VERSION_MINOR 0x10 -#define T5FW_VERSION_MICRO 0x2B +#define T5FW_VERSION_MICRO 0x2D #define T5FW_VERSION_BUILD 0x00 #define T5FW_MIN_VERSION_MAJOR 0x00 @@ -55,7 +55,7 @@ #define T6FW_VERSION_MAJOR 0x01 #define T6FW_VERSION_MINOR 0x10 -#define T6FW_VERSION_MICRO 0x2B +#define T6FW_VERSION_MICRO 0x2D #define T6FW_VERSION_BUILD 0x00 #define T6FW_MIN_VERSION_MAJOR 0x00 -- cgit v1.2.3 From 3968d38917eb9bd0cd391265f6c9c538d9b33ffa Mon Sep 17 00:00:00 2001 From: "Mintz, Yuval" Date: Thu, 1 Jun 2017 15:57:56 +0300 Subject: bnx2x: Fix Multi-Cos Apparently multi-cos isn't working for bnx2x quite some time - driver implements ndo_select_queue() to allow queue-selection for FCoE, but the regular L2 flow would cause it to modulo the fallback's result by the number of queues. The fallback would return a queue matching the needed tc [via __skb_tx_hash()], but since the modulo is by the number of TSS queues where number of TCs is not accounted, transmission would always be done by a queue configured into using TC0. Fixes: ada7c19e6d27 ("bnx2x: use XPS if possible for bnx2x_select_queue instead of pure hash") Signed-off-by: Yuval Mintz Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index eccb3d1b6abb..5f49334dcad5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1926,7 +1926,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, } /* select a non-FCoE queue */ - return fallback(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp); + return fallback(dev, skb) % (BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos); } void bnx2x_set_num_queues(struct bnx2x *bp) -- cgit v1.2.3 From aeb073241fe7a2b932e04e20c60e47718332877f Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Thu, 1 Jun 2017 18:07:55 +0300 Subject: net: bridge: start hello timer only if device is up When the transition of NO_STP -> KERNEL_STP was fixed by always calling mod_timer in br_stp_start, it introduced a new regression which causes the timer to be armed even when the bridge is down, and since we stop the timers in its ndo_stop() function, they never get disabled if the device is destroyed before it's upped. To reproduce: $ while :; do ip l add br0 type bridge hello_time 100; brctl stp br0 on; ip l del br0; done; CC: Xin Long CC: Ivan Vecera CC: Sebastian Ott Reported-by: Sebastian Ott Fixes: 6d18c732b95c ("bridge: start hello_timer when enabling KERNEL_STP in br_stp_start") Signed-off-by: Nikolay Aleksandrov Signed-off-by: David S. Miller --- net/bridge/br_stp_if.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 0db8102995a5..6f12a5271219 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -179,7 +179,8 @@ static void br_stp_start(struct net_bridge *br) br_debug(br, "using kernel STP\n"); /* To start timers on any ports left in blocking */ - mod_timer(&br->hello_timer, jiffies + br->hello_time); + if (br->dev->flags & IFF_UP) + mod_timer(&br->hello_timer, jiffies + br->hello_time); br_port_state_selection(br); } -- cgit v1.2.3 From 35cf2845563c1aaa01d27bd34d64795c4ae72700 Mon Sep 17 00:00:00 2001 From: Lance Richardson Date: Mon, 29 May 2017 13:25:57 -0400 Subject: vxlan: eliminate cached dst leak After commit 0c1d70af924b ("net: use dst_cache for vxlan device"), cached dst entries could be leaked when more than one remote was present for a given vxlan_fdb entry, causing subsequent netns operations to block indefinitely and "unregister_netdevice: waiting for lo to become free." messages to appear in the kernel log. Fix by properly releasing cached dst and freeing resources in this case. Fixes: 0c1d70af924b ("net: use dst_cache for vxlan device") Signed-off-by: Lance Richardson Acked-by: Paolo Abeni Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 328b4712683c..5c1d69e3787