linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: stable-review@kernel.org, torvalds@linux-foundation.org,
	akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
	Milton Miller <miltonm@bga.com>,
	Anton Blanchard <anton@samba.org>,
	Sonny Rao <sonnyrao@us.ibm.com>,
	Jeff Kirsher <jeffrey.t.kirsher@intel.com>,
	"David S. Miller" <davem@davemloft.net>
Subject: [30/67] e100/e1000*/igb*/ixgb*: Add missing read memory barrier
Date: Wed, 11 Aug 2010 17:05:45 -0700	[thread overview]
Message-ID: <20100812000615.433588319@clark.site> (raw)
In-Reply-To: <20100812000641.GA6348@kroah.com>

2.6.35-stable review patch.  If anyone has any objections, please let us know.

------------------

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

commit 2d0bb1c1f4524befe9f0fcf0d0cd3081a451223f upstream.

Based on patches from Sonny Rao and Milton Miller...

Combined the patches to fix up clean_tx_irq and clean_rx_irq.

The PowerPC architecture does not require loads to independent bytes
to be ordered without adding an explicit barrier.

In ixgbe_clean_rx_irq we load the status bit then load the packet data.
With packet split disabled if these loads go out of order we get a
stale packet, but we will notice the bad sequence numbers and drop it.

The problem occurs with packet split enabled where the TCP/IP header
and data are in different descriptors. If the reads go out of order
we may have data that doesn't match the TCP/IP header. Since we use
hardware checksumming this bad data is never verified and it makes it
all the way to the application.

This bug was found during stress testing and adding this barrier has
been shown to fix it.  The bug can manifest as a data integrity issue
(bad payload data) or as a BUG in skb_pull().

This was a nasty bug to hunt down, if people agree with the fix I think
it's a candidate for stable.

Previously Submitted to e1000-devel only for ixgbe

http://marc.info/?l=e1000-devel&m=126593062701537&w=3

We've now seen this problem hit with other device drivers (e1000e mostly)
So I'm resubmitting with fixes for other Intel Device Drivers with
similar issues.

CC: Milton Miller <miltonm@bga.com>
CC: Anton Blanchard <anton@samba.org>
CC: Sonny Rao <sonnyrao@us.ibm.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 drivers/net/e100.c                 |    2 ++
 drivers/net/e1000/e1000_main.c     |    3 +++
 drivers/net/e1000e/netdev.c        |    4 ++++
 drivers/net/igb/igb_main.c         |    2 ++
 drivers/net/igbvf/netdev.c         |    2 ++
 drivers/net/ixgb/ixgb_main.c       |    2 ++
 drivers/net/ixgbe/ixgbe_main.c     |    1 +
 drivers/net/ixgbevf/ixgbevf_main.c |    2 ++
 8 files changed, 18 insertions(+)

