ibmveth: Add tx_copybreak
Santiago Leon [Fri, 3 Sep 2010 18:28:20 +0000 (18:28 +0000)]
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>

drivers/net/ibmveth.c

index 9d662de..fc6e2cf 100644 (file)
@@ -117,6 +117,11 @@ MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(ibmveth_driver_version);
 
+static unsigned int tx_copybreak __read_mostly = 128;
+module_param(tx_copybreak, uint, 0644);
+MODULE_PARM_DESC(tx_copybreak,
+       "Maximum size of packet that is copied to a new buffer on transmit");
+
 struct ibmveth_stat {
        char name[ETH_GSTRING_LEN];
        int offset;
@@ -931,17 +936,24 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb,
                buf[1] = 0;
        }
 
-       data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
-                                      skb->len, DMA_TO_DEVICE);
-       if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) {
-               if (!firmware_has_feature(FW_FEATURE_CMO))
-                       ibmveth_error_printk("tx: unable to map xmit buffer\n");
+       if (skb->len < tx_copybreak) {
+               used_bounce = 1;
+       } else {
+               data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
+                                              skb->len, DMA_TO_DEVICE);
+               if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) {
+                       if (!firmware_has_feature(FW_FEATURE_CMO))
+                               ibmveth_error_printk("tx: unable to map "
+                                                    "xmit buffer\n");
+                       tx_map_failed++;
+                       used_bounce = 1;
+               }
+       }
+
+       if (used_bounce) {
                skb_copy_from_linear_data(skb, adapter->bounce_buffer,
                                          skb->len);
                desc.fields.address = adapter->bounce_buffer_dma;
-               tx_map_failed++;
-               used_bounce = 1;
-               wmb();
        } else
                desc.fields.address = data_dma_addr;