mirror of https://gitee.com/openkylin/linux.git
bnx2x: Prevent FW assertion when using Vxlan
FW has a rare corner case in which a fragmented packet using lots of frags would not be linearized, causing the FW to assert while trying to transmit the packet. To prevent this, we need to make sure the window of fragements containing MSS worth of data contains 1 BD less than for regular packets due to the additional parsing BD. Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com> Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6d3c348a63
commit
ea2465af3b
|
@ -3430,25 +3430,29 @@ static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
|
/* VXLAN: 4 = 1 (for linear data BD) + 3 (2 for PBD and last BD) */
|
||||||
|
#define BNX2X_NUM_VXLAN_TSO_WIN_SUB_BDS 4
|
||||||
|
|
||||||
|
/* Regular: 3 = 1 (for linear data BD) + 2 (for PBD and last BD) */
|
||||||
|
#define BNX2X_NUM_TSO_WIN_SUB_BDS 3
|
||||||
|
|
||||||
|
#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - BDS_PER_TX_PKT)
|
||||||
/* check if packet requires linearization (packet is too fragmented)
|
/* check if packet requires linearization (packet is too fragmented)
|
||||||
no need to check fragmentation if page size > 8K (there will be no
|
no need to check fragmentation if page size > 8K (there will be no
|
||||||
violation to FW restrictions) */
|
violation to FW restrictions) */
|
||||||
static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
|
static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
|
||||||
u32 xmit_type)
|
u32 xmit_type)
|
||||||
{
|
{
|
||||||
int to_copy = 0;
|
int first_bd_sz = 0, num_tso_win_sub = BNX2X_NUM_TSO_WIN_SUB_BDS;
|
||||||
int hlen = 0;
|
int to_copy = 0, hlen = 0;
|
||||||
int first_bd_sz = 0;
|
|
||||||
|
|
||||||
/* 3 = 1 (for linear data BD) + 2 (for PBD and last BD) */
|
if (xmit_type & XMIT_GSO_ENC)
|
||||||
if (skb_shinfo(skb)->nr_frags >= (MAX_FETCH_BD - 3)) {
|
num_tso_win_sub = BNX2X_NUM_VXLAN_TSO_WIN_SUB_BDS;
|
||||||
|
|
||||||
|
if (skb_shinfo(skb)->nr_frags >= (MAX_FETCH_BD - num_tso_win_sub)) {
|
||||||
if (xmit_type & XMIT_GSO) {
|
if (xmit_type & XMIT_GSO) {
|
||||||
unsigned short lso_mss = skb_shinfo(skb)->gso_size;
|
unsigned short lso_mss = skb_shinfo(skb)->gso_size;
|
||||||
/* Check if LSO packet needs to be copied:
|
int wnd_size = MAX_FETCH_BD - num_tso_win_sub;
|
||||||
3 = 1 (for headers BD) + 2 (for PBD and last BD) */
|
|
||||||
int wnd_size = MAX_FETCH_BD - 3;
|
|
||||||
/* Number of windows to check */
|
/* Number of windows to check */
|
||||||
int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size;
|
int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size;
|
||||||
int wnd_idx = 0;
|
int wnd_idx = 0;
|
||||||
|
|
Loading…
Reference in New Issue