--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1779,6 +1779,7 @@ static int e100_tx_clean(struct nic *nic
 	for (cb = nic->cb_to_clean;
 	    cb->status & cpu_to_le16(cb_complete);
 	    cb = nic->cb_to_clean = cb->next) {
+		rmb(); /* read skb after status */
 		netif_printk(nic, tx_done, KERN_DEBUG, nic->netdev,
 			     "cb[%d]->status = 0x%04X\n",
 			     (int)(((void*)cb - (void*)nic->cbs)/sizeof(struct cb)),
@@ -1927,6 +1928,7 @@ static int e100_rx_indicate(struct nic *
 
 	netif_printk(nic, rx_status, KERN_DEBUG, nic->netdev,
 		     "status=0x%04X\n", rfd_status);
+	rmb(); /* read size after status bit */
 
 	/* If data isn't ready, nothing to indicate */
 	if (unlikely(!(rfd_status & cb_complete))) {
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3448,6 +3448,7 @@ static bool e1000_clean_tx_irq(struct e1
 	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
 		bool cleaned = false;
+		rmb();	/* read buffer_info after eop_desc */
 		for ( ; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
@@ -3637,6 +3638,7 @@ static bool e1000_clean_jumbo_rx_irq(str
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		status = rx_desc->status;
 		skb = buffer_info->skb;
@@ -3843,6 +3845,7 @@ static bool e1000_clean_rx_irq(struct e1
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		status = rx_desc->status;
 		skb = buffer_info->skb;
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -774,6 +774,7 @@ static bool e1000_clean_rx_irq(struct e1
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
 
 		status = rx_desc->status;
 		skb = buffer_info->skb;
@@ -984,6 +985,7 @@ static bool e1000_clean_tx_irq(struct e1
 	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
 		bool cleaned = false;
+		rmb(); /* read buffer_info after eop_desc */
 		for (; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
@@ -1080,6 +1082,7 @@ static bool e1000_clean_rx_irq_ps(struct
 			break;
 		(*work_done)++;
 		skb = buffer_info->skb;
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
 
 		/* in the packet split case this is header only */
 		prefetch(skb->data - NET_IP_ALIGN);
@@ -1279,6 +1282,7 @@ static bool e1000_clean_jumbo_rx_irq(str
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
 
 		status = rx_desc->status;
 		skb = buffer_info->skb;
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -5344,6 +5344,7 @@ static bool igb_clean_tx_irq(struct igb_
 
 	while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
+		rmb();	/* read buffer_info after eop_desc status */
 		for (cleaned = false; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
@@ -5549,6 +5550,7 @@ static bool igb_clean_rx_irq_adv(struct
 		if (*work_done >= budget)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		skb = buffer_info->skb;
 		prefetch(skb->data - NET_IP_ALIGN);
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -248,6 +248,7 @@ static bool igbvf_clean_rx_irq(struct ig
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		buffer_info = &rx_ring->buffer_info[i];
 
@@ -780,6 +781,7 @@ static bool igbvf_clean_tx_irq(struct ig
 
 	while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
+		rmb();	/* read buffer_info after eop_desc status */
 		for (cleaned = false; !cleaned; count++) {
 			tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -1816,6 +1816,7 @@ ixgb_clean_tx_irq(struct ixgb_adapter *a
 
 	while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
 
+		rmb(); /* read buffer_info after eop_desc */
 		for (cleaned = false; !cleaned; ) {
 			tx_desc = IXGB_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
@@ -1976,6 +1977,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *a
 			break;
 
 		(*work_done)++;
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
 		status = rx_desc->status;
 		skb = buffer_info->skb;
 		buffer_info->skb = NULL;
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -748,6 +748,7 @@ static bool ixgbe_clean_tx_irq(struct ix
 	while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
 	       (count < tx_ring->work_limit)) {
 		bool cleaned = false;
+		rmb(); /* read buffer_info after eop_desc */
 		for ( ; !cleaned; count++) {
 			struct sk_buff *skb;
 			tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -231,6 +231,7 @@ static bool ixgbevf_clean_tx_irq(struct
 	while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
 	       (count < tx_ring->work_limit)) {
 		bool cleaned = false;
+		rmb(); /* read buffer_info after eop_desc */
 		for ( ; !cleaned; count++) {
 			struct sk_buff *skb;
 			tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
@@ -518,6 +519,7 @@ static bool ixgbevf_clean_rx_irq(struct
 			break;
 		(*work_done)++;
 
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 		if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
 			hdr_info = le16_to_cpu(ixgbevf_get_hdr_info(rx_desc));
 			len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>



  parent reply	other threads:[~2010-08-12  0:08 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-12  0:06 [00/67] 2.6.35.2 stable review Greg KH
2010-08-12  0:05 ` [01/67] x86, vmware: Preset lpj values when on VMware Greg KH
2010-08-12  0:05 ` [02/67] ata_piix: fix locking around SIDPR access Greg KH
2010-08-12  0:05 ` [03/67] perf, powerpc: fsl_emb: Restore setting perf_sample_data.period Greg KH
2010-08-12  0:05 ` [04/67] powerpc: fix build with make 3.82 Greg KH
2010-08-12  0:05 ` [05/67] x86, kmmio/mmiotrace: Fix double free of kmmio_fault_pages Greg KH
2010-08-12  0:05 ` [06/67] x86/PCI: use host bridge _CRS info on ASRock ALiveSATA2-GLAN Greg KH
2010-08-12  0:05 ` [07/67] pcmcia: avoid buffer overflow in pcmcia_setup_isa_irq Greg KH
2010-08-12  0:05 ` [08/67] x86: Add memory modify constraints to xchg() and cmpxchg() Greg KH
2010-08-12  0:05 ` [09/67] staging: rt2870: Add USB ID for Belkin F6D4050 v2 Greg KH
2010-08-12  0:05 ` [10/67] Staging: line6: needs to select SND_PCM Greg KH
2010-08-12  0:05 ` [11/67] Staging: panel: Prevent double-calling of parport_release - fix oops Greg KH
2010-08-12  0:05 ` [12/67] staging: hv: Fix Kconfig dependency of hv_blkvsc Greg KH
2010-08-12  0:05 ` [13/67] serial: add support for OX16PCI958 card Greg KH
2010-08-12  0:05 ` [14/67] PCI: Do not run NVidia quirks related to MSI with MSI disabled Greg KH
2010-08-12  0:05 ` [15/67] PCI: disable MSI on VIA K8M800 Greg KH
2010-08-12  0:05 ` [16/67] solos-pci: Fix race condition in tasklet RX handling Greg KH
2010-08-12  0:05 ` [17/67] x86, mtrr: Use stop machine context to rendezvous all the cpus Greg KH
2010-08-12  0:05 ` [18/67] ALSA: hda - Add PC-beep whitelist for an Intel board Greg KH
2010-08-12  0:05 ` [19/67] Char: nozomi, fix tty->count counting Greg KH
2010-08-12  0:05 ` [20/67] Char: nozomi, set tty->driver_data appropriately Greg KH
2010-08-12  0:05 ` [21/67] mm: fix corruption of hibernation caused by reusing swap during image saving Greg KH
2010-08-12  0:05 ` [22/67] drivers/video/w100fb.c: ignore void return value / fix build failure Greg KH
2010-08-12  0:05 ` [23/67] iwlwifi: fix TX tracer Greg KH
2010-08-12  0:05 ` [24/67] rtl8180: avoid potential NULL deref in rtl8180_beacon_work Greg KH
2010-08-12  0:05 ` [25/67] ipmi: fix ACPI detection with regspacing Greg KH
2010-08-12  0:05 ` [26/67] ide-cd: Do not access completed requests in the irq handler Greg KH
2010-08-12  0:05 ` [27/67] md: move revalidate_disk() back outside open_mutex Greg KH
2010-08-12  0:05 ` [28/67] md: fix another deadlock with removing sysfs attributes Greg KH
2010-08-12  0:05 ` [29/67] md/raid10: fix deadlock with unaligned read during resync Greg KH
2010-08-12  0:05 ` Greg KH [this message]
2010-08-12  0:05 ` [31/67] ioat2: catch and recover from broken vtd configurations v6 Greg KH
2010-08-12  0:05 ` [32/67] Fix sget() race with failing mount Greg KH
2010-08-12  0:05 ` [33/67] blkdev: cgroup whitelist permission fix Greg KH
2010-08-12  0:05 ` [34/67] eCryptfs: Handle ioctl calls with unlocked and compat functions Greg KH
2010-08-12  0:05 ` [35/67] ecryptfs: release reference to lower mount if interpose fails Greg KH
2010-08-12  0:05 ` [36/67] fs/ecryptfs/file.c: introduce missing free Greg KH
2010-08-12  0:05 ` [37/67] drbd: Initialize all members of sync_conf to their defaults [Bugz 315] Greg KH
2010-08-12  0:05 ` [38/67] drbd: Disable delay probes for the upcomming release Greg KH
2010-08-12  3:15   ` [Stable-review] " Ben Hutchings
2010-08-12 10:24     ` Lars Ellenberg
2010-08-12  0:05 ` [39/67] bio, fs: update RWA_MASK, READA and SWRITE to match the corresponding BIO_RW_* bits Greg KH
2010-08-12  0:05 ` [40/67] signalfd: fill in ssi_int for posix timers and message queues Greg KH
2010-08-12  0:05 ` [41/67] [ARM] pxa/cm-x300: fix ffuart registration Greg KH
2010-08-12  0:05 ` [42/67] smsc911x: Add spinlocks around registers access Greg KH
2010-08-12  0:05 ` [43/67] ARM: 6299/1: errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID Greg KH
2010-08-12  0:05 ` [44/67] ARM: 6280/1: imx: Fix build failure when including <mach/gpio.h> without <linux/spinlock.h> Greg KH
2010-08-12  0:06 ` [45/67] USB: musb: use correct register widths in register dumps Greg KH
2010-08-12  0:06 ` [46/67] USB: EHCI: remove PCI assumption Greg KH
2010-08-12  0:06 ` [47/67] USB: resizing usbmon binary interface buffer causes protection faults Greg KH
2010-08-12  0:06 ` [48/67] USB delay init quirk for logitech Harmony 700-series devices Greg KH
2010-08-12  0:06 ` [49/67] USB: serial: enabling support for Segway RMP in ftdi_sio Greg KH
2010-08-12  0:06 ` [50/67] USB: option: Huawei ETS 1220 support added Greg KH
2010-08-12  0:06 ` [51/67] USB: option: add huawei k3765 k4505 devices to work properly Greg KH
2010-08-12  0:06 ` [52/67] USB: ftdi_sio: device id for Navitator Greg KH
2010-08-12  0:06 ` [53/67] USB: cp210x: Add four new device IDs Greg KH
2010-08-12  0:06 ` [54/67] USB: usbtest: avoid to free coherent buffer in atomic context Greg KH
2010-08-12  0:06 ` [55/67] USB: fix thread-unsafe anchor utiliy routines Greg KH
2010-08-12  0:06 ` [56/67] USB: serial: fix stalled writes Greg KH
2010-08-12  0:06 ` [57/67] Bluetooth: Added support for controller shipped with iMac i5 Greg KH
2010-08-12  0:06 ` [58/67] sched: Revert nohz_ratelimit() for now Greg KH
2010-08-12  0:06 ` [59/67] mtd: mxc_nand: fix unbalanced enable for IRQ Greg KH
2010-08-12  0:06 ` [60/67] mtd: gen_nand: fix support for multiple chips Greg KH
2010-08-12  1:07   ` Marek Vasut
2010-08-12  0:06 ` [61/67] l2tp: fix export of header file for userspace Greg KH
2010-08-12  0:06 ` [62/67] jfs: dont allow os2 xattr namespace overlap with others Greg KH
2010-08-12  0:06 ` [63/67] net: Fix NETDEV_NOTIFY_PEERS to not conflict with NETDEV_BONDING_DESLAVE Greg KH
2010-08-12  0:06 ` [64/67] irq: Add new IRQ flag IRQF_NO_SUSPEND Greg KH
2010-08-12  0:06 ` [65/67] xen: Do not suspend IPI IRQs Greg KH
2010-08-12  0:06 ` [66/67] crypto: testmgr - add an option to disable cryptoalgos self-tests Greg KH
2010-08-12  0:06 ` [67/67] ext4: fix freeze deadlock under IO Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100812000615.433588319@clark.site \
    --to=gregkh@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=anton@samba.org \
    --cc=davem@davemloft.net \
    --cc=jeffrey.t.kirsher@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miltonm@bga.com \
    --cc=sonnyrao@us.ibm.com \
    --cc=stable-review@kernel.org \
    --cc=stable@kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).