Commit 4e48d3a1 authored by David S. Miller's avatar David S. Miller

[TIGON3]: Fix slight perf regression from TSO changes.

- Keep cache of previously written vlan_tag value in TX ring.
Avoid the TX descriptor write if they match.
parent d870596f
...@@ -1661,7 +1661,7 @@ static void tg3_tx(struct tg3 *tp) ...@@ -1661,7 +1661,7 @@ static void tg3_tx(struct tg3 *tp)
u32 sw_idx = tp->tx_cons; u32 sw_idx = tp->tx_cons;
while (sw_idx != hw_idx) { while (sw_idx != hw_idx) {
struct ring_info *ri = &tp->tx_buffers[sw_idx]; struct tx_ring_info *ri = &tp->tx_buffers[sw_idx];
struct sk_buff *skb = ri->skb; struct sk_buff *skb = ri->skb;
int i; int i;
...@@ -2286,6 +2286,7 @@ static void tg3_set_txd(struct tg3 *tp, int entry, ...@@ -2286,6 +2286,7 @@ static void tg3_set_txd(struct tg3 *tp, int entry,
txd->len_flags = (len << TXD_LEN_SHIFT) | flags; txd->len_flags = (len << TXD_LEN_SHIFT) | flags;
txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT; txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT;
} else { } else {
struct tx_ring_info *txr = &tp->tx_buffers[entry];
unsigned long txd; unsigned long txd;
txd = (tp->regs + txd = (tp->regs +
...@@ -2301,7 +2302,10 @@ static void tg3_set_txd(struct tg3 *tp, int entry, ...@@ -2301,7 +2302,10 @@ static void tg3_set_txd(struct tg3 *tp, int entry,
writel(((u64) mapping & 0xffffffff), writel(((u64) mapping & 0xffffffff),
txd + TXD_ADDR + TG3_64BIT_REG_LOW); txd + TXD_ADDR + TG3_64BIT_REG_LOW);
writel(len << TXD_LEN_SHIFT | flags, txd + TXD_LEN_FLAGS); writel(len << TXD_LEN_SHIFT | flags, txd + TXD_LEN_FLAGS);
if (txr->prev_vlan_tag != vlan_tag) {
writel(vlan_tag << TXD_VLAN_TAG_SHIFT, txd + TXD_VLAN_TAG); writel(vlan_tag << TXD_VLAN_TAG_SHIFT, txd + TXD_VLAN_TAG);
txr->prev_vlan_tag = vlan_tag;
}
} }
} }
...@@ -2684,7 +2688,7 @@ static void tg3_free_rings(struct tg3 *tp) ...@@ -2684,7 +2688,7 @@ static void tg3_free_rings(struct tg3 *tp)
} }
for (i = 0; i < TG3_TX_RING_SIZE; ) { for (i = 0; i < TG3_TX_RING_SIZE; ) {
struct ring_info *txp; struct tx_ring_info *txp;
struct sk_buff *skb; struct sk_buff *skb;
int j; int j;
...@@ -2751,6 +2755,8 @@ static void tg3_init_rings(struct tg3 *tp) ...@@ -2751,6 +2755,8 @@ static void tg3_init_rings(struct tg3 *tp)
writel(0, start); writel(0, start);
start += 4; start += 4;
} }
for (i = 0; i < TG3_TX_RING_SIZE; i++)
tp->tx_buffers[i].prev_vlan_tag = 0;
} }
/* Initialize invariants of the rings, we only set this /* Initialize invariants of the rings, we only set this
...@@ -2873,12 +2879,13 @@ static void tg3_free_consistent(struct tg3 *tp) ...@@ -2873,12 +2879,13 @@ static void tg3_free_consistent(struct tg3 *tp)
*/ */
static int tg3_alloc_consistent(struct tg3 *tp) static int tg3_alloc_consistent(struct tg3 *tp)
{ {
tp->rx_std_buffers = kmalloc(sizeof(struct ring_info) * tp->rx_std_buffers = kmalloc((sizeof(struct ring_info) *
(TG3_RX_RING_SIZE + (TG3_RX_RING_SIZE +
#if TG3_MINI_RING_WORKS #if TG3_MINI_RING_WORKS
TG3_RX_MINI_RING_SIZE + TG3_RX_MINI_RING_SIZE +
#endif #endif
TG3_RX_JUMBO_RING_SIZE + TG3_RX_JUMBO_RING_SIZE)) +
(sizeof(struct tx_ring_info) *
TG3_TX_RING_SIZE), TG3_TX_RING_SIZE),
GFP_KERNEL); GFP_KERNEL);
if (!tp->rx_std_buffers) if (!tp->rx_std_buffers)
...@@ -2889,14 +2896,16 @@ static int tg3_alloc_consistent(struct tg3 *tp) ...@@ -2889,14 +2896,16 @@ static int tg3_alloc_consistent(struct tg3 *tp)
(sizeof(struct ring_info) * (sizeof(struct ring_info) *
(TG3_RX_RING_SIZE + (TG3_RX_RING_SIZE +
TG3_RX_MINI_RING_SIZE + TG3_RX_MINI_RING_SIZE +
TG3_RX_JUMBO_RING_SIZE + TG3_RX_JUMBO_RING_SIZE)) +
TG3_TX_RING_SIZE))); (sizeof(struct tx_ring_info) *
TG3_TX_RING_SIZE));
#else #else
memset(tp->rx_std_buffers, 0, memset(tp->rx_std_buffers, 0,
(sizeof(struct ring_info) * (sizeof(struct ring_info) *
(TG3_RX_RING_SIZE + (TG3_RX_RING_SIZE +
TG3_RX_JUMBO_RING_SIZE + TG3_RX_JUMBO_RING_SIZE)) +
TG3_TX_RING_SIZE))); (sizeof(struct tx_ring_info) *
TG3_TX_RING_SIZE));
#endif #endif
#if TG3_MINI_RING_WORKS #if TG3_MINI_RING_WORKS
...@@ -2905,7 +2914,8 @@ static int tg3_alloc_consistent(struct tg3 *tp) ...@@ -2905,7 +2914,8 @@ static int tg3_alloc_consistent(struct tg3 *tp)
#else #else
tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE]; tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE];
#endif #endif
tp->tx_buffers = &tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE]; tp->tx_buffers = (struct tx_ring_info *)
&tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE];
tp->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES, tp->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES,
&tp->rx_std_mapping); &tp->rx_std_mapping);
......
...@@ -1666,6 +1666,12 @@ struct ring_info { ...@@ -1666,6 +1666,12 @@ struct ring_info {
DECLARE_PCI_UNMAP_ADDR(mapping) DECLARE_PCI_UNMAP_ADDR(mapping)
}; };
struct tx_ring_info {
struct sk_buff *skb;
DECLARE_PCI_UNMAP_ADDR(mapping)
u32 prev_vlan_tag;
};
struct tg3_config_info { struct tg3_config_info {
u32 flags; u32 flags;
}; };
...@@ -1860,7 +1866,7 @@ struct tg3 { ...@@ -1860,7 +1866,7 @@ struct tg3 {
/* TX descs are only used if TG3_FLAG_HOST_TXDS is set. */ /* TX descs are only used if TG3_FLAG_HOST_TXDS is set. */
struct tg3_tx_buffer_desc *tx_ring; struct tg3_tx_buffer_desc *tx_ring;
struct ring_info *tx_buffers; struct tx_ring_info *tx_buffers;
dma_addr_t tx_desc_mapping; dma_addr_t tx_desc_mapping;
struct tg3_hw_status *hw_status; struct tg3_hw_status *hw_status;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment