diff options
author | Amit Kumar Salecha <amit.salecha@qlogic.com> | 2011-04-12 13:05:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-13 14:53:11 -0400 |
commit | 91a403caf0f26c71ce4407fd235b2d6fb225fba9 (patch) | |
tree | 9c542d7ab98275d87e32eb97056025a14b520b16 /drivers/net/qlcnic | |
parent | 7c9f6472d46d07000c197e1d24fa2a332606968e (diff) |
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: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlcnic')
-rw-r--r-- | drivers/net/qlcnic/qlcnic.h | 1 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 14 |
2 files changed, 15 insertions, 0 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index dc44564ef6f9..b0dead00b2d1 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h | |||
@@ -99,6 +99,7 @@ | |||
99 | #define TX_UDPV6_PKT 0x0c | 99 | #define TX_UDPV6_PKT 0x0c |
100 | 100 | ||
101 | /* Tx defines */ | 101 | /* Tx defines */ |
102 | #define QLCNIC_MAX_FRAGS_PER_TX 14 | ||
102 | #define MAX_TSO_HEADER_DESC 2 | 103 | #define MAX_TSO_HEADER_DESC 2 |
103 | #define MGMT_CMD_DESC_RESV 4 | 104 | #define MGMT_CMD_DESC_RESV 4 |
104 | #define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \ | 105 | #define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \ |
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index cd88c7e1bfa9..cb1a1ef36c0a 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -2099,6 +2099,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2099 | struct cmd_desc_type0 *hwdesc, *first_desc; | 2099 | struct cmd_desc_type0 *hwdesc, *first_desc; |
2100 | struct pci_dev *pdev; | 2100 | struct pci_dev *pdev; |
2101 | struct ethhdr *phdr; | 2101 | struct ethhdr *phdr; |
2102 | int delta = 0; | ||
2102 | int i, k; | 2103 | int i, k; |
2103 | 2104 | ||
2104 | u32 producer; | 2105 | u32 producer; |
@@ -2118,6 +2119,19 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2118 | } | 2119 | } |
2119 | 2120 | ||
2120 | frag_count = skb_shinfo(skb)->nr_frags + 1; | 2121 | frag_count = skb_shinfo(skb)->nr_frags + 1; |
2122 | /* 14 frags supported for normal packet and | ||
2123 | * 32 frags supported for TSO packet | ||
2124 | */ | ||
2125 | if (!skb_is_gso(skb) && frag_count > QLCNIC_MAX_FRAGS_PER_TX) { | ||
2126 | |||
2127 | for (i = 0; i < (frag_count - QLCNIC_MAX_FRAGS_PER_TX); i++) | ||
2128 | delta += skb_shinfo(skb)->frags[i].size; | ||
2129 | |||
2130 | if (!__pskb_pull_tail(skb, delta)) | ||
2131 | goto drop_packet; | ||
2132 | |||
2133 | frag_count = 1 + skb_shinfo(skb)->nr_frags; | ||
2134 | } | ||
2121 | 2135 | ||
2122 | /* 4 fragments per cmd des */ | 2136 | /* 4 fragments per cmd des */ |
2123 | no_of_desc = (frag_count + 3) >> 2; | 2137 | no_of_desc = (frag_count + 3) >> 2; |