]>
Commit | Line | Data |
---|---|---|
adaf8559 GKH |
1 | From 0a9a17e3bb4564caf4bfe2a6783ae1287667d188 Mon Sep 17 00:00:00 2001 |
2 | From: Brian King <brking@linux.vnet.ibm.com> | |
3 | Date: Fri, 17 Nov 2017 11:05:43 -0600 | |
4 | Subject: ixgbe: Fix skb list corruption on Power systems | |
5 | ||
6 | From: Brian King <brking@linux.vnet.ibm.com> | |
7 | ||
8 | commit 0a9a17e3bb4564caf4bfe2a6783ae1287667d188 upstream. | |
9 | ||
10 | This patch fixes an issue seen on Power systems with ixgbe which results | |
11 | in skb list corruption and an eventual kernel oops. The following is what | |
12 | was observed: | |
13 | ||
14 | CPU 1 CPU2 | |
15 | ============================ ============================ | |
16 | 1: ixgbe_xmit_frame_ring ixgbe_clean_tx_irq | |
17 | 2: first->skb = skb eop_desc = tx_buffer->next_to_watch | |
18 | 3: ixgbe_tx_map read_barrier_depends() | |
19 | 4: wmb check adapter written status bit | |
20 | 5: first->next_to_watch = tx_desc napi_consume_skb(tx_buffer->skb ..); | |
21 | 6: writel(i, tx_ring->tail); | |
22 | ||
23 | The read_barrier_depends is insufficient to ensure that tx_buffer->skb does not | |
24 | get loaded prior to tx_buffer->next_to_watch, which then results in loading | |
25 | a stale skb pointer. This patch replaces the read_barrier_depends with | |
26 | smp_rmb to ensure loads are ordered with respect to the load of | |
27 | tx_buffer->next_to_watch. | |
28 | ||
29 | Signed-off-by: Brian King <brking@linux.vnet.ibm.com> | |
30 | Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com> | |
31 | Tested-by: Andrew Bowers <andrewx.bowers@intel.com> | |
32 | Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> | |
33 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
34 | ||
35 | --- | |
36 | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- | |
37 | 1 file changed, 1 insertion(+), 1 deletion(-) | |
38 | ||
39 | --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |
40 | +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |
41 | @@ -1114,7 +1114,7 @@ static bool ixgbe_clean_tx_irq(struct ix | |
42 | break; | |
43 | ||
44 | /* prevent any other reads prior to eop_desc */ | |
45 | - read_barrier_depends(); | |
46 | + smp_rmb(); | |
47 | ||
48 | /* if DD is not set pending work has not been completed */ | |
49 | if (!(eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD))) |