Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ixgbe: DCB, fix TX hang occurring in stress condition with PFC

The DCB credits refill quantum _must_ be greater than half the max
packet size. This is needed to guarantee that TX DMA operations
are not attempted during a pause state. Additionally, the min IFG
must be set correctly for DCB mode. If a DMA operation is
requested unexpectedly during the pause state the HW data
store may be corrupted leading to a DMA hang. The DMA hang
requires a reset to correct. This fixes the HW configuration
to avoid this condition.

Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

John Fastabend and committed by
David S. Miller
9806307a affa9dfb

+54 -10
+34 -5
drivers/net/ixgbe/ixgbe_dcb.c
··· 43 43 * ixgbe_dcb_check_config(). 44 44 */ 45 45 s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, 46 - u8 direction) 46 + int max_frame, u8 direction) 47 47 { 48 48 struct tc_bw_alloc *p; 49 + int min_credit; 50 + int min_multiplier; 51 + int min_percent = 100; 49 52 s32 ret_val = 0; 50 53 /* Initialization values default for Tx settings */ 51 54 u32 credit_refill = 0; ··· 61 58 ret_val = DCB_ERR_CONFIG; 62 59 goto out; 63 60 } 61 + 62 + min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) / 63 + DCB_CREDIT_QUANTUM; 64 + 65 + /* Find smallest link percentage */ 66 + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { 67 + p = &dcb_config->tc_config[i].path[direction]; 68 + bw_percent = dcb_config->bw_percentage[direction][p->bwg_id]; 69 + link_percentage = p->bwg_percent; 70 + 71 + link_percentage = (link_percentage * bw_percent) / 100; 72 + 73 + if (link_percentage && link_percentage < min_percent) 74 + min_percent = link_percentage; 75 + } 76 + 77 + /* 78 + * The ratio between traffic classes will control the bandwidth 79 + * percentages seen on the wire. To calculate this ratio we use 80 + * a multiplier. It is required that the refill credits must be 81 + * larger than the max frame size so here we find the smallest 82 + * multiplier that will allow all bandwidth percentages to be 83 + * greater than the max frame size. 84 + */ 85 + min_multiplier = (min_credit / min_percent) + 1; 64 86 65 87 /* Find out the link percentage for each TC first */ 66 88 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { ··· 101 73 /* Save link_percentage for reference */ 102 74 p->link_percent = (u8)link_percentage; 103 75 104 - /* Calculate credit refill and save it */ 105 - credit_refill = link_percentage * MINIMUM_CREDIT_REFILL; 76 + /* Calculate credit refill ratio using multiplier */ 77 + credit_refill = min(link_percentage * min_multiplier, 78 + MAX_CREDIT_REFILL); 106 79 p->data_credits_refill = (u16)credit_refill; 107 80 108 81 /* Calculate maximum credit for the TC */ ··· 114 85 * of a TC is too small, the maximum credit may not be 115 86 * enough to send out a jumbo frame in data plane arbitration. 116 87 */ 117 - if (credit_max && (credit_max < MINIMUM_CREDIT_FOR_JUMBO)) 118 - credit_max = MINIMUM_CREDIT_FOR_JUMBO; 88 + if (credit_max && (credit_max < min_credit)) 89 + credit_max = min_credit; 119 90 120 91 if (direction == DCB_TX_CONFIG) { 121 92 /*
+2 -3
drivers/net/ixgbe/ixgbe_dcb.h
··· 150 150 /* DCB driver APIs */ 151 151 152 152 /* DCB credits calculation */ 153 - s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, u8); 153 + s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, int, u8); 154 154 155 155 /* DCB hw initialization */ 156 156 s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *); 157 157 158 158 /* DCB definitions for credit calculation */ 159 + #define DCB_CREDIT_QUANTUM 64 /* DCB Quantum */ 159 160 #define MAX_CREDIT_REFILL 511 /* 0x1FF * 64B = 32704B */ 160 - #define MINIMUM_CREDIT_REFILL 5 /* 5*64B = 320B */ 161 - #define MINIMUM_CREDIT_FOR_JUMBO 145 /* 145= UpperBound((9*1024+54)/64B) for 9KB jumbo frame */ 162 161 #define DCB_MAX_TSO_SIZE (32*1024) /* MAX TSO packet size supported in DCB mode */ 163 162 #define MINIMUM_CREDIT_FOR_TSO (DCB_MAX_TSO_SIZE/64 + 1) /* 513 for 32KB TSO packet */ 164 163 #define MAX_CREDIT 4095 /* Maximum credit supported: 256KB * 1204 / 64B */
+5
drivers/net/ixgbe/ixgbe_dcb_82599.c
··· 397 397 reg &= ~IXGBE_RTTDCS_ARBDIS; 398 398 IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg); 399 399 400 + /* Enable Security TX Buffer IFG for DCB */ 401 + reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG); 402 + reg |= IXGBE_SECTX_DCB; 403 + IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg); 404 + 400 405 return 0; 401 406 } 402 407
+3
drivers/net/ixgbe/ixgbe_dcb_82599.h
··· 95 95 96 96 #define IXGBE_TXPBTHRESH_DCB 0xA /* THRESH value for DCB mode */ 97 97 98 + /* SECTXMINIFG DCB */ 99 + #define IXGBE_SECTX_DCB 0x00001F00 /* DCB TX Buffer IFG */ 100 + 98 101 99 102 /* DCB hardware-specific driver APIs */ 100 103
+10 -2
drivers/net/ixgbe/ixgbe_main.c
··· 3347 3347 static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) 3348 3348 { 3349 3349 struct ixgbe_hw *hw = &adapter->hw; 3350 + int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; 3350 3351 u32 txdctl; 3351 3352 int i, j; 3352 3353 ··· 3360 3359 if (hw->mac.type == ixgbe_mac_82598EB) 3361 3360 netif_set_gso_max_size(adapter->netdev, 32768); 3362 3361 3363 - ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_TX_CONFIG); 3364 - ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_RX_CONFIG); 3362 + #ifdef CONFIG_FCOE 3363 + if (adapter->netdev->features & NETIF_F_FCOE_MTU) 3364 + max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); 3365 + #endif 3366 + 3367 + ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame, 3368 + DCB_TX_CONFIG); 3369 + ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame, 3370 + DCB_RX_CONFIG); 3365 3371 3366 3372 /* reconfigure the hardware */ 3367 3373 ixgbe_dcb_hw_config(&adapter->hw, &adapter->dcb_cfg);