Skip to content

Commit

Permalink
qlcnic: limit skb frags for non tso packet
Browse files Browse the repository at this point in the history
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: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Amit Kumar Salecha authored and David S. Miller committed Apr 13, 2011
1 parent 7c9f647 commit 91a403c
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/net/qlcnic/qlcnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
#define TX_UDPV6_PKT 0x0c

/* Tx defines */
#define QLCNIC_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 \
Expand Down
14 changes: 14 additions & 0 deletions drivers/net/qlcnic/qlcnic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2099,6 +2099,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
struct cmd_desc_type0 *hwdesc, *first_desc;
struct pci_dev *pdev;
struct ethhdr *phdr;
int delta = 0;
int i, k;

u32 producer;
Expand All @@ -2118,6 +2119,19 @@ qlcnic_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 > 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 */
no_of_desc = (frag_count + 3) >> 2;
Expand Down

0 comments on commit 91a403c

Please sign in to comment.