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

Commit c968bdf6 authored by amit salecha's avatar amit salecha Committed by David S. Miller
Browse files

netxen: 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 77c8e2c0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@

#define	MAX_NUM_CARDS		4

#define MAX_BUFFERS_PER_CMD	32
#define NETXEN_MAX_FRAGS_PER_TX	14
#define MAX_TSO_HEADER_DESC	2
#define MGMT_CMD_DESC_RESV	4
#define TX_STOP_THRESH		((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \
@@ -558,7 +558,7 @@ struct netxen_recv_crb {
 */
struct netxen_cmd_buffer {
	struct sk_buff *skb;
	struct netxen_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1];
	struct netxen_skb_frag frag_array[MAX_SKB_FRAGS + 1];
	u32 frag_count;
};

+17 −0
Original line number Diff line number Diff line
@@ -1844,6 +1844,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
	struct cmd_desc_type0 *hwdesc, *first_desc;
	struct pci_dev *pdev;
	int i, k;
	int delta = 0;
	struct skb_frag_struct *frag;

	u32 producer;
	int frag_count, no_of_desc;
@@ -1851,6 +1853,21 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)

	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 > NETXEN_MAX_FRAGS_PER_TX) {

		for (i = 0; i < (frag_count - NETXEN_MAX_FRAGS_PER_TX); i++) {
			frag = &skb_shinfo(skb)->frags[i];
			delta += frag->size;
		}

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

		frag_count = 1 + skb_shinfo(skb)->nr_frags;
	}
	/* 4 fragments per cmd des */
	no_of_desc = (frag_count + 3) >> 2;