]> Pileus Git - ~andy/linux/commitdiff
igb: Improve performance and reduce size of igb_tx_map
authorAlexander Duyck <alexander.h.duyck@intel.com>
Tue, 13 Nov 2012 04:03:24 +0000 (04:03 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 13 Nov 2012 19:18:15 +0000 (14:18 -0500)
This change is meant to both improve the performance and reduce the size of
igb_tx_map.  To do this I have expanded the work done in the main loop by
pushing first into tx_buffer.  This allows us to pull in the dma_mapping_error
check, the tx_buffer value assignment, and the initial DMA value assignment to
the Tx descriptor.  The net result is that the function reduces in size by a
little over a 100 bytes and is about 1% or 2% faster.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/intel/igb/igb_main.c

index 0a0bd819d95b437c6191e12f2ea52e3e161b0061..7044aaadeca1edaacc6435aa07fd2a4dc2606c7f 100644 (file)
@@ -4188,29 +4188,34 @@ static void igb_tx_map(struct igb_ring *tx_ring,
        struct sk_buff *skb = first->skb;
        struct igb_tx_buffer *tx_buffer;
        union e1000_adv_tx_desc *tx_desc;
+       struct skb_frag_struct *frag;
        dma_addr_t dma;
-       struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0];
-       unsigned int data_len = skb->data_len;
-       unsigned int size = skb_headlen(skb);
-       unsigned int paylen = skb->len - hdr_len;
+       unsigned int data_len, size;
        u32 tx_flags = first->tx_flags;
        u32 cmd_type = igb_tx_cmd_type(skb, tx_flags);
        u16 i = tx_ring->next_to_use;
 
        tx_desc = IGB_TX_DESC(tx_ring, i);
 
-       igb_tx_olinfo_status(tx_ring, tx_desc, tx_flags, paylen);
+       igb_tx_olinfo_status(tx_ring, tx_desc, tx_flags, skb->len - hdr_len);
+
+       size = skb_headlen(skb);
+       data_len = skb->data_len;
 
        dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE);
-       if (dma_mapping_error(tx_ring->dev, dma))
-               goto dma_error;
 
-       /* record length, and DMA address */
-       dma_unmap_len_set(first, len, size);
-       dma_unmap_addr_set(first, dma, dma);
-       tx_desc->read.buffer_addr = cpu_to_le64(dma);
+       tx_buffer = first;
+
+       for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
+               if (dma_mapping_error(tx_ring->dev, dma))
+                       goto dma_error;
+
+               /* record length, and DMA address */
+               dma_unmap_len_set(tx_buffer, len, size);
+               dma_unmap_addr_set(tx_buffer, dma, dma);
+
+               tx_desc->read.buffer_addr = cpu_to_le64(dma);
 
-       for (;;) {
                while (unlikely(size > IGB_MAX_DATA_PER_TXD)) {
                        tx_desc->read.cmd_type_len =
                                cpu_to_le32(cmd_type ^ IGB_MAX_DATA_PER_TXD);
@@ -4221,11 +4226,11 @@ static void igb_tx_map(struct igb_ring *tx_ring,
                                tx_desc = IGB_TX_DESC(tx_ring, 0);
                                i = 0;
                        }
+                       tx_desc->read.olinfo_status = 0;
 
                        dma += IGB_MAX_DATA_PER_TXD;
                        size -= IGB_MAX_DATA_PER_TXD;
 
-                       tx_desc->read.olinfo_status = 0;
                        tx_desc->read.buffer_addr = cpu_to_le64(dma);
                }
 
@@ -4240,31 +4245,23 @@ static void igb_tx_map(struct igb_ring *tx_ring,
                        tx_desc = IGB_TX_DESC(tx_ring, 0);
                        i = 0;
                }
+               tx_desc->read.olinfo_status = 0;
 
                size = skb_frag_size(frag);
                data_len -= size;
 
                dma = skb_frag_dma_map(tx_ring->dev, frag, 0,
-                                  size, DMA_TO_DEVICE);
-               if (dma_mapping_error(tx_ring->dev, dma))
-                       goto dma_error;
+                                      size, DMA_TO_DEVICE);
 
                tx_buffer = &tx_ring->tx_buffer_info[i];
-               dma_unmap_len_set(tx_buffer, len, size);
-               dma_unmap_addr_set(tx_buffer, dma, dma);
-
-               tx_desc->read.olinfo_status = 0;
-               tx_desc->read.buffer_addr = cpu_to_le64(dma);
-
-               frag++;
        }
 
-       netdev_tx_sent_queue(txring_txq(tx_ring), first->bytecount);
-
        /* write last descriptor with RS and EOP bits */
        cmd_type |= size | IGB_TXD_DCMD;
        tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type);
 
+       netdev_tx_sent_queue(txring_txq(tx_ring), first->bytecount);
+
        /* set the timestamp */
        first->time_stamp = jiffies;