Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91a403ca authored by Amit Kumar Salecha's avatar Amit Kumar Salecha Committed by David S. Miller
Browse files

qlcnic: limit skb frags for non tso packet



Machines are getting deadlock in four node cluster environment.
All nodes are accessing (find /gfs2 -depth -print|cpio -ocv > /dev/null)
200 GB storage on a GFS2 filesystem.
This result in memory fragmentation and driver receives 18 frags for
1448 byte packets.
For non tso packet, fw drops the tx request, if it has >14 frags.

Fixing it by pulling extra frags.

Cc: stable@kernel.org
Signed-off-by: default avatarAmit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7c9f6472
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -99,6 +99,7 @@
#define TX_UDPV6_PKT	0x0c
#define TX_UDPV6_PKT	0x0c


/* Tx defines */
/* Tx defines */
#define QLCNIC_MAX_FRAGS_PER_TX	14
#define MAX_TSO_HEADER_DESC	2
#define MAX_TSO_HEADER_DESC	2
#define MGMT_CMD_DESC_RESV	4
#define MGMT_CMD_DESC_RESV	4
#define TX_STOP_THRESH		((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \
#define TX_STOP_THRESH		((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \
+14 −0
Original line number Original line Diff line number Diff line
@@ -2099,6 +2099,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
	struct cmd_desc_type0 *hwdesc, *first_desc;
	struct cmd_desc_type0 *hwdesc, *first_desc;
	struct pci_dev *pdev;
	struct pci_dev *pdev;
	struct ethhdr *phdr;
	struct ethhdr *phdr;
	int delta = 0;
	int i, k;
	int i, k;


	u32 producer;
	u32 producer;
@@ -2118,6 +2119,19 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
	}
	}


	frag_count = skb_shinfo(skb)->nr_frags + 1;
	frag_count = skb_shinfo(skb)->nr_frags + 1;
	/* 14 frags supported for normal packet and
	 * 32 frags supported for TSO packet
	 */
	if (!skb_is_gso(skb) && frag_count > QLCNIC_MAX_FRAGS_PER_TX) {

		for (i = 0; i < (frag_count - QLCNIC_MAX_FRAGS_PER_TX); i++)
			delta += skb_shinfo(skb)->frags[i].size;

		if (!__pskb_pull_tail(skb, delta))
			goto drop_packet;

		frag_count = 1 + skb_shinfo(skb)->nr_frags;
	}


	/* 4 fragments per cmd des */
	/* 4 fragments per cmd des */
	no_of_desc = (frag_count + 3) >> 2;
	no_of_desc = (frag_count + 3) >> 2;