diff options
author | Joe Perches <joe@perches.com> | 2010-05-13 15:26:17 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-05-14 03:06:19 -0700 |
commit | 57bf6eef2f43ae810504753208b3a2c0bb2e4765 (patch) | |
tree | 54ea4e292e1a6279139580b7d3e9ea74f3d09c61 /drivers/net/e1000 | |
parent | 621b99b6f6a8ae69ca9b69dec0fec3a68f774bb7 (diff) |
ixgb and e1000: Use new function for copybreak tests
There appears to be an off-by-1 defect in the maximum packet size
copied when copybreak is speified in these modules.
The copybreak module params are specified as:
"Maximum size of packet that is copied to a new buffer on receive"
The tests are changed from "< copybreak" to "<= copybreak"
and moved into new static functions for readability.
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/e1000')
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 5de738a6d0e..ebdea089166 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3785,6 +3785,31 @@ next_desc: return cleaned; } +/* + * this should improve performance for small packets with large amounts + * of reassembly being done in the stack + */ +static void e1000_check_copybreak(struct net_device *netdev, + struct e1000_buffer *buffer_info, + u32 length, struct sk_buff **skb) +{ + struct sk_buff *new_skb; + + if (length > copybreak) + return; + + new_skb = netdev_alloc_skb_ip_align(netdev, length); + if (!new_skb) + return; + + skb_copy_to_linear_data_offset(new_skb, -NET_IP_ALIGN, + (*skb)->data - NET_IP_ALIGN, + length + NET_IP_ALIGN); + /* save the skb in buffer_info as good */ + buffer_info->skb = *skb; + *skb = new_skb; +} + /** * e1000_clean_rx_irq - Send received data up the network stack; legacy * @adapter: board private structure @@ -3883,26 +3908,8 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, total_rx_bytes += length; total_rx_packets++; - /* code added for copybreak, this should improve - * performance for small packets with large amounts - * of reassembly being done in the stack */ - if (length < copybreak) { - struct sk_buff *new_skb = - netdev_alloc_skb_ip_align(netdev, length); - if (new_skb) { - skb_copy_to_linear_data_offset(new_skb, - -NET_IP_ALIGN, - (skb->data - - NET_IP_ALIGN), - (length + - NET_IP_ALIGN)); - /* save the skb in buffer_info as good */ - buffer_info->skb = skb; - skb = new_skb; - } - /* else just continue with the old one */ - } - /* end copybreak code */ + e1000_check_copybreak(netdev, buffer_info, length, &skb); + skb_put(skb, length); /* Receive Checksum Offload */ |