diff options
author | Santiago Leon <santil@linux.vnet.ibm.com> | 2010-09-03 14:28:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-06 21:20:33 -0400 |
commit | c08cc3ccebd46dce44d13a8ce81d249e687eeb8a (patch) | |
tree | 1e44318be42fbbef6c6cc224c9d4a2adafef4e98 /drivers/net/ibmveth.c | |
parent | e8cb7eb473ac47703282db6f90b4926f31cdf376 (diff) |
ibmveth: Add tx_copybreak
Use the existing bounce buffer if we send a buffer under a certain size.
This saves the overhead of a TCE map/unmap.
I can't see any reason for the wmb() in the bounce buffer case, if we need
a barrier it will be before we call h_send_logical_lan but we have
nothing in the common case. Remove it.
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 | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 9d662dec21b0..fc6e2cf879c0 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -117,6 +117,11 @@ MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver"); | |||
117 | MODULE_LICENSE("GPL"); | 117 | MODULE_LICENSE("GPL"); |
118 | MODULE_VERSION(ibmveth_driver_version); | 118 | MODULE_VERSION(ibmveth_driver_version); |
119 | 119 | ||
120 | static unsigned int tx_copybreak __read_mostly = 128; | ||
121 | module_param(tx_copybreak, uint, 0644); | ||
122 | MODULE_PARM_DESC(tx_copybreak, | ||
123 | "Maximum size of packet that is copied to a new buffer on transmit"); | ||
124 | |||
120 | struct ibmveth_stat { | 125 | struct ibmveth_stat { |
121 | char name[ETH_GSTRING_LEN]; | 126 | char name[ETH_GSTRING_LEN]; |
122 | int offset; | 127 | int offset; |
@@ -931,17 +936,24 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, | |||
931 | buf[1] = 0; | 936 | buf[1] = 0; |
932 | } | 937 | } |
933 | 938 | ||
934 | data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, | 939 | if (skb->len < tx_copybreak) { |
935 | skb->len, DMA_TO_DEVICE); | 940 | used_bounce = 1; |
936 | if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) { | 941 | } else { |
937 | if (!firmware_has_feature(FW_FEATURE_CMO)) | 942 | data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, |
938 | ibmveth_error_printk("tx: unable to map xmit buffer\n"); | 943 | skb->len, DMA_TO_DEVICE); |
944 | if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) { | ||
945 | if (!firmware_has_feature(FW_FEATURE_CMO)) | ||
946 | ibmveth_error_printk("tx: unable to map " | ||
947 | "xmit buffer\n"); | ||
948 | tx_map_failed++; | ||
949 | used_bounce = 1; | ||
950 | } | ||
951 | } | ||
952 | |||
953 | if (used_bounce) { | ||
939 | skb_copy_from_linear_data(skb, adapter->bounce_buffer, | 954 | skb_copy_from_linear_data(skb, adapter->bounce_buffer, |
940 | skb->len); | 955 | skb->len); |
941 | desc.fields.address = adapter->bounce_buffer_dma; | 956 | desc.fields.address = adapter->bounce_buffer_dma; |
942 | tx_map_failed++; | ||
943 | used_bounce = 1; | ||
944 | wmb(); | ||
945 | } else | 957 | } else |
946 | desc.fields.address = data_dma_addr; | 958 | desc.fields.address = data_dma_addr; |
947 | 959 | ||