Skip to content

Commit

Permalink
netxen: 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 salecha authored and David S. Miller committed Apr 11, 2011
1 parent 77c8e2c commit c968bdf
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
4 changes: 2 additions & 2 deletions drivers/net/netxen/netxen_nic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down Expand Up @@ -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;
};

Expand Down
17 changes: 17 additions & 0 deletions drivers/net/netxen/netxen_nic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1844,13 +1844,30 @@ 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;
u32 num_txd = tx_ring->num_desc;

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;

Expand Down

0 comments on commit c968bdf

Please sign in to comment.