* Re: [PATCH] usbnet: convert dev(dbg|err|warn|info) macros to usbnet_(dbg|err|warn|info)
From: David Miller @ 2010-02-12 20:38 UTC (permalink / raw)
To: david-b
Cc: joe, gregkh, linux-usb, netdev, linux-kernel, oliver, jacmet,
steve.glendinning
In-Reply-To: <201002092256.30175.david-b@pacbell.net>
From: David Brownell <david-b@pacbell.net>
Date: Tue, 9 Feb 2010 22:56:29 -0800
> On Tuesday 09 February 2010, Joe Perches wrote:
>
>> netdev_printk macros instead.
>>
>> http://patchwork.ozlabs.org/patch/44955/
>
> That'd make sense. Had they existed way back when ...
> they could have been used instead of custom stuff.
Joe, this patch doesn't apply cleanly to net-next-2.6 so could
you respin whatever variant of this you want me to apply?
Thanks!
^ permalink raw reply
* Re: [PATCH 1/2] e1000e: Only disable ASPM on 82573L devices
From: David Miller @ 2010-02-12 20:39 UTC (permalink / raw)
To: mjg
Cc: e1000-devel, netdev, linux-kernel, jeffrey.t.kirsher,
peter.p.waskiewicz.jr
In-Reply-To: <1265756630-8093-1-git-send-email-mjg@redhat.com>
Intel folks, are you looking at these patches?
Thanks.
^ permalink raw reply
* Re: [PATCH 1/2] e1000e: Only disable ASPM on 82573L devices
From: Brandeburg, Jesse @ 2010-02-12 20:54 UTC (permalink / raw)
To: David Miller
Cc: mjg@redhat.com, e1000-devel@lists.sourceforge.net,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Kirsher, Jeffrey T, Waskiewicz Jr, Peter P, bruce.w.allan
In-Reply-To: <20100212.123917.109973609.davem@davemloft.net>
On Fri, 12 Feb 2010, David Miller wrote:
> Intel folks, are you looking at these patches?
Hi Dave, yes we're looking at them but due to Bruce being out, we need to
wait until next week to reply. If you can wait, we'll make sure they come
through Jeff or receive comments after full review.
It's a bit of a scary area to mess with as there were lots of ASPM related
bugs in the hardware in this hardware generation (system chipsets and
82573).
^ permalink raw reply
* Re: [PATCH v2] net/macvtap: fix reference counting
From: Ed Swierk @ 2010-02-12 20:58 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: Patrick McHardy, Sridhar Samudrala, netdev
In-Reply-To: <201002111655.40349.arnd@arndb.de>
On Thu, Feb 11, 2010 at 7:55 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> The RCU usage in the original code was broken because
> there are cases where we possibly sleep with rcu_read_lock
> held. As a fix, change the macvtap_file_get_queue to
> get a reference on the socket and the netdev instead of
> taking the full rcu_read_lock.
>
> Also, change macvtap_file_get_queue failure case to
> not require a subsequent macvtap_file_put_queue, as
> pointed out by Ed Swierk.
Works for me. Thanks.
Acked-by: Ed Swierk <eswierk@aristanetworks.com>
^ permalink raw reply
* Re: [RFC PATCH net-next 0/7] Add netdev_printk and netif_printk macros
From: David Miller @ 2010-02-12 21:10 UTC (permalink / raw)
To: joe; +Cc: netdev, bhutchings
In-Reply-To: <20100212.123129.163263355.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Fri, 12 Feb 2010 12:31:29 -0800 (PST)
> All applied to net-next-2.6, thanks!
Hmmm, some build problems:
drivers/net/atl1e/atl1e_main.c: In function 'atl1e_vlan_rx_register':
drivers/net/atl1e/atl1e_main.c:322: error: 'struct net_device' has no member named 'adapter'
drivers/net/atl1e/atl1e_main.c:322: error: 'struct net_device' has no member named 'adapter'
drivers/net/atl1e/atl1e_main.c: In function 'atl1e_restore_vlan':
drivers/net/atl1e/atl1e_main.c:343: error: 'struct net_device' has no member named 'adapter'
drivers/net/atl1e/atl1e_main.c:343: error: 'struct net_device' has no member named 'adapter'
...
Passing in a derference like "adapter->netdev" as an argument doesn't work with these macros
end up giving us things like:
dev_driver_string((adapter->netdev)->adapter->netdev.parent)
and
dev_name((adapter->netdev)->adapter->netdev.parent)
The issue seems to be the netdev_dbg() define when DEBUG is not set and
CONFIG_DYNAMIC_DEBUG is set.
It goes "(dev)->dev.parent" and CPP has fun with that.
I'll use a different name for the first macro argument to netdev_dbg() and see
if that's enough to fix this.
^ permalink raw reply
* [PATCH] net: remove INIT_RCU_HEAD() usage
From: Alexey Dobriyan @ 2010-02-12 21:41 UTC (permalink / raw)
To: davem; +Cc: netdev
call_rcu() will unconditionally reinitialize RCU head anyway.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
net/core/drop_monitor.c | 1 -
net/ipv6/sit.c | 1 -
net/ipv6/xfrm6_tunnel.c | 1 -
net/netlabel/netlabel_domainhash.c | 1 -
net/netlabel/netlabel_unlabeled.c | 3 ---
net/sctp/bind_addr.c | 1 -
net/sctp/ipv6.c | 1 -
net/sctp/protocol.c | 1 -
8 files changed, 10 deletions(-)
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -296,7 +296,6 @@ static int dropmon_net_event(struct notifier_block *ev_block,
new_stat->dev = dev;
new_stat->last_rx = jiffies;
- INIT_RCU_HEAD(&new_stat->rcu);
spin_lock(&trace_state_lock);
list_add_rcu(&new_stat->list, &hw_stats_list);
spin_unlock(&trace_state_lock);
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -363,7 +363,6 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
goto out;
}
- INIT_RCU_HEAD(&p->rcu_head);
p->next = t->prl;
p->addr = a->addr;
p->flags = a->flags;
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -178,7 +178,6 @@ alloc_spi:
if (!x6spi)
goto out;
- INIT_RCU_HEAD(&x6spi->rcu_head);
memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr));
x6spi->spi = spi;
atomic_set(&x6spi->refcnt, 1);
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -315,7 +315,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
entry_old = netlbl_domhsh_search_def(entry->domain);
if (entry_old == NULL) {
entry->valid = 1;
- INIT_RCU_HEAD(&entry->rcu);
if (entry->domain != NULL) {
u32 bkt = netlbl_domhsh_hash(entry->domain);
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -327,7 +327,6 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
entry->list.addr = addr->s_addr & mask->s_addr;
entry->list.mask = mask->s_addr;
entry->list.valid = 1;
- INIT_RCU_HEAD(&entry->rcu);
entry->secid = secid;
spin_lock(&netlbl_unlhsh_lock);
@@ -373,7 +372,6 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
ipv6_addr_copy(&entry->list.mask, mask);
entry->list.valid = 1;
- INIT_RCU_HEAD(&entry->rcu);
entry->secid = secid;
spin_lock(&netlbl_unlhsh_lock);
@@ -410,7 +408,6 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
INIT_LIST_HEAD(&iface->addr4_list);
INIT_LIST_HEAD(&iface->addr6_list);
iface->valid = 1;
- INIT_RCU_HEAD(&iface->rcu);
spin_lock(&netlbl_unlhsh_lock);
if (ifindex > 0) {
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -186,7 +186,6 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
addr->valid = 1;
INIT_LIST_HEAD(&addr->list);
- INIT_RCU_HEAD(&addr->rcu);
/* We always hold a socket lock when calling this function,
* and that acts as a writer synchronizing lock.
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -381,7 +381,6 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist,
addr->a.v6.sin6_scope_id = dev->ifindex;
addr->valid = 1;
INIT_LIST_HEAD(&addr->list);
- INIT_RCU_HEAD(&addr->rcu);
list_add_tail(&addr->list, addrlist);
}
}
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -188,7 +188,6 @@ static void sctp_v4_copy_addrlist(struct list_head *addrlist,
addr->a.v4.sin_addr.s_addr = ifa->ifa_local;
addr->valid = 1;
INIT_LIST_HEAD(&addr->list);
- INIT_RCU_HEAD(&addr->rcu);
list_add_tail(&addr->list, addrlist);
}
}
^ permalink raw reply
* pull request: wireless-2.6 2010-02-12
From: John W. Linville @ 2010-02-12 21:45 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
Dave,
Here are a couple of stragglers for 2.6.33. One purports to fix a
crash, the other avoids processing of uninitialized data when using
devices with rate control in hardware.
The latter patch will cause a merge issue in linux-next. I'll be happy
to resolve that in wireless-next-2.6 once this merge request is
resolved.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit 044c18c9f51a2b92b310e28bb121e55451b088dd:
David S. Miller (1):
Merge branch 'master' of git://git.kernel.org/.../linville/wireless-2.6
are available in the git repository at:
ssh://master.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git master
Juuso Oikarinen (1):
mac80211: fix handling of null-rate control in rate_control_get_rate
Shanyu Zhao (1):
iwlwifi: fix AMSDU Rx after paged Rx patch
drivers/net/wireless/iwlwifi/iwl-rx.c | 5 ++++-
net/mac80211/rate.c | 3 +++
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 6f36b6e..2dbce85 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -928,7 +928,10 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
if (ieee80211_is_mgmt(fc) ||
ieee80211_has_protected(fc) ||
ieee80211_has_morefrags(fc) ||
- le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)
+ le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG ||
+ (ieee80211_is_data_qos(fc) &&
+ *ieee80211_get_qos_ctl(hdr) &
+ IEEE80211_QOS_CONTROL_A_MSDU_PRESENT))
ret = skb_linearize(skb);
else
ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index b9007f8..12a2bff 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -245,6 +245,9 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
info->control.rates[i].count = 1;
}
+ if (sdata->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
+ return;
+
if (sta && sdata->force_unicast_rateidx > -1) {
info->control.rates[0].idx = sdata->force_unicast_rateidx;
} else {
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply related
* pull request: wireless-next-2.6 2010-02-12
From: John W. Linville @ 2010-02-12 21:45 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev
Dave,
Here is this weeks dump of wireless bits intended for 2.6.34. It is the
usual variety of driver updates and fixes to problems introduced by
updates earlier in the cycle. Also, more progress on N-phy support in
b43 and the removal of the unused mac80211 op get_tx_stats.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit 375c568844e49d292885c7485d4a255f71680e56:
stephen hemminger (1):
sky2: receive checksum refactoring
are available in the git repository at:
ssh://master.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6.git master
Andres Salomon (1):
mac80211: make rate_control_alloc static
Ben M Cahill (2):
iwlwifi: Add chain noise scaling factor
iwlwifi: Add chain_noise support for 6050
Benoit Papillault (2):
mac80211: Fix probe request filtering in IBSS mode
mac80211: Added a new debugfs file for reading channel_type
Bob Copeland (1):
ath5k: use correct packet type when transmitting
Christian Lamparter (1):
ath: fix WARN_ON with Polish (Poland) Contry code
Deepak Saxena (1):
Add Station and AdHoc mode support to libertas_tf
Felix Fietkau (1):
ath9k: add a workaround for ack timeout issues
Holger Schurig (1):
libertas: don't retry commands
Jochen Friedrich (1):
ssb: fix interrupt assignment
Johannes Berg (7):
mac80211: fix deferred hardware scan requests
mac80211_hwsim: add fake hw scan handler
wireless: update radiotap parser
mac80211: don't probe if we have probe response
mac80211: allow station add/remove to sleep
mac80211: fix bss_conf.dtim_period
mac80211: fix deauth race
John W. Linville (1):
Merge branch 'master' of git://git.kernel.org/.../linville/wireless-2.6
Kalle Valo (11):
wl1251: fix txop unit
adm821: remove get_tx_stats() mac80211 op
mwl8k: remove get_tx_stats() mac80211 op
ar9170: remove get_tx_stats() mac80211 op
ath5k: remove get_tx_stats() mac80211 op
b43: remove get_tx_stats() mac80211 op
b43legacy: remove get_tx_stats() mac80211 op
iwlwifi: remove get_tx_stats() mac80211 op
p54: remove get_tx_stats() mac80211 op
rt2x00: remove get_tx_stats() mac80211 op
mac80211: remove get_tx_stats() driver op
Larry Finger (2):
b43: Fix throughput regression
b43/b43legacy: Wake queues in wireless_core_start
Michael Buesch (1):
ssb: Fix CONFIG_SSB_SDIOHOST typo
Ming Lei (1):
ath9k: fix keycache leak in split tkip case
Rafał Miłecki (6):
b43: N-PHY: implement overriding RF control intc
b43: N-PHY: prepare code for reapplying TX cal coeffs
b43: N-PHY: save calibration for further restore
b43: N-PHY: partly implement SPUR workaround
b43: N-PHY: load generated samples
b43: N-PHY: handle allocation fail in samples generation
Randy Dunlap (1):
libertas/if_spi: needs linux/semaphore.h
Samuel Ortiz (1):
iwlwifi: Send broadcast probe request only when asked to
Senthil Balasubramanian (2):
ath9k: configure the beacon only if the STA is associated
ath9k: Enable TIM timer interrupt only when needed.
Sujith (1):
mac80211: Deny TX BA session requests during disassociation
Vivek Natarajan (3):
mac80211: Reset dynamic ps timer in Rx path.
mac80211: Retry null data frame for power save.
ath9k: Enable IEEE80211_HW_REPORTS_TX_ACK_STATUS flag for ath9k.
Wey-Yi Guy (2):
iwlwifi: Fix to set correct ht configuration
mac80211: tear down all agg queues when restart/reconfig hw
Documentation/DocBook/mac80211.tmpl | 1 -
drivers/net/wireless/adm8211.c | 13 -
drivers/net/wireless/ath/ar9170/ar9170.h | 8 +-
drivers/net/wireless/ath/ar9170/main.c | 13 -
drivers/net/wireless/ath/ath5k/ath5k.h | 1 -
drivers/net/wireless/ath/ath5k/base.c | 44 +-
drivers/net/wireless/ath/ath5k/base.h | 1 -
drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
drivers/net/wireless/ath/ath9k/beacon.c | 8 +-
drivers/net/wireless/ath/ath9k/hw.c | 18 +-
drivers/net/wireless/ath/ath9k/init.c | 3 +-
drivers/net/wireless/ath/ath9k/main.c | 27 +-
drivers/net/wireless/ath/ath9k/xmit.c | 7 +-
drivers/net/wireless/ath/regd.c | 5 +-
drivers/net/wireless/b43/b43.h | 1 +
drivers/net/wireless/b43/dma.c | 17 -
drivers/net/wireless/b43/dma.h | 5 -
drivers/net/wireless/b43/main.c | 38 +-
drivers/net/wireless/b43/phy_n.c | 302 +++++++++++-
drivers/net/wireless/b43/phy_n.h | 4 +
drivers/net/wireless/b43/pio.c | 17 -
drivers/net/wireless/b43/pio.h | 5 -
drivers/net/wireless/b43legacy/dma.c | 20 -
drivers/net/wireless/b43legacy/dma.h | 10 -
drivers/net/wireless/b43legacy/main.c | 26 +-
drivers/net/wireless/b43legacy/pio.c | 13 -
drivers/net/wireless/b43legacy/pio.h | 11 -
drivers/net/wireless/iwlwifi/iwl-1000.c | 2 +
drivers/net/wireless/iwlwifi/iwl-5000.c | 21 +-
drivers/net/wireless/iwlwifi/iwl-6000.c | 25 +-
drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +-
drivers/net/wireless/iwlwifi/iwl-core.c | 37 +--
drivers/net/wireless/iwlwifi/iwl-core.h | 3 +-
drivers/net/wireless/iwlwifi/iwl-scan.c | 49 ++-
drivers/net/wireless/iwlwifi/iwl-sta.c | 4 +-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 -
drivers/net/wireless/libertas/cmdresp.c | 5 -
drivers/net/wireless/libertas/dev.h | 1 -
drivers/net/wireless/libertas/if_spi.c | 1 +
drivers/net/wireless/libertas/main.c | 31 +-
drivers/net/wireless/libertas_tf/main.c | 3 +
drivers/net/wireless/mac80211_hwsim.c | 44 ++-
drivers/net/wireless/mwl8k.c | 35 +-
drivers/net/wireless/p54/main.c | 11 -
drivers/net/wireless/p54/p54.h | 8 +-
drivers/net/wireless/p54/txrx.c | 2 +-
drivers/net/wireless/rt2x00/rt2400pci.c | 1 -
drivers/net/wireless/rt2x00/rt2500pci.c | 1 -
drivers/net/wireless/rt2x00/rt2500usb.c | 1 -
drivers/net/wireless/rt2x00/rt2800lib.c | 1 -
drivers/net/wireless/rt2x00/rt2x00.h | 2 -
drivers/net/wireless/rt2x00/rt2x00mac.c | 16 -
drivers/net/wireless/rt2x00/rt61pci.c | 1 -
drivers/net/wireless/rt2x00/rt73usb.c | 1 -
drivers/net/wireless/wl12xx/wl1251_main.c | 3 +-
drivers/ssb/driver_mipscore.c | 5 +-
drivers/ssb/main.c | 3 +-
include/net/cfg80211.h | 83 +++-
include/net/ieee80211_radiotap.h | 4 +
include/net/mac80211.h | 49 +-
net/mac80211/agg-tx.c | 8 +
net/mac80211/cfg.c | 25 +-
net/mac80211/debugfs.c | 33 ++
net/mac80211/driver-ops.h | 42 ++-
net/mac80211/driver-trace.h | 75 ++-
net/mac80211/ibss.c | 24 +-
net/mac80211/ieee80211_i.h | 19 +-
net/mac80211/mesh_plink.c | 17 +-
net/mac80211/mlme.c | 60 ++-
net/mac80211/pm.c | 10 +-
net/mac80211/rate.c | 2 +-
net/mac80211/rate.h | 7 +-
net/mac80211/rx.c | 12 +-
net/mac80211/scan.c | 27 +-
net/mac80211/sta_info.c | 731 +++++++++++++--------------
net/mac80211/sta_info.h | 36 +-
net/mac80211/status.c | 17 +-
net/mac80211/tx.c | 11 +-
net/mac80211/util.c | 24 +-
net/wireless/radiotap.c | 305 ++++++++----
80 files changed, 1465 insertions(+), 1096 deletions(-)
Omnibus patch is available here:
http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6-2010-02-12.patch.bz2
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* bnx2 receive ring crash
From: Brian Haley @ 2010-02-12 21:50 UTC (permalink / raw)
To: mchan; +Cc: netdev@vger.kernel.org, Montgomery, Bob
Hi Michael,
We've been seeing some crashes in the bnx2 driver lately in the 2.6.32.x stable
series kernels, v2.0.2 of the driver. One of our engineers has gone through
the dumps and found some inconsistencies in the receive ring, but we don't know
how it happened. I was hoping someone from Broadcom might be able to take a
look and help point us in the right direction so we can track this down, since
it's most likely broken upstream as well. We'll be running tests against
the latest net-next kernel next week. Hopefully there is enough information
below.
Thanks for any help,
-Brian
# ethtool -i eth4
driver: bnx2
version: 2.0.2
firmware-version: 5.0.6
bus-info: 0000:07:00.0
07:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)
Subsystem: Hewlett-Packard Company NC382T PCI Express Dual Port Multifunction Gigabit Server Adapter
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 32
Region 0: Memory at f8000000 (64-bit, non-prefetchable) [size=32M]
[virtual] Expansion ROM at dc100000 [disabled] [size=128K]
Capabilities: [48] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 PME-Enable- DSel=0 DScale=1 PME-
Capabilities: [50] Vital Product Data <?>
Capabilities: [58] Message Signalled Interrupts: Mask- 64bit+ Queue=0/4 Enable-
Address: 0000000000000000 Data: 0000
Capabilities: [a0] MSI-X: Enable+ Mask- TabSize=9
Vector table: BAR=0 offset=0000c000
PBA: BAR=0 offset=0000e000
Capabilities: [ac] Express (v2) Endpoint, MSI 00
DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <4us, L1 <64us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported-
RlxdOrd+ ExtTag- PhantFunc- AuxPwr+ NoSnoop+
MaxPayload 256 bytes, MaxReadReq 4096 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend-
LnkCap: Port #0, Speed 5GT/s, Width x4, ASPM L0s L1, Latency L0 <4us, L1 <4us
ClockPM- Suprise- LLActRep- BwNot-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
Capabilities: [100] Device Serial Number 04-21-af-fe-ff-81-24-00
Capabilities: [110] Advanced Error Reporting <?>
Capabilities: [150] Power Budgeting <?>
Capabilities: [160] Virtual Channel <?>
Kernel driver in use: bnx2
Kernel modules: bnx2
Kernel Crash dump info:
crash-5.0.fix> sys
KERNEL: kernel_link
DUMPFILE: dump.201001241024 [PARTIAL DUMP]
CPUS: 16
DATE: Sun Jan 24 10:23:20 2010
UPTIME: 1 days, 11:27:27
LOAD AVERAGE: 11.16, 11.47, 10.71
TASKS: 360
NODENAME: dl380g6-6.ned.telco
RELEASE: 2.6.32-clim-3-amd64
VERSION: #1 SMP Wed Jan 6 22:06:39 UTC 2010
MACHINE: x86_64 (2267 Mhz)
MEMORY: 12 GB
PANIC: "[127452.588891] Oops: 0000 [#1] SMP " (check log for details)
This is a 2.6.32.2 stable kernel with a few backports, but the network drivers haven't
been touched.
>From dmesg:
[127452.577999] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
[127452.582207] IP: [<ffffffffa00539b7>] bnx2_poll_work+0xc16/0x1111 [bnx2]
>From dis -l bnx2_poll_work:
/build/buildd/linux-2.6-clim-2.6.32-clim/debian/build/build_amd64_none_amd64/drivers/net/bnx2.c: 3007
0xffffffffa00539b7 <bnx2_poll_work+0xc16>: mov 0x8(%rsi),%rax
0xffffffffa00539bb <bnx2_poll_work+0xc1a>: mov %rax,-0x98(%rbp)
Line 3007 is in inlined routine bnx2_rx_skb.
3002 rx_pg = &rxr->rx_pg_ring[pg_cons];
3003
3004 /* Don't unmap yet. If we're unable to allocate a new
3005 * page, we need to recycle the page and the DMA addr.
3006 */
3007 mapping_old = pci_unmap_addr(rx_pg, mapping);
3008 if (i == pages - 1)
3009 frag_len -= 4;
But the rx_pg_ring isn't set up, and we are only here because the l2_fhdr
struct is full of garbage:
3094 rx_hdr = (struct l2_fhdr *) skb->data;
3095 len = rx_hdr->l2_fhdr_pkt_len;
/build/buildd/linux-2.6-clim-2.6.32-clim/debian/build/build_amd64_none_amd64/drivers/net/bnx2.c: 3094
0xffffffffa00531a7 <bnx2_poll_work+0x406>: mov 0xd8(%r12),%rax
0xffffffffa00531af <bnx2_poll_work+0x40e>: mov %rax,-0x160(%rbp)
(0xd8 is offset of unsigned char *data in struct sk_buff.)
rx_hdr is 0xffff88018ddcd020
crash-5.0.fix> struct l2_fhdr 0xffff88018ddcd020
struct l2_fhdr {
l2_fhdr_status = 0x28000000,
l2_fhdr_hash = 0x3a7,
l2_fhdr_vlan_tag = 0x0,
l2_fhdr_pkt_len = 0x3000, <<<<<<<<<<<<<<<<< NOT
l2_fhdr_tcp_udp_xsum = 0x3a7,
l2_fhdr_ip_xsum = 0x0
}
The l2_fhdr_pkt_len isn't really 0x3000. The whole data area of this
skb is a page of test data from our networking test:
crash-5.0.fix> x/512xg 0xffff88018ddcd000
0xffff88018ddcd000: 0x000003a708000000 0x000003a710000000
0xffff88018ddcd010: 0x000003a718000000 0x000003a720000000
0xffff88018ddcd020: 0x000003a728000000 0x000003a730000000
0xffff88018ddcd030: 0x000003a738000000 0x000003a740000000
0xffff88018ddcd040: 0x000003a748000000 0x000003a750000000
0xffff88018ddcd050: 0x000003a758000000 0x000003a760000000
0xffff88018ddcd060: 0x000003a768000000 0x000003a770000000
...
That test pattern consists of an unaligned array of 8-byte integers that
increment by 8. (0x3a708, 0x3a710, 0x3a718, 0x3a720, ...)
I spent a lot of time trying to show that some other part of the kernel
had trashed our ring of sk_buff data, but have concluded that this is
just an uninitialized "size-4096" allocation from a bnx2_alloc_rx_skb
that has not been filled in by the card yet. So why are we trying to
process it in bnx2_rx_int?
Getting the ring info:
struct bnx2_napi is 0xffff8801a420cf00
--------------------------------------
Got this from the saved 2nd param to bnx2_poll_work:
0xffffffffa0052db8 <bnx2_poll_work+0x17>: mov %rsi,-0x1a0(%rbp)
From oops tombstone in dmesg: RBP: ffff880028203e30
crash-5.0.fix> x/xg 0xffff880028203e30-0x1a0
0xffff880028203c90: 0xffff8801a420cf00
struct bnx2 is 0xffff8801a420c5c0
---------------------------------
Got this from struct bnx2_napi:
crash-5.0.fix> struct bnx2_napi.bp 0xffff8801a420cf00
bp = 0xffff8801a420c5c0,
The 9 receive (rx) rings associated with this bnx2 struct:
crash-5.0.fix> struct bnx2 0xffff8801a420c5c0 | grep -e "rx_prod =" -e rx_cons -e hw_rx_cons_ptr -e rx_buf_ring
hw_rx_cons_ptr = 0xffff8801a4de6012, *hw_rx_cons_ptr in dump: 0x0001
rx_prod = 0x101,
rx_cons = 0x1,
rx_buf_ring = 0xffffc900067bd000,
hw_rx_cons_ptr = 0xffff8801a4de6080, *hw_rx_cons_ptr in dump: 0xcac7
rx_prod = 0xcbc7,
rx_cons = 0xcac7,
rx_buf_ring = 0xffffc900067e2000,
hw_rx_cons_ptr = 0xffff8801a4de6100, *hw_rx_cons_ptr in dump: 0x2cbd
rx_prod = 0x2d90,
rx_cons = 0x2c90,
rx_buf_ring = 0xffffc900067e5000,
hw_rx_cons_ptr = 0xffff8801a4de6180, *hw_rx_cons_ptr in dump: 0x3f3f
rx_prod = 0x403f,
rx_cons = 0x3f3f,
rx_buf_ring = 0xffffc900067e8000,
/* This is the ring that we're on when we fail: */
/* The value of hw_cons left on the stack when we entered bnx2_rx_int: 0xcac8
hw_rx_cons_ptr = 0xffff8801a4de6200, *hw_rx_cons_ptr in dump: 0xcb48
rx_prod = 0x6cce,
rx_cons = 0x6bce,
rx_buf_ring = 0xffffc900067eb000,
hw_rx_cons_ptr = 0xffff8801a4de6280, *hw_rx_cons_ptr in dump: 0x2af9
rx_prod = 0x2bf0,
rx_cons = 0x2af0,
rx_buf_ring = 0xffffc900067ee000,
hw_rx_cons_ptr = 0xffff8801a4de6300, *hw_rx_cons_ptr in dump: 0x5763
rx_prod = 0x57f4,
rx_cons = 0x56f4,
rx_buf_ring = 0xffffc900067f1000,
hw_rx_cons_ptr = 0xffff8801a4de6380, *hw_rx_cons_ptr in dump: 0x9a2b
rx_prod = 0x9b0f,
rx_cons = 0x9a0f,
rx_buf_ring = 0xffffc900067f4000,
hw_rx_cons_ptr = 0xffff8801a4de6400, *hw_rx_cons_ptr in dump: 0x0000
rx_prod = 0x0,
rx_cons = 0x0,
rx_buf_ring = 0x0,
hw_rx_cons_ptr = 0xffff8801a4de6400,
rx_prod = 0x0,
rx_cons = 0x0,
rx_buf_ring = 0x0,
Notes:
1) The first (0) ring has seen no action.
2) The last (8) ring isn't initialized.
3) All other rings have the hw_rx_cons_ptr within the limits
shown for rx_cons and rx_prod, except for the ring we're on
when we die.
4) The bad ring's bnx2_napi info is shown again here:
hw_rx_cons_ptr = 0xffff8801a4de6200, *hw_rx_cons_ptr in dump: 0xcb48
rx_prod = 0x6cce,
rx_cons = 0x6bce,
rx_buf_ring = 0xffffc900067eb000,
The hw_cons left on the stack from the first part of bnx2_rx_int
is 0xcac8.
3063 hw_cons = bnx2_get_hw_rx_cons(bnapi);
3064 sw_cons = rxr->rx_cons;
3065 sw_prod = rxr->rx_prod;
...
3071 while (sw_cons != hw_cons) {
That value (0xcac8) is way outside of the rx_cons (0x6bce) and
rx_prod (0x6cce) for this loop. By the time the dump was captured,
the memory value of *hw_rx_cons_ptr had increased to 0xcb48.
Since sw_cons can only catch hw_cons by going around the loop
about 95 more times, this loop isn't going to terminate without
passing through uninitialized skb's.
The values of sw_cons and sw_prod on the stack at the time of
the crash are:
crash-5.0.fix> x/xh 0xffff880028203e30-0x130
0xffff880028203d00: 0x6bcf (sw_cons)
crash-5.0.fix> x/xh 0xffff880028203e30-0x150
0xffff880028203ce0: 0x6ccf (sw_prod)
The hw_cons left on the stack (0xcac8) is suspiciously similar to
the value in the apparently well-behaved 2nd rx_loop shown here:
hw_rx_cons_ptr = 0xffff8801a4de6080, *hw_rx_cons_ptr in dump: 0xcac7
rx_prod = 0xcbc7,
rx_cons = 0xcac7,
rx_buf_ring = 0xffffc900067e2000,
So I think the crash was caused by some corruption of the hw_rx_cons
index to take it way out of the range of rx_prod and rx_cons on this ring,
and that corruption is suspiciously similar to the hw_rx_cons value of
another ring in the set.
hw_rx_cons_ptr = 0xffff8801a4de6200, *hw_rx_cons_ptr in dump: 0xcb48
rx_prod = 0x6cce,
rx_cons = 0x6bce,
rx_buf_ring = 0xffffc900067eb000,
(hw_cons on stack: 0xcac8)
======================================
To test the theory that skb->data on an rx ring could (at times) look like
a whole page of test pattern, I looked through the uninitialized parts of
the other rings (between hw_cons and rx_prod). Two of the other rings
also had data buffers that looked like test patterns. Here is one of them:
rx_buf_ring: 0xffffc900067e5000
rx_prod = 0x2d90,
rx_cons = 0x2c90,
*hw_rx_cons_ptr = 0x2cbd
At index 0x20: (outside of the range of 0x2c90...0x2cbd)
crash-5.0.fix> p ((struct sw_bd *)0xffffc900067e5000)[0x20]
$5 = {
skb = 0xffff8801a185b180,
mapping = 0x194886020
}
crash-5.0.fix> struct sk_buff.data 0xffff8801a185b180
data = 0xffff880194886020 "",
crash-5.0.fix> x/512xg 0xffff880194886000
0xffff880194886000: 0x02c6280000000000 0x02c6300000000000
0xffff880194886010: 0x02c6380000000000 0x02c6400000000000
0xffff880194886020: 0x02c6480000000000 0x02c6500000000000
0xffff880194886030: 0x02c6580000000000 0x02c6600000000000
0xffff880194886040: 0x02c6680000000000 0x02c6700000000000
...
^ permalink raw reply
* [PATCH net-next-2.6] macvtap: Add GSO/csum offload support
From: Sridhar Samudrala @ 2010-02-12 22:27 UTC (permalink / raw)
To: David Miller, Arnd Bergmann, Herbert Xu; +Cc: netdev
This patch adds GSO/checksum offload support to macvtap driver and applies
on top of Arnd's refcnt bugfix.
http://patchwork.ozlabs.org/patch/45136/
Added flags field to macvtap_queue to enable/disable processing of
virtio_net_hdr via IFF_VNET_HDR. This flag is checked to prepend virtio_net_hdr
in the receive path and process/skip virtio_net_hdr in the send path.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index fe7656b..5f70f13 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -17,6 +17,7 @@
#include <net/net_namespace.h>
#include <net/rtnetlink.h>
#include <net/sock.h>
+#include <linux/virtio_net.h>
/*
* A macvtap queue is the central object of this driver, it connects
@@ -37,6 +38,7 @@ struct macvtap_queue {
struct socket sock;
struct macvlan_dev *vlan;
struct file *file;
+ unsigned int flags;
};
static struct proto macvtap_proto = {
@@ -286,6 +288,7 @@ static int macvtap_open(struct inode *inode, struct file *file)
sock_init_data(&q->sock, &q->sk);
q->sk.sk_allocation = GFP_ATOMIC; /* for now */
q->sk.sk_write_space = macvtap_sock_write_space;
+ q->flags = IFF_VNET_HDR;
err = macvtap_set_queue(dev, file, q);
if (err)
@@ -328,6 +331,29 @@ out:
return mask;
}
+static inline struct sk_buff *macvtap_alloc_skb(struct sock *sk, size_t prepad,
+ size_t len, size_t linear,
+ int noblock, int *err)
+{
+ struct sk_buff *skb;
+
+ /* Under a page? Don't bother with paged skb. */
+ if (prepad + len < PAGE_SIZE || !linear)
+ linear = len;
+
+ skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
+ err);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, prepad);
+ skb_put(skb, linear);
+ skb->data_len = len - linear;
+ skb->len += len - linear;
+
+ return skb;
+}
+
/* Get packet from user space buffer */
static ssize_t macvtap_get_user(struct macvtap_queue *q,
const struct iovec *iv, size_t count,
@@ -336,31 +362,99 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q,
struct sk_buff *skb;
size_t len = count;
int err;
+ struct virtio_net_hdr vnet_hdr = { 0 };
+ int vnet_hdr_len = 0;
+ unsigned short gso_type = 0;
+
+ if (q->flags & IFF_VNET_HDR) {
+ vnet_hdr_len = sizeof(vnet_hdr);
+
+ err = -EINVAL;
+ if ((len -= vnet_hdr_len) < 0)
+ goto out;
+
+ err = (memcpy_fromiovecend((void *)&vnet_hdr, iv, 0,
+ vnet_hdr_len));
+ if (err < 0)
+ goto out;
+
+ if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
+ vnet_hdr.csum_start + vnet_hdr.csum_offset + 2 >
+ vnet_hdr.hdr_len)
+ vnet_hdr.hdr_len = vnet_hdr.csum_start +
+ vnet_hdr.csum_offset + 2;
+
+ err = -EINVAL;
+ if (vnet_hdr.hdr_len > len)
+ goto out;
+
+ if (vnet_hdr.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+ switch (vnet_hdr.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+ case VIRTIO_NET_HDR_GSO_TCPV4:
+ gso_type = SKB_GSO_TCPV4;
+ break;
+ case VIRTIO_NET_HDR_GSO_TCPV6:
+ gso_type = SKB_GSO_TCPV6;
+ break;
+ case VIRTIO_NET_HDR_GSO_UDP:
+ gso_type = SKB_GSO_UDP;
+ break;
+ default:
+ goto out;
+ }
+
+ if (vnet_hdr.gso_type & VIRTIO_NET_HDR_GSO_ECN)
+ gso_type |= SKB_GSO_TCP_ECN;
+
+ if (vnet_hdr.gso_size == 0)
+ goto out;
+ }
+ }
if (unlikely(len < ETH_HLEN))
- return -EINVAL;
+ goto out;
- skb = sock_alloc_send_skb(&q->sk, NET_IP_ALIGN + len, noblock, &err);
+ skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, len, vnet_hdr.hdr_len,
+ noblock, &err);
+ if (!skb)
+ goto out;
- if (!skb) {
- macvlan_count_rx(q->vlan, 0, false, false);
- return err;
- }
+ err = -EFAULT;
+ if (skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, len))
+ goto out_free;
- skb_reserve(skb, NET_IP_ALIGN);
- skb_put(skb, count);
+ skb_set_network_header(skb, ETH_HLEN);
+ skb_reset_mac_header(skb);
+ skb->protocol = eth_hdr(skb)->h_proto;
+
+ if (vnet_hdr_len) {
+ if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+ err = -EINVAL;
+ if (!skb_partial_csum_set(skb, vnet_hdr.csum_start,
+ vnet_hdr.csum_offset))
+ goto out_free;
+ }
- if (skb_copy_datagram_from_iovec(skb, 0, iv, 0, len)) {
- macvlan_count_rx(q->vlan, 0, false, false);
- kfree_skb(skb);
- return -EFAULT;
- }
+ if (vnet_hdr.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+ skb_shinfo(skb)->gso_size = vnet_hdr.gso_size;
+ skb_shinfo(skb)->gso_type = gso_type;
- skb_set_network_header(skb, ETH_HLEN);
+ /* Header must be checked, and gso_segs computed. */
+ skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+ skb_shinfo(skb)->gso_segs = 0;
+ }
+ }
macvlan_start_xmit(skb, q->vlan->dev);
+ macvlan_count_rx(q->vlan, skb->len, 1, 0);
return count;
+
+out_free:
+ kfree_skb(skb);
+out:
+ macvlan_count_rx(q->vlan, 0, false, false);
+ return -EINVAL;
}
static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv,
@@ -387,14 +481,54 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
{
struct macvlan_dev *vlan = q->vlan;
int ret;
+ int vnet_hdr_len = 0;
+
+ if (q->flags & IFF_VNET_HDR) {
+ struct virtio_net_hdr vnet_hdr = { 0 };
+
+ vnet_hdr_len = sizeof(vnet_hdr);
+ if ((len -= vnet_hdr_len) < 0)
+ return -EINVAL;
+
+ if (skb_is_gso(skb)) {
+ struct skb_shared_info *sinfo = skb_shinfo(skb);
+
+ /* This is a hint as to how much should be linear. */
+ vnet_hdr.hdr_len = skb_headlen(skb);
+ vnet_hdr.gso_size = sinfo->gso_size;
+ if (sinfo->gso_type & SKB_GSO_TCPV4)
+ vnet_hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+ else if (sinfo->gso_type & SKB_GSO_TCPV6)
+ vnet_hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+ else if (sinfo->gso_type & SKB_GSO_UDP)
+ vnet_hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP;
+ else
+ BUG();
+ if (sinfo->gso_type & SKB_GSO_TCP_ECN)
+ vnet_hdr.gso_type |= VIRTIO_NET_HDR_GSO_ECN;
+ } else
+ vnet_hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ vnet_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+ vnet_hdr.csum_start = skb->csum_start -
+ skb_headroom(skb);
+ vnet_hdr.csum_offset = skb->csum_offset;
+ } /* else everything is zero */
+
+ if (unlikely(memcpy_toiovecend(iv, (void *)&vnet_hdr, 0,
+ vnet_hdr_len)))
+ return -EFAULT;
+ }
+
len = min_t(int, skb->len, len);
- ret = skb_copy_datagram_const_iovec(skb, 0, iv, 0, len);
+ ret = skb_copy_datagram_const_iovec(skb, 0, iv, vnet_hdr_len, len);
macvlan_count_rx(vlan, len, ret == 0, 0);
- return ret ? ret : len;
+ return ret ? ret : (len + vnet_hdr_len);
}
static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv,
@@ -460,14 +594,23 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
unsigned int __user *up = argp;
unsigned int u;
char devname[IFNAMSIZ];
+ int ret;
switch (cmd) {
case TUNSETIFF:
/* ignore the name, just look at flags */
if (get_user(u, &ifr->ifr_flags))
return -EFAULT;
- if (u != (IFF_TAP | IFF_NO_PI))
- return -EINVAL;
+ q = macvtap_file_get_queue(file);
+ if (!q)
+ return -ENOLINK;
+
+ if (u & IFF_VNET_HDR)
+ q->flags |= IFF_VNET_HDR;
+ else
+ q->flags &= ~IFF_VNET_HDR;
+
+ macvtap_file_put_queue(q);
return 0;
case TUNGETIFF:
@@ -475,17 +618,23 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
if (!q)
return -ENOLINK;
memcpy(devname, q->vlan->dev->name, sizeof(devname));
- macvtap_file_put_queue(q);
+ ret = 0;
if (copy_to_user(&ifr->ifr_name, q->vlan->dev->name, IFNAMSIZ) ||
- put_user((TUN_TAP_DEV | TUN_NO_PI), &ifr->ifr_flags))
- return -EFAULT;
- return 0;
+ put_user(q->flags, &ifr->ifr_flags))
+ ret = -EFAULT;
+ macvtap_file_put_queue(q);
+ return ret;
case TUNGETFEATURES:
- if (put_user((IFF_TAP | IFF_NO_PI), up))
- return -EFAULT;
- return 0;
+ q = macvtap_file_get_queue(file);
+ if (!q)
+ return -ENOLINK;
+ ret = 0;
+ if (put_user(q->flags, up))
+ ret = -EFAULT;
+ macvtap_file_put_queue(q);
+ return ret;
case TUNSETSNDBUF:
if (get_user(u, up))
@@ -499,18 +648,14 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
return 0;
case TUNSETOFFLOAD:
- /* let the user check for future flags */
- if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
- TUN_F_TSO_ECN | TUN_F_UFO))
- return -EINVAL;
-
- /* TODO: add support for these, so far we don't
- support any offload */
- if (arg & (TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
- TUN_F_TSO_ECN | TUN_F_UFO))
- return -EINVAL;
-
- return 0;
+ q = macvtap_file_get_queue(file);
+ if (!q)
+ return -ENOLINK;
+ ret = 0;
+ if (!(q->flags & IFF_VNET_HDR))
+ ret = -EINVAL;
+ macvtap_file_put_queue(q);
+ return ret;
default:
return -EINVAL;
^ permalink raw reply related
* Re: bnx2 receive ring crash
From: Michael Chan @ 2010-02-12 22:49 UTC (permalink / raw)
To: Brian Haley; +Cc: netdev@vger.kernel.org, Montgomery, Bob
In-Reply-To: <4B75CD1C.7090808@hp.com>
On Fri, 2010-02-12 at 13:50 -0800, Brian Haley wrote:
> Hi Michael,
>
> We've been seeing some crashes in the bnx2 driver lately in the 2.6.32.x stable
> series kernels, v2.0.2 of the driver. One of our engineers has gone through
> the dumps and found some inconsistencies in the receive ring, but we don't know
> how it happened. I was hoping someone from Broadcom might be able to take a
> look and help point us in the right direction so we can track this down, since
> it's most likely broken upstream as well. We'll be running tests against
> the latest net-next kernel next week. Hopefully there is enough information
> below.
Thanks for the detailed report. The software logic to handle the rx
rings hasn't changed much for many years and my guess is that this may
be caused by firmware. We haven't seen this type of failure in our lab.
If you can do further debugging for us, I'd like to send you a patch to
switch back to an earlier version of the firmware to see if it fixes the
issue. Thanks again.
^ permalink raw reply
* Call +234 807 518 6556 For Claims
From: Western Union @ 2010-02-12 23:19 UTC (permalink / raw)
Dear Western Union Customer,
You have been awarded with the sum of $50,000 USD by our office.Please
provide Mr.Steve Page with the following details listed below so that yourfunds can be remitted to you through Western Union.
1.Name:___ 2.Sex Gender:_____3.Age____4.Residential Address____5.Phone
Number____6.Occupation:____
Mr.Steve Page
Tel.+234 807 518 6556
E-mail: wu.africa1@w.cn
^ permalink raw reply
* bug and question in tcp stack
From: Joe Cao @ 2010-02-12 23:22 UTC (permalink / raw)
To: netdev, linux-kernel
Hi,
I think it is an obvious bug both in the old and latest kernel:
In function net/ipv4/tcp_output.c, tcp_retransmit_skb() returns a NEGTIVE value on failures. But in net/ipv4/tcp_timer.c, in function tcp_retransmit_timer(), the line
if (tcp_retransmit_skb(sk, tcp_write_queue_head(sk)) > 0) {
checks the return value as a positive number, which will never be true. On failures from tcp_retransmit_skb(), the code will follow the wrong path.
My second question is regarding the function tcp_retransmit_skb(). The first check in the function is copied here:
/* Do not sent more than we queued. 1/4 is reserved for possible
* copying overhead: fragmentation, tunneling, mangling etc.
*/
if (atomic_read(&sk->sk_wmem_alloc) >
min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))
return -EAGAIN;
My question is if that turns out to be true, which I saw happend, how could the stack get out of the state? Because all TCP retransmission may fail, no buffer will be released. The connection is virtually dead. Is that true?
Thanks,
Joe
^ permalink raw reply
* Re: bug and question in tcp stack
From: David Miller @ 2010-02-12 23:39 UTC (permalink / raw)
To: caoco2002; +Cc: netdev, linux-kernel
In-Reply-To: <157135.69931.qm@web63405.mail.re1.yahoo.com>
From: Joe Cao <caoco2002@yahoo.com>
Date: Fri, 12 Feb 2010 15:22:16 -0800 (PST)
> if (tcp_retransmit_skb(sk, tcp_write_queue_head(sk)) > 0) {
>
> checks the return value as a positive number, which will never be true.
It can, recheck the code paths.
The upcall to send an SKB out through the packet schedular and onwards
to the actual device can return congestion notification values, which
are positive.
^ permalink raw reply
* [net-next-2.6 PATCH 1/3] ethtool: Fix filter addition when caching n-tuple filters
From: Jeff Kirsher @ 2010-02-12 23:48 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Peter P Waskiewicz Jr, Jeff Kirsher
From: Peter Waskiewicz <peter.p.waskiewicz.jr@intel.com>
We can allow a filter to be added successfully to the underlying
hardware, but still return an error if the cached list memory
allocation fails. This patch fixes that condition.
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
net/core/ethtool.c | 40 ++++++++++++++++++++++++----------------
1 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index a1280f6..fbbe4b4 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -283,18 +283,17 @@ err_out:
return ret;
}
-static int __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
- struct ethtool_rx_ntuple_flow_spec *spec)
+static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
+ struct ethtool_rx_ntuple_flow_spec *spec,
+ struct ethtool_rx_ntuple_flow_spec_container *fsc)
{
- struct ethtool_rx_ntuple_flow_spec_container *fsc;
/* don't add filters forever */
- if (list->count >= ETHTOOL_MAX_NTUPLE_LIST_ENTRY)
- return 0;
-
- fsc = kmalloc(sizeof(*fsc), GFP_ATOMIC);
- if (!fsc)
- return -ENOMEM;
+ if (list->count >= ETHTOOL_MAX_NTUPLE_LIST_ENTRY) {
+ /* free the container */
+ kfree(fsc);
+ return;
+ }
/* Copy the whole filter over */
fsc->fs.flow_type = spec->flow_type;
@@ -310,14 +309,13 @@ static int __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
/* add to the list */
list_add_tail_rcu(&fsc->list, &list->list);
list->count++;
-
- return 0;
}
static int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr)
{
struct ethtool_rx_ntuple cmd;
const struct ethtool_ops *ops = dev->ethtool_ops;
+ struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL;
int ret;
if (!ops->set_rx_ntuple)
@@ -329,16 +327,26 @@ static int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr)
if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
return -EFAULT;
- ret = ops->set_rx_ntuple(dev, &cmd);
-
/*
* Cache filter in dev struct for GET operation only if
* the underlying driver doesn't have its own GET operation, and
- * only if the filter was added successfully.
+ * only if the filter was added successfully. First make sure we
+ * can allocate the filter, then continue if successful.
*/
- if (!ops->get_rx_ntuple && !ret)
- if (__rx_ntuple_filter_add(&dev->ethtool_ntuple_list, &cmd.fs))
+ if (!ops->get_rx_ntuple) {
+ fsc = kmalloc(sizeof(*fsc), GFP_ATOMIC);
+ if (!fsc)
return -ENOMEM;
+ }
+
+ ret = ops->set_rx_ntuple(dev, &cmd);
+ if (ret) {
+ kfree(fsc);
+ return ret;
+ }
+
+ if (!ops->get_rx_ntuple)
+ __rx_ntuple_filter_add(&dev->ethtool_ntuple_list, &cmd.fs, fsc);
return ret;
}
^ permalink raw reply related
* [net-next-2.6 PATCH 2/3] ethtool: Move n-tuple capability check into set_flags
From: Jeff Kirsher @ 2010-02-12 23:48 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Peter P Waskiewicz Jr, Jeff Kirsher
In-Reply-To: <20100212234715.2346.60380.stgit@localhost.localdomain>
From: Peter Waskiewicz <peter.p.waskiewicz.jr@intel.com>
set_flags should check if the underlying device supports
n-tuple filter programming before setting the device flags
on the netdevice.
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
net/core/ethtool.c | 13 ++++++++-----
1 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index fbbe4b4..794cf57 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -134,15 +134,21 @@ u32 ethtool_op_get_flags(struct net_device *dev)
int ethtool_op_set_flags(struct net_device *dev, u32 data)
{
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+
if (data & ETH_FLAG_LRO)
dev->features |= NETIF_F_LRO;
else
dev->features &= ~NETIF_F_LRO;
- if (data & ETH_FLAG_NTUPLE)
+ if (data & ETH_FLAG_NTUPLE) {
+ if (!ops->set_rx_ntuple)
+ return -EOPNOTSUPP;
dev->features |= NETIF_F_NTUPLE;
- else
+ } else {
+ /* safe to clear regardless */
dev->features &= ~NETIF_F_NTUPLE;
+ }
return 0;
}
@@ -318,9 +324,6 @@ static int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr)
struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL;
int ret;
- if (!ops->set_rx_ntuple)
- return -EOPNOTSUPP;
-
if (!(dev->features & NETIF_F_NTUPLE))
return -EINVAL;
^ permalink raw reply related
* [net-next-2.6 PATCH 3/3] ixgbe: Cleanup incorrect header comments
From: Jeff Kirsher @ 2010-02-12 23:48 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Peter P Waskiewicz Jr, Jeff Kirsher
In-Reply-To: <20100212234715.2346.60380.stgit@localhost.localdomain>
From: Peter Waskiewicz <peter.p.waskiewicz.jr@intel.com>
The recent n-tuple patches added some comments to the headers
of the Flow Director functions that aren't accurate. This
cleans them up, and is a purely cosmetic patch.
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_82599.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 4fa8633..1f30e16 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -1631,7 +1631,6 @@ static u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *atr_input,
* ixgbe_atr_set_vlan_id_82599 - Sets the VLAN id in the ATR input stream
* @input: input stream to modify
* @vlan: the VLAN id to load
- * @vlan_mask: bitwise mask for the VLAN
**/
s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan)
{
@@ -1645,7 +1644,6 @@ s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan)
* ixgbe_atr_set_src_ipv4_82599 - Sets the source IPv4 address
* @input: input stream to modify
* @src_addr: the IP address to load
- * @src_addr_mask: bitwise mask for the source IP address
**/
s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr)
{
@@ -1663,7 +1661,6 @@ s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr)
* ixgbe_atr_set_dst_ipv4_82599 - Sets the destination IPv4 address
* @input: input stream to modify
* @dst_addr: the IP address to load
- * @dst_addr_mask: bitwise mask for the destination IP address
**/
s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr)
{
@@ -1767,7 +1764,6 @@ s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input,
* ixgbe_atr_set_src_port_82599 - Sets the source port
* @input: input stream to modify
* @src_port: the source port to load
- * @src_port_mask: bitwise mask for the source port
**/
s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port)
{
@@ -1781,7 +1777,6 @@ s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port)
* ixgbe_atr_set_dst_port_82599 - Sets the destination port
* @input: input stream to modify
* @dst_port: the destination port to load
- * @dst_port_mask: bitwise mask for the destination port
**/
s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port)
{
^ permalink raw reply related
* Re: [PATCH 00/10] sky2 update for net-next
From: David Miller @ 2010-02-13 0:21 UTC (permalink / raw)
To: shemminger; +Cc: netdev
In-Reply-To: <20100212165757.767062851@vyatta.com>
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Fri, 12 Feb 2010 08:57:57 -0800
> Several little fixes:
> * Change WoL setup to fix http://bugzilla.kernel.org/show_bug.cgi?id=13764
> * Change Jumbo settings for some chips
> * Mike's changes to avoid free and alloc on driver recovery
All applied to net-next-2.6, thanks!
^ permalink raw reply
* Re: Subject: [PATCH 0/6] bna: Brocade 10Gb Ethernet device driver
From: David Miller @ 2010-02-13 0:41 UTC (permalink / raw)
To: rmody; +Cc: netdev, adapter_linux_open_src_team
In-Reply-To: <201002121400.o1CE0v9w031867@blc-10-10.brocade.com>
From: Rasesh Mody <rmody@brocade.com>
Date: Fri, 12 Feb 2010 06:00:57 -0800
> From: Rasesh Mody <rmody@brocade.com>
>
> This is patch 0/6 which contains the summary of changes we've
> done in this particular submission for Brocade's BR1010/BR1020
> 10Gb CEE capable ethernet adapter. Source is based against
> net-next-2.6.
>
> The changes are as follows:
>
> 1) Cleaned up extra BUG_ON()
>
> 2) Using mutex wherever appropriate
>
> 3) Using PCI_DEVICE_TABLE
>
> We wish this patch to be considered for inclusion in net-next-2.6.
>
> Signed-off-by: Rasesh Mody <rmody@brocade.com>
The driver doesn't build:
drivers/net/bna/bnad.c: In function ‘bnad_alloc_unmap_q’:
drivers/net/bna/bnad.c:850: error: implicit declaration of function ‘vmalloc’
drivers/net/bna/bnad.c:850: warning: assignment makes pointer from integer without a cast
drivers/net/bna/bnad.c: In function ‘bnad_free_txq’:
drivers/net/bna/bnad.c:1319: error: implicit declaration of function ‘vfree’
drivers/net/bna/bnad.c: In function ‘bnad_priv_init’:
drivers/net/bna/bnad.c:3163: warning: assignment makes pointer from integer without a cast
Second, the driver header files make reference to global functions which do
not exist, such as bna_ioctl_init() and friends. Please remove those.
Lastly, some of the files added have extra trailing empty lines, please remove
them.
Thanks.
^ permalink raw reply
* [PATCH 5/9] tg3: Turn off multiple DMA reads for 5717
From: Matt Carlson @ 2010-02-13 0:47 UTC (permalink / raw)
To: davem; +Cc: netdev, andy, mcarlson
The 5717's DMA read engine has a bug when initiating multiple DMA reads
across the PCIe bus. This patch disables the feature.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
---
drivers/net/tg3.c | 3 +++
drivers/net/tg3.h | 1 +
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index d1452d3..1c545a8 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -7915,6 +7915,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
RDMAC_MODE_LNGREAD_ENAB);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+ rdmac_mode |= RDMAC_MODE_MULT_DMA_RD_DIS;
+
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 46db4ad..a8fb53a 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1258,6 +1258,7 @@
#define RDMAC_MODE_MBUF_SBD_CRPT_ENAB 0x00002000
#define RDMAC_MODE_FIFO_SIZE_128 0x00020000
#define RDMAC_MODE_FIFO_LONG_BURST 0x00030000
+#define RDMAC_MODE_MULT_DMA_RD_DIS 0x01000000
#define RDMAC_MODE_IPV4_LSO_EN 0x08000000
#define RDMAC_MODE_IPV6_LSO_EN 0x10000000
#define RDMAC_STATUS 0x00004804
--
1.6.4.4
^ permalink raw reply related
* [PATCH 9/9] tg3: Update driver version to 3.107
From: Matt Carlson @ 2010-02-13 0:47 UTC (permalink / raw)
To: davem; +Cc: netdev, andy, mcarlson
This patch updates the tg3 version to 3.107.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 5b03231..34b0d3c 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.106"
-#define DRV_MODULE_RELDATE "January 12, 2010"
+#define DRV_MODULE_VERSION "3.107"
+#define DRV_MODULE_RELDATE "February 12, 2010"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
--
1.6.4.4
^ permalink raw reply related
* [PATCH 8/9] tg3: Fix AC131 loopback test errors for 5785
From: Matt Carlson @ 2010-02-13 0:47 UTC (permalink / raw)
To: davem; +Cc: netdev, andy, mcarlson
The AC131 does not enable the forced transmit clock settings
immediately. The workaround is to read the register again to get the
setting to take effect.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
---
drivers/net/tg3.c | 8 ++++++--
drivers/net/tg3.h | 3 +++
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 74fa6d5..5b03231 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10822,8 +10822,12 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
mac_mode = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
- tg3_writephy(tp, MII_TG3_FET_PTEST, 0x1800);
+ tg3_writephy(tp, MII_TG3_FET_PTEST,
+ MII_TG3_FET_PTEST_FRC_TX_LINK |
+ MII_TG3_FET_PTEST_FRC_TX_LOCK);
+ /* The write needs to be flushed for the AC131 */
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+ tg3_readphy(tp, MII_TG3_FET_PTEST, &val);
mac_mode |= MAC_MODE_PORT_MODE_MII;
} else
mac_mode |= MAC_MODE_PORT_MODE_GMII;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index a8fb53a..b4fd596 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2112,6 +2112,9 @@
/* Fast Ethernet Tranceiver definitions */
#define MII_TG3_FET_PTEST 0x17
+#define MII_TG3_FET_PTEST_FRC_TX_LINK 0x1000
+#define MII_TG3_FET_PTEST_FRC_TX_LOCK 0x0800
+
#define MII_TG3_FET_TEST 0x1f
#define MII_TG3_FET_SHADOW_EN 0x0080
--
1.6.4.4
^ permalink raw reply related
* [PATCH 0/9] tg3: Bugfixes
From: Matt Carlson @ 2010-02-13 0:47 UTC (permalink / raw)
To: davem; +Cc: netdev, andy, mcarlson
This patchset implements some critical bugfixes for the tg3 driver.
^ permalink raw reply
* [PATCH 2/9] tg3: Prevent rx producer ring overruns
From: Matt Carlson @ 2010-02-13 0:47 UTC (permalink / raw)
To: davem; +Cc: netdev, andy, mcarlson, Michael Chan
When operating in RSS mode, it is possible for one rx return ring to
submit enough rx buffers back to the hardware such that it inadvertently
overwrites data needed by another rx return ring. This patch addresses
the problem by looking for non-NULL skb pointers in the
rx_[std|jmb]_buffers rings that parallel the rx producer rings.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
---
drivers/net/tg3.c | 38 ++++++++++++++++++++++++++++++++++++++
1 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 6874ce5..115fb7c 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -4552,6 +4552,12 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi,
pci_unmap_addr(src_map, mapping));
dest_desc->addr_hi = src_desc->addr_hi;
dest_desc->addr_lo = src_desc->addr_lo;
+
+ /* Ensure that the update to the skb happens after the physical
+ * addresses have been transferred to the new BD location.
+ */
+ smp_wmb();
+
src_map->skb = NULL;
}
@@ -4816,6 +4822,22 @@ static void tg3_rx_prodring_xfer(struct tg3 *tp,
si = spr->rx_std_cons_idx;
di = dpr->rx_std_prod_idx;
+ for (i = di; i < di + cpycnt; i++) {
+ if (dpr->rx_std_buffers[i].skb) {
+ cpycnt = i - di;
+ break;
+ }
+ }
+
+ if (!cpycnt)
+ break;
+
+ /* Ensure that updates to the rx_std_buffers ring and the
+ * shadowed hardware producer ring from tg3_recycle_skb() are
+ * ordered correctly WRT the skb check above.
+ */
+ smp_rmb();
+
memcpy(&dpr->rx_std_buffers[di],
&spr->rx_std_buffers[si],
cpycnt * sizeof(struct ring_info));
@@ -4856,6 +4878,22 @@ static void tg3_rx_prodring_xfer(struct tg3 *tp,
si = spr->rx_jmb_cons_idx;
di = dpr->rx_jmb_prod_idx;
+ for (i = di; i < di + cpycnt; i++) {
+ if (dpr->rx_jmb_buffers[i].skb) {
+ cpycnt = i - di;
+ break;
+ }
+ }
+
+ if (!cpycnt)
+ break;
+
+ /* Ensure that updates to the rx_jmb_buffers ring and the
+ * shadowed hardware producer ring from tg3_recycle_skb() are
+ * ordered correctly WRT the skb check above.
+ */
+ smp_rmb();
+
memcpy(&dpr->rx_jmb_buffers[di],
&spr->rx_jmb_buffers[si],
cpycnt * sizeof(struct ring_info));
--
1.6.4.4
^ permalink raw reply related
* [PATCH 3/9] tg3: Unwedge stuck MSI-X vectors
From: Matt Carlson @ 2010-02-13 0:47 UTC (permalink / raw)
To: davem; +Cc: netdev, andy, mcarlson
The previous patch changed the code so that new rx buffer submissions to
the hardware stall if a new submission would overwrite data needed by an
unserviced rx packet. On very busy 5717 and 57765 asic rev devices,
there is a corner case where the hardware will fail to assert an MSI-X
interrupt for rx traffic. If that vector's interrupt never has another
reason to assert, any rx buffers held will never be serviced. If the
buffers are never serviced and the hardware consumes all the available
rx packets for other rx rings, deadlock will result.
The most reliable and least intrusive way to work around the problem is
to detect the case where new submissions would overwrite existing data
and force all rx interrupt vectors to fire.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
---
drivers/net/tg3.c | 29 +++++++++++++++++++----------
drivers/net/tg3.h | 1 +
2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 115fb7c..e6ee291 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -642,7 +642,6 @@ static void tg3_disable_ints(struct tg3 *tp)
static void tg3_enable_ints(struct tg3 *tp)
{
int i;
- u32 coal_now = 0;
tp->irq_sync = 0;
wmb();
@@ -650,13 +649,14 @@ static void tg3_enable_ints(struct tg3 *tp)
tw32(TG3PCI_MISC_HOST_CTRL,
(tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
+ tp->coal_now = tp->coalesce_mode | HOSTCC_MODE_ENABLE;
for (i = 0; i < tp->irq_cnt; i++) {
struct tg3_napi *tnapi = &tp->napi[i];
tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
- coal_now |= tnapi->coal_now;
+ tp->coal_now |= tnapi->coal_now;
}
/* Force an initial interrupt */
@@ -664,8 +664,9 @@ static void tg3_enable_ints(struct tg3 *tp)
(tp->napi[0].hw_status->status & SD_STATUS_UPDATED))
tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
else
- tw32(HOSTCC_MODE, tp->coalesce_mode |
- HOSTCC_MODE_ENABLE | coal_now);
+ tw32(HOSTCC_MODE, tp->coal_now);
+
+ tp->coal_now &= ~(tp->napi[0].coal_now | tp->napi[1].coal_now);
}
static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
@@ -4794,12 +4795,12 @@ static void tg3_poll_link(struct tg3 *tp)
}
}
-static void tg3_rx_prodring_xfer(struct tg3 *tp,
- struct tg3_rx_prodring_set *dpr,
- struct tg3_rx_prodring_set *spr)
+static int tg3_rx_prodring_xfer(struct tg3 *tp,
+ struct tg3_rx_prodring_set *dpr,
+ struct tg3_rx_prodring_set *spr)
{
u32 si, di, cpycnt, src_prod_idx;
- int i;
+ int i, err = 0;
while (1) {
src_prod_idx = spr->rx_std_prod_idx;
@@ -4825,6 +4826,7 @@ static void tg3_rx_prodring_xfer(struct tg3 *tp,
for (i = di; i < di + cpycnt; i++) {
if (dpr->rx_std_buffers[i].skb) {
cpycnt = i - di;
+ err = -ENOSPC;
break;
}
}
@@ -4881,6 +4883,7 @@ static void tg3_rx_prodring_xfer(struct tg3 *tp,
for (i = di; i < di + cpycnt; i++) {
if (dpr->rx_jmb_buffers[i].skb) {
cpycnt = i - di;
+ err = -ENOSPC;
break;
}
}
@@ -4911,6 +4914,8 @@ static void tg3_rx_prodring_xfer(struct tg3 *tp,
dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) %
TG3_RX_JUMBO_RING_SIZE;
}
+
+ return err;
}
static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
@@ -4933,12 +4938,13 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
struct tg3_rx_prodring_set *dpr = &tp->prodring[0];
- int i;
+ int i, err = 0;
u32 std_prod_idx = dpr->rx_std_prod_idx;
u32 jmb_prod_idx = dpr->rx_jmb_prod_idx;
for (i = 1; i < tp->irq_cnt; i++)
- tg3_rx_prodring_xfer(tp, dpr, tp->napi[i].prodring);
+ err |= tg3_rx_prodring_xfer(tp, dpr,
+ tp->napi[i].prodring);
wmb();
@@ -4951,6 +4957,9 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
dpr->rx_jmb_prod_idx);
mmiowb();
+
+ if (err)
+ tw32_f(HOSTCC_MODE, tp->coal_now);
}
return work_done;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 88a87bb..cc8bf7d 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2699,6 +2699,7 @@ struct tg3 {
struct net_device *dev;
struct pci_dev *pdev;
+ u32 coal_now;
u32 msg_enable;
/* begin "tx thread" cacheline section */
--
1.6.4.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox