From: Rob Herring <hidden> Date: 2012-11-05 16:22:38
From: Rob Herring <redacted>
This is a series of performance improvements to the xgmac driver. The
most significant changes are the alignment fixes to avoid alignment
traps on received frames and using raw i/o accessors.
v3:
- Only patch 3 changed. Use raw i/o accessors instead of relaxed for
better build coverage.
v2:
- Only patch 5 changed. Add a missing enabling of tx irq.
Rob
Rob Herring (6):
net: calxedaxgmac: enable operate on 2nd frame mode
net: calxedaxgmac: remove explicit rx dma buffer polling
net: calxedaxgmac: use raw i/o accessors in rx and tx paths
net: calxedaxgmac: drop some unnecessary register writes
net: calxedaxgmac: rework transmit ring handling
net: calxedaxgmac: ip align receive buffers
drivers/net/ethernet/calxeda/xgmac.c | 59 +++++++++++++++-------------------
1 file changed, 26 insertions(+), 33 deletions(-)
--
1.7.10.4
From: Rob Herring <hidden> Date: 2012-11-05 16:22:40
From: Rob Herring <redacted>
Enable the tx dma to start reading the next frame while sending the current
frame.
Signed-off-by: Rob Herring <redacted>
---
drivers/net/ethernet/calxeda/xgmac.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
@@ -965,8 +966,7 @@ static int xgmac_hw_init(struct net_device *dev)ctrl|=XGMAC_CONTROL_IPC;writel(ctrl,ioaddr+XGMAC_CONTROL);-value=DMA_CONTROL_DFF;-writel(value,ioaddr+XGMAC_DMA_CONTROL);+writel(DMA_CONTROL_DFF|DMA_CONTROL_OSF,ioaddr+XGMAC_DMA_CONTROL);/* Set the HW DMA mode and the COE */writel(XGMAC_OMR_TSF|XGMAC_OMR_RFD|XGMAC_OMR_RFA|
From: Rob Herring <hidden> Date: 2012-11-05 16:22:41
From: Rob Herring <redacted>
New received frames will trigger the rx DMA to poll the DMA descriptors,
so there is no need to tell the h/w to poll. We also want to enable
dropping frames from the fifo when there is no buffer.
Signed-off-by: Rob Herring <redacted>
---
drivers/net/ethernet/calxeda/xgmac.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
@@ -966,7 +966,7 @@ static int xgmac_hw_init(struct net_device *dev)ctrl|=XGMAC_CONTROL_IPC;writel(ctrl,ioaddr+XGMAC_CONTROL);-writel(DMA_CONTROL_DFF|DMA_CONTROL_OSF,ioaddr+XGMAC_DMA_CONTROL);+writel(DMA_CONTROL_OSF,ioaddr+XGMAC_DMA_CONTROL);/* Set the HW DMA mode and the COE */writel(XGMAC_OMR_TSF|XGMAC_OMR_RFD|XGMAC_OMR_RFA|
@@ -1180,8 +1180,6 @@ static int xgmac_rx(struct xgmac_priv *priv, int limit)xgmac_rx_refill(priv);-writel(1,priv->base+XGMAC_DMA_RX_POLL);-returncount;}
From: Rob Herring <hidden> Date: 2012-11-05 16:22:42
From: Rob Herring <redacted>
The standard readl/writel accessors involve a spinlock and cache sync
operation on ARM platforms with an outer cache. Only DMA triggering
accesses need this, so use the raw variants instead in the critical paths.
The relaxed variants would be more appropriate, but don't exist on all
arches.
Signed-off-by: Rob Herring <redacted>
---
v3:
- Use raw i/o accessors instead of relaxed for better build coverage.
drivers/net/ethernet/calxeda/xgmac.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
@@ -1203,7 +1203,7 @@ static int xgmac_poll(struct napi_struct *napi, int budget)if(work_done<budget){napi_complete(napi);-writel(DMA_INTR_DEFAULT_MASK,priv->base+XGMAC_DMA_INTR_ENA);+__raw_writel(DMA_INTR_DEFAULT_MASK,priv->base+XGMAC_DMA_INTR_ENA);}returnwork_done;}
@@ -1348,7 +1348,7 @@ static irqreturn_t xgmac_pmt_interrupt(int irq, void *dev_id)structxgmac_priv*priv=netdev_priv(dev);void__iomem*ioaddr=priv->base;-intr_status=readl(ioaddr+XGMAC_INT_STAT);+intr_status=__raw_readl(ioaddr+XGMAC_INT_STAT);if(intr_status&XGMAC_INT_STAT_PMT){netdev_dbg(priv->dev,"received Magic frame\n");/* clear the PMT bits 5 and 6 by reading the PMT */
@@ -1366,9 +1366,9 @@ static irqreturn_t xgmac_interrupt(int irq, void *dev_id)structxgmac_extra_stats*x=&priv->xstats;/* read the status register (CSR5) */-intr_status=readl(priv->base+XGMAC_DMA_STATUS);-intr_status&=readl(priv->base+XGMAC_DMA_INTR_ENA);-writel(intr_status,priv->base+XGMAC_DMA_STATUS);+intr_status=__raw_readl(priv->base+XGMAC_DMA_STATUS);+intr_status&=__raw_readl(priv->base+XGMAC_DMA_INTR_ENA);+__raw_writel(intr_status,priv->base+XGMAC_DMA_STATUS);/* It displays the DMA process states (CSR5 register) *//* ABNORMAL interrupts */
From: Rob Herring <hidden> Date: 2012-11-05 16:22:46
From: Rob Herring <redacted>
The interrupts have already been cleared, so we don't need to clear them
again. Also, we could miss interrupts if they are cleared, but we don't
process the packet.
Signed-off-by: Rob Herring <redacted>
---
drivers/net/ethernet/calxeda/xgmac.c | 6 ------
1 file changed, 6 deletions(-)
From: Rob Herring <hidden> Date: 2012-11-05 16:22:48
From: Rob Herring <redacted>
Only generate tx interrupts on every ring size / 4 descriptors. Move the
netif_stop_queue call to the end of the xmit function rather than
checking at the beginning.
Signed-off-by: Rob Herring <redacted>
---
drivers/net/ethernet/calxeda/xgmac.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
@@ -1110,9 +1107,9 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev)/* Interrupt on completition only for the latest segment */if(desc!=first)desc_set_tx_owner(desc,desc_flags|-TXDESC_LAST_SEG|TXDESC_INTERRUPT);+TXDESC_LAST_SEG|irq_flag);else-desc_flags|=TXDESC_LAST_SEG|TXDESC_INTERRUPT;+desc_flags|=TXDESC_LAST_SEG|irq_flag;/* Set owner on first desc last to avoid race condition */wmb();
From: Rob Herring <hidden> Date: 2012-11-05 16:22:51
From: Rob Herring <redacted>
On gcc 4.7, we will get alignment traps in the ip stack if we don't align
the ip headers on receive. The h/w can support this, so use ip aligned
allocations.
Cut down the unnecessary padding on the allocation. The buffer can start on
any byte alignment, but the size including the begining offset must be 8
byte aligned. So the h/w buffer size must include the NET_IP_ALIGN offset.
Thanks to Eric Dumazet for the initial patch highlighting the padding issues.
Signed-off-by: Rob Herring <redacted>
---
drivers/net/ethernet/calxeda/xgmac.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
@@ -703,10 +704,10 @@ static int xgmac_dma_desc_rings_init(struct net_device *dev)unsignedintbfsize;/* Set the Buffer size according to the MTU;-*indeed,incaseofjumboweneedtobump-upthebuffersizes.+*ThetotalbuffersizeincludinganyIPoffsetmustbeamultiple+*of8bytes.*/-bfsize=ALIGN(dev->mtu+ETH_HLEN+ETH_FCS_LEN+NET_IP_ALIGN+64,-64);+bfsize=ALIGN(dev->mtu+ETH_HLEN+ETH_FCS_LEN+NET_IP_ALIGN,8);netdev_dbg(priv->dev,"mtu [%d] bfsize [%d]\n",dev->mtu,bfsize);
From: Eric Dumazet <hidden> Date: 2012-11-05 16:53:49
On Mon, 2012-11-05 at 10:22 -0600, Rob Herring wrote:
From: Rob Herring <redacted>
On gcc 4.7, we will get alignment traps in the ip stack if we don't align
the ip headers on receive. The h/w can support this, so use ip aligned
allocations.
Cut down the unnecessary padding on the allocation. The buffer can start on
any byte alignment, but the size including the begining offset must be 8
byte aligned. So the h/w buffer size must include the NET_IP_ALIGN offset.
Thanks to Eric Dumazet for the initial patch highlighting the padding issues.
Signed-off-by: Rob Herring <redacted>
---
From: David Miller <davem@davemloft.net> Date: 2012-11-06 23:57:06
From: Rob Herring <redacted>
Date: Mon, 5 Nov 2012 10:22:23 -0600
Only generate tx interrupts on every ring size / 4 descriptors.
I thought we told you that you cannot do this.
With this change if we get a few packets, then stop generating any
traffic, there will be SKBs that just sit dead in your TX queue.
This cannot ever happen. All TX SKBs must be freed up in a short,
finite, amount of time. Under all conditions, and in every situation.
Otherwise memory accounted to sockets is not liberated, and such
sockets cannot be destroyed or closed.
SKBs also hold onto other kinds of resources, for which it is critical
to liberate in a finite amount of time.
I'm not applying this series, it still needs more work.
From: Rob Herring <hidden> Date: 2012-11-07 00:29:13
David,
On 11/06/2012 05:57 PM, David Miller wrote:
From: Rob Herring <redacted>
Date: Mon, 5 Nov 2012 10:22:23 -0600
quoted
Only generate tx interrupts on every ring size / 4 descriptors.
I thought we told you that you cannot do this.
With this change if we get a few packets, then stop generating any
traffic, there will be SKBs that just sit dead in your TX queue.
And as I previously mentioned, we do get a tx complete interrupt in
addition. The h/w will interrupt when all packets are transmitted and
there is not another descriptor ready. That is the only tx interrupt we
get without this patch. With this patch, we will get interrupts for
every N descriptors in addition to a tx complete/idle interrupt. This
patch is to avoid the transmitter from going idle and only refilling the
tx ring after finishing sending all frames. I can repost this patch and
make the commit message more clear, but I don't think there is any
functional change needed. This one is not so important compared to the
rest of the series, so you can just drop it if you still don't agree.
Rob
This cannot ever happen. All TX SKBs must be freed up in a short,
finite, amount of time. Under all conditions, and in every situation.
Otherwise memory accounted to sockets is not liberated, and such
sockets cannot be destroyed or closed.
SKBs also hold onto other kinds of resources, for which it is critical
to liberate in a finite amount of time.
I'm not applying this series, it still needs more work.
From: David Miller <davem@davemloft.net> Date: 2012-11-07 01:10:56
From: Rob Herring <redacted>
Date: Tue, 06 Nov 2012 18:29:11 -0600
David,
On 11/06/2012 05:57 PM, David Miller wrote:
quoted
From: Rob Herring <redacted>
Date: Mon, 5 Nov 2012 10:22:23 -0600
quoted
Only generate tx interrupts on every ring size / 4 descriptors.
I thought we told you that you cannot do this.
With this change if we get a few packets, then stop generating any
traffic, there will be SKBs that just sit dead in your TX queue.
And as I previously mentioned, we do get a tx complete interrupt in
addition. The h/w will interrupt when all packets are transmitted and
there is not another descriptor ready.
Ok, in that case it's fine. I'll keep reviewing this series then.
From: David Miller <davem@davemloft.net> Date: 2012-11-07 08:52:52
From: Rob Herring <redacted>
Date: Mon, 5 Nov 2012 10:22:18 -0600
This is a series of performance improvements to the xgmac driver. The
most significant changes are the alignment fixes to avoid alignment
traps on received frames and using raw i/o accessors.