| From 0a9a17e3bb4564caf4bfe2a6783ae1287667d188 Mon Sep 17 00:00:00 2001 |
| From: Brian King <brking@linux.vnet.ibm.com> |
| Date: Fri, 17 Nov 2017 11:05:43 -0600 |
| Subject: ixgbe: Fix skb list corruption on Power systems |
| |
| From: Brian King <brking@linux.vnet.ibm.com> |
| |
| commit 0a9a17e3bb4564caf4bfe2a6783ae1287667d188 upstream. |
| |
| This patch fixes an issue seen on Power systems with ixgbe which results |
| in skb list corruption and an eventual kernel oops. The following is what |
| was observed: |
| |
| CPU 1 CPU2 |
| ============================ ============================ |
| 1: ixgbe_xmit_frame_ring ixgbe_clean_tx_irq |
| 2: first->skb = skb eop_desc = tx_buffer->next_to_watch |
| 3: ixgbe_tx_map read_barrier_depends() |
| 4: wmb check adapter written status bit |
| 5: first->next_to_watch = tx_desc napi_consume_skb(tx_buffer->skb ..); |
| 6: writel(i, tx_ring->tail); |
| |
| The read_barrier_depends is insufficient to ensure that tx_buffer->skb does not |
| get loaded prior to tx_buffer->next_to_watch, which then results in loading |
| a stale skb pointer. This patch replaces the read_barrier_depends with |
| smp_rmb to ensure loads are ordered with respect to the load of |
| tx_buffer->next_to_watch. |
| |
| Signed-off-by: Brian King <brking@linux.vnet.ibm.com> |
| Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com> |
| Tested-by: Andrew Bowers <andrewx.bowers@intel.com> |
| Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |
| +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |
| @@ -1080,7 +1080,7 @@ static bool ixgbe_clean_tx_irq(struct ix |
| break; |
| |
| /* prevent any other reads prior to eop_desc */ |
| - read_barrier_depends(); |
| + smp_rmb(); |
| |
| /* if DD is not set pending work has not been completed */ |
| if (!(eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD))) |