diff options
author | amit salecha <amit.salecha@qlogic.com> | 2011-04-10 22:10:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-11 16:15:57 -0400 |
commit | c968bdf6912cad6d0fc63d7037cc1c870604a808 (patch) | |
tree | a2a10926aa0ddac61b30c168d29c487845aacd36 /drivers/net/netxen | |
parent | 77c8e2c01542649f7a02fef8eb3b3d0e7fed6bbd (diff) |
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: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 4 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 17 |
2 files changed, 19 insertions, 2 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index d7299f1a4940..679dc8519c5b 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -174,7 +174,7 @@ | |||
174 | 174 | ||
175 | #define MAX_NUM_CARDS 4 | 175 | #define MAX_NUM_CARDS 4 |
176 | 176 | ||
177 | #define MAX_BUFFERS_PER_CMD 32 | 177 | #define NETXEN_MAX_FRAGS_PER_TX 14 |
178 | #define MAX_TSO_HEADER_DESC 2 | 178 | #define MAX_TSO_HEADER_DESC 2 |
179 | #define MGMT_CMD_DESC_RESV 4 | 179 | #define MGMT_CMD_DESC_RESV 4 |
180 | #define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \ | 180 | #define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \ |
@@ -558,7 +558,7 @@ struct netxen_recv_crb { | |||
558 | */ | 558 | */ |
559 | struct netxen_cmd_buffer { | 559 | struct netxen_cmd_buffer { |
560 | struct sk_buff *skb; | 560 | struct sk_buff *skb; |
561 | struct netxen_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1]; | 561 | struct netxen_skb_frag frag_array[MAX_SKB_FRAGS + 1]; |
562 | u32 frag_count; | 562 | u32 frag_count; |
563 | }; | 563 | }; |
564 | 564 | ||
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 83348dc4b184..e8a4b6655999 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -1844,6 +1844,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1844 | struct cmd_desc_type0 *hwdesc, *first_desc; | 1844 | struct cmd_desc_type0 *hwdesc, *first_desc; |
1845 | struct pci_dev *pdev; | 1845 | struct pci_dev *pdev; |
1846 | int i, k; | 1846 | int i, k; |
1847 | int delta = 0; | ||
1848 | struct skb_frag_struct *frag; | ||
1847 | 1849 | ||
1848 | u32 producer; | 1850 | u32 producer; |
1849 | int frag_count, no_of_desc; | 1851 | int frag_count, no_of_desc; |
@@ -1851,6 +1853,21 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1851 | 1853 | ||
1852 | frag_count = skb_shinfo(skb)->nr_frags + 1; | 1854 | frag_count = skb_shinfo(skb)->nr_frags + 1; |
1853 | 1855 | ||
1856 | /* 14 frags supported for normal packet and | ||
1857 | * 32 frags supported for TSO packet | ||
1858 | */ | ||
1859 | if (!skb_is_gso(skb) && frag_count > NETXEN_MAX_FRAGS_PER_TX) { | ||
1860 | |||
1861 | for (i = 0; i < (frag_count - NETXEN_MAX_FRAGS_PER_TX); i++) { | ||
1862 | frag = &skb_shinfo(skb)->frags[i]; | ||
1863 | delta += frag->size; | ||
1864 | } | ||
1865 | |||
1866 | if (!__pskb_pull_tail(skb, delta)) | ||
1867 | goto drop_packet; | ||
1868 | |||
1869 | frag_count = 1 + skb_shinfo(skb)->nr_frags; | ||
1870 | } | ||
1854 | /* 4 fragments per cmd des */ | 1871 | /* 4 fragments per cmd des */ |
1855 | no_of_desc = (frag_count + 3) >> 2; | 1872 | no_of_desc = (frag_count + 3) >> 2; |
1856 | 1873 | ||