diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2013-08-12 17:26:00 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2013-08-12 17:26:00 +0000 |
commit | 63f7150fc3167cbf96d36454e44aed4863433f5e (patch) | |
tree | 54186c62c68b8948acb074592c006aff3ec0b096 /target/linux | |
parent | 7497c864c85b19638c99912089362e7fe2ad239f (diff) |
ar71xx: ethernet: cache skb->len in the tx function to avoid accessing it again in completion
Improves ethernet performance, especially during bridging
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@37761 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux')
-rw-r--r-- | target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h | 7 | ||||
-rw-r--r-- | target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c | 8 |
2 files changed, 10 insertions, 5 deletions
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h index b9d95adaf6..6d51e722b0 100644 --- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h @@ -91,8 +91,11 @@ struct ag71xx_buf { void *rx_buf; }; struct ag71xx_desc *desc; - dma_addr_t dma_addr; - unsigned long timestamp; + union { + dma_addr_t dma_addr; + unsigned long timestamp; + }; + unsigned int len; }; struct ag71xx_ring { diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c index 93071690e8..fc6be0e001 100644 --- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c @@ -145,7 +145,7 @@ static void ag71xx_ring_tx_clean(struct ag71xx *ag) } if (ring->buf[i].skb) { - bytes_compl += ring->buf[i].skb->len; + bytes_compl += ring->buf[i].len; pkts_compl++; dev_kfree_skb_any(ring->buf[i].skb); } @@ -684,6 +684,7 @@ static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb, DMA_TO_DEVICE); netdev_sent_queue(dev, skb->len); + ring->buf[i].len = skb->len; ring->buf[i].skb = skb; ring->buf[i].timestamp = jiffies; @@ -824,6 +825,7 @@ static int ag71xx_tx_packets(struct ag71xx *ag) unsigned int i = ring->dirty % ring->size; struct ag71xx_desc *desc = ring->buf[i].desc; struct sk_buff *skb = ring->buf[i].skb; + int len = ring->buf[i].len; if (!ag71xx_desc_empty(desc)) { if (pdata->is_ar7240 && @@ -834,8 +836,8 @@ static int ag71xx_tx_packets(struct ag71xx *ag) ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); - bytes_compl += skb->len; - ag->dev->stats.tx_bytes += skb->len; + bytes_compl += len; + ag->dev->stats.tx_bytes += len; ag->dev->stats.tx_packets++; dev_kfree_skb_any(skb); |