diff options
author | Santiago Leon <santil@linux.vnet.ibm.com> | 2010-09-03 14:28:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-06 21:20:34 -0400 |
commit | 8d86c61ae41d9068fd5e5cc01a4abd53c4fe3ab5 (patch) | |
tree | ac612e5ddbb624ebb6500334d16b648cc7545471 /drivers/net/ibmveth.c | |
parent | c08cc3ccebd46dce44d13a8ce81d249e687eeb8a (diff) |
ibmveth: Add rx_copybreak
For small packets, create a new skb and copy the packet into it so we
avoid tearing down and creating a TCE entry.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Santiago Leon <santil@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ibmveth.c')
-rw-r--r-- | drivers/net/ibmveth.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index fc6e2cf879c0..c236c8af3367 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -122,6 +122,11 @@ module_param(tx_copybreak, uint, 0644); | |||
122 | MODULE_PARM_DESC(tx_copybreak, | 122 | MODULE_PARM_DESC(tx_copybreak, |
123 | "Maximum size of packet that is copied to a new buffer on transmit"); | 123 | "Maximum size of packet that is copied to a new buffer on transmit"); |
124 | 124 | ||
125 | static unsigned int rx_copybreak __read_mostly = 128; | ||
126 | module_param(rx_copybreak, uint, 0644); | ||
127 | MODULE_PARM_DESC(rx_copybreak, | ||
128 | "Maximum size of packet that is copied to a new buffer on receive"); | ||
129 | |||
125 | struct ibmveth_stat { | 130 | struct ibmveth_stat { |
126 | char name[ETH_GSTRING_LEN]; | 131 | char name[ETH_GSTRING_LEN]; |
127 | int offset; | 132 | int offset; |
@@ -1002,8 +1007,6 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) | |||
1002 | 1007 | ||
1003 | restart_poll: | 1008 | restart_poll: |
1004 | do { | 1009 | do { |
1005 | struct sk_buff *skb; | ||
1006 | |||
1007 | if (!ibmveth_rxq_pending_buffer(adapter)) | 1010 | if (!ibmveth_rxq_pending_buffer(adapter)) |
1008 | break; | 1011 | break; |
1009 | 1012 | ||
@@ -1014,20 +1017,34 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) | |||
1014 | ibmveth_debug_printk("recycling invalid buffer\n"); | 1017 | ibmveth_debug_printk("recycling invalid buffer\n"); |
1015 | ibmveth_rxq_recycle_buffer(adapter); | 1018 | ibmveth_rxq_recycle_buffer(adapter); |
1016 | } else { | 1019 | } else { |
1020 | struct sk_buff *skb, *new_skb; | ||
1017 | int length = ibmveth_rxq_frame_length(adapter); | 1021 | int length = ibmveth_rxq_frame_length(adapter); |
1018 | int offset = ibmveth_rxq_frame_offset(adapter); | 1022 | int offset = ibmveth_rxq_frame_offset(adapter); |
1019 | int csum_good = ibmveth_rxq_csum_good(adapter); | 1023 | int csum_good = ibmveth_rxq_csum_good(adapter); |
1020 | 1024 | ||
1021 | skb = ibmveth_rxq_get_buffer(adapter); | 1025 | skb = ibmveth_rxq_get_buffer(adapter); |
1022 | if (csum_good) | ||
1023 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1024 | 1026 | ||
1025 | ibmveth_rxq_harvest_buffer(adapter); | 1027 | new_skb = NULL; |
1028 | if (length < rx_copybreak) | ||
1029 | new_skb = netdev_alloc_skb(netdev, length); | ||
1030 | |||
1031 | if (new_skb) { | ||
1032 | skb_copy_to_linear_data(new_skb, | ||
1033 | skb->data + offset, | ||
1034 | length); | ||
1035 | skb = new_skb; | ||
1036 | ibmveth_rxq_recycle_buffer(adapter); | ||
1037 | } else { | ||
1038 | ibmveth_rxq_harvest_buffer(adapter); | ||
1039 | skb_reserve(skb, offset); | ||
1040 | } | ||
1026 | 1041 | ||
1027 | skb_reserve(skb, offset); | ||
1028 | skb_put(skb, length); | 1042 | skb_put(skb, length); |
1029 | skb->protocol = eth_type_trans(skb, netdev); | 1043 | skb->protocol = eth_type_trans(skb, netdev); |
1030 | 1044 | ||
1045 | if (csum_good) | ||
1046 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1047 | |||
1031 | netif_receive_skb(skb); /* send it up */ | 1048 | netif_receive_skb(skb); /* send it up */ |
1032 | 1049 | ||
1033 | netdev->stats.rx_packets++; | 1050 | netdev->stats.rx_packets++; |