All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/2] net: moxa: clear TX descriptor length bits
@ 2014-08-19 14:49 ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-19 14:49 UTC (permalink / raw)
  To: netdev
  Cc: davem, linux-arm-kernel, linux-kernel, f.fainelli, bhutchings,
	Jonas Jensen

TX buffer length is not cleared on ndo_start_xmit().
Failing to do so can bug/hang the controller and
cause TX interrupts to stop altogether.

Add TX_DESC1_BUF_SIZE_MASK to bits that are cleared,
before the TX buffer length is set.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69031

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Changes since v3:
    
    1. commit message reworded
    
    Applies to next-20140818

 drivers/net/ethernet/moxa/moxart_ether.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 5020fd4..aa45607 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -348,7 +348,8 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
 	txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
 	txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
-	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
+	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE |
+		    TX_DESC1_BUF_SIZE_MASK);
 	txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
 	writel(txdes1, desc + TX_REG_OFFSET_DESC1);
 	writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);
-- 
1.8.2.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v4 1/2] net: moxa: clear TX descriptor length bits
@ 2014-08-19 14:49 ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-19 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

TX buffer length is not cleared on ndo_start_xmit().
Failing to do so can bug/hang the controller and
cause TX interrupts to stop altogether.

Add TX_DESC1_BUF_SIZE_MASK to bits that are cleared,
before the TX buffer length is set.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69031

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Changes since v3:
    
    1. commit message reworded
    
    Applies to next-20140818

 drivers/net/ethernet/moxa/moxart_ether.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 5020fd4..aa45607 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -348,7 +348,8 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
 	txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
 	txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
-	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
+	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE |
+		    TX_DESC1_BUF_SIZE_MASK);
 	txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
 	writel(txdes1, desc + TX_REG_OFFSET_DESC1);
 	writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);
-- 
1.8.2.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
  2014-08-19 14:49 ` Jonas Jensen
@ 2014-08-19 14:49   ` Jonas Jensen
  -1 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-19 14:49 UTC (permalink / raw)
  To: netdev
  Cc: davem, linux-arm-kernel, linux-kernel, f.fainelli, bhutchings,
	Jonas Jensen

build_skb() is used to make skbs out of existing RX ring memory
which is bad because the RX ring is allocated only once, on probe.
Memory corruption occur because said memory is reclaimed, i.e.
__kfree_skb() (and eventually put_page()).

Replace build_skb() with netdev_alloc_skb_ip_align() and use memcpy().
Also, synchronize DMA memory before passing skb to napi_gro_receive().

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    The original motivation was to avoid memcpy(), since the memory is
    already allocated, why make a copy.
    
    Maybe the copy can be avoided updating RX ring descriptor addresses;
    new memory must be allocated just the same, the only difference that
    the controller could write directly to it.
    
    This fixes errors due to memory corruption, such as the following,
    seen on wget download (or ncftp):
    
    "read error: Bad address"
    
    On receiving error, wget exits without resuming (busybox default).
    
    Changes since v3:
    
    1. commit message reworded
    
    Applies to next-20140818

 drivers/net/ethernet/moxa/moxart_ether.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index aa45607..17c9f0e 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -226,14 +226,21 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
 		if (len > RX_BUF_SIZE)
 			len = RX_BUF_SIZE;
 
-		skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
+		dma_sync_single_for_cpu(&ndev->dev,
+					priv->rx_mapping[rx_head],
+					priv->rx_buf_size, DMA_FROM_DEVICE);
+		skb = netdev_alloc_skb_ip_align(ndev, len);
 		if (unlikely(!skb)) {
-			net_dbg_ratelimited("build_skb failed\n");
+			net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
 			priv->stats.rx_dropped++;
 			priv->stats.rx_errors++;
 		}
-
+		memcpy(skb->data, priv->rx_buf[rx_head], len);
 		skb_put(skb, len);
+		dma_sync_single_for_device(&ndev->dev,
+					   priv->rx_mapping[rx_head],
+					   priv->rx_buf_size, DMA_FROM_DEVICE);
+
 		skb->protocol = eth_type_trans(skb, ndev);
 		napi_gro_receive(&priv->napi, skb);
 		rx++;
-- 
1.8.2.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-19 14:49   ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-19 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

build_skb() is used to make skbs out of existing RX ring memory
which is bad because the RX ring is allocated only once, on probe.
Memory corruption occur because said memory is reclaimed, i.e.
__kfree_skb() (and eventually put_page()).

Replace build_skb() with netdev_alloc_skb_ip_align() and use memcpy().
Also, synchronize DMA memory before passing skb to napi_gro_receive().

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    The original motivation was to avoid memcpy(), since the memory is
    already allocated, why make a copy.
    
    Maybe the copy can be avoided updating RX ring descriptor addresses;
    new memory must be allocated just the same, the only difference that
    the controller could write directly to it.
    
    This fixes errors due to memory corruption, such as the following,
    seen on wget download (or ncftp):
    
    "read error: Bad address"
    
    On receiving error, wget exits without resuming (busybox default).
    
    Changes since v3:
    
    1. commit message reworded
    
    Applies to next-20140818

 drivers/net/ethernet/moxa/moxart_ether.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index aa45607..17c9f0e 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -226,14 +226,21 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
 		if (len > RX_BUF_SIZE)
 			len = RX_BUF_SIZE;
 
-		skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
+		dma_sync_single_for_cpu(&ndev->dev,
+					priv->rx_mapping[rx_head],
+					priv->rx_buf_size, DMA_FROM_DEVICE);
+		skb = netdev_alloc_skb_ip_align(ndev, len);
 		if (unlikely(!skb)) {
-			net_dbg_ratelimited("build_skb failed\n");
+			net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
 			priv->stats.rx_dropped++;
 			priv->stats.rx_errors++;
 		}
-
+		memcpy(skb->data, priv->rx_buf[rx_head], len);
 		skb_put(skb, len);
+		dma_sync_single_for_device(&ndev->dev,
+					   priv->rx_mapping[rx_head],
+					   priv->rx_buf_size, DMA_FROM_DEVICE);
+
 		skb->protocol = eth_type_trans(skb, ndev);
 		napi_gro_receive(&priv->napi, skb);
 		rx++;
-- 
1.8.2.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
  2014-08-19 14:49   ` Jonas Jensen
@ 2014-08-19 18:31     ` Eric Dumazet
  -1 siblings, 0 replies; 41+ messages in thread
From: Eric Dumazet @ 2014-08-19 18:31 UTC (permalink / raw)
  To: Jonas Jensen
  Cc: netdev, davem, linux-arm-kernel, linux-kernel, f.fainelli, bhutchings

On Tue, 2014-08-19 at 16:49 +0200, Jonas Jensen wrote:
> build_skb() is used to make skbs out of existing RX ring memory
> which is bad because the RX ring is allocated only once, on probe.
> Memory corruption occur because said memory is reclaimed, i.e.
> __kfree_skb() (and eventually put_page()).
> 
> Replace build_skb() with netdev_alloc_skb_ip_align() and use memcpy().
> Also, synchronize DMA memory before passing skb to napi_gro_receive().
> 
> Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041

Wow, this driver was really buggy.

Patch is not complete.

Instead of :

priv->rx_buf_size = RX_BUF_SIZE + 
		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));

I think rx_buf_size can now be RX_BUF_SIZE

Another point is that priv->stats seems not needed, as ndev->stats could
be used instead (and remove moxart_mac_get_stats())




^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-19 18:31     ` Eric Dumazet
  0 siblings, 0 replies; 41+ messages in thread
From: Eric Dumazet @ 2014-08-19 18:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2014-08-19 at 16:49 +0200, Jonas Jensen wrote:
> build_skb() is used to make skbs out of existing RX ring memory
> which is bad because the RX ring is allocated only once, on probe.
> Memory corruption occur because said memory is reclaimed, i.e.
> __kfree_skb() (and eventually put_page()).
> 
> Replace build_skb() with netdev_alloc_skb_ip_align() and use memcpy().
> Also, synchronize DMA memory before passing skb to napi_gro_receive().
> 
> Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041

Wow, this driver was really buggy.

Patch is not complete.

Instead of :

priv->rx_buf_size = RX_BUF_SIZE + 
		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));

I think rx_buf_size can now be RX_BUF_SIZE

Another point is that priv->stats seems not needed, as ndev->stats could
be used instead (and remove moxart_mac_get_stats())

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v5 1/2] net: moxa: clear TX descriptor length bits
  2014-08-19 14:49 ` Jonas Jensen
@ 2014-08-20 14:18   ` Jonas Jensen
  -1 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-20 14:18 UTC (permalink / raw)
  To: netdev
  Cc: davem, linux-arm-kernel, linux-kernel, f.fainelli, eric.dumazet,
	Jonas Jensen

TX buffer length is not cleared on ndo_start_xmit().
Failing to do so can bug/hang the controller and
cause TX interrupts to stop altogether.

Add TX_DESC1_BUF_SIZE_MASK to bits that are cleared,
before the TX buffer length is set.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69031

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    No changes since v4.
    
    Applies to next-20140820

 drivers/net/ethernet/moxa/moxart_ether.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 5020fd4..aa45607 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -348,7 +348,8 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
 	txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
 	txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
-	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
+	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE |
+		    TX_DESC1_BUF_SIZE_MASK);
 	txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
 	writel(txdes1, desc + TX_REG_OFFSET_DESC1);
 	writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);
-- 
1.8.2.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v5 1/2] net: moxa: clear TX descriptor length bits
@ 2014-08-20 14:18   ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-20 14:18 UTC (permalink / raw)
  To: linux-arm-kernel

TX buffer length is not cleared on ndo_start_xmit().
Failing to do so can bug/hang the controller and
cause TX interrupts to stop altogether.

Add TX_DESC1_BUF_SIZE_MASK to bits that are cleared,
before the TX buffer length is set.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69031

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    No changes since v4.
    
    Applies to next-20140820

 drivers/net/ethernet/moxa/moxart_ether.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 5020fd4..aa45607 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -348,7 +348,8 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
 	txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
 	txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
-	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
+	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE |
+		    TX_DESC1_BUF_SIZE_MASK);
 	txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
 	writel(txdes1, desc + TX_REG_OFFSET_DESC1);
 	writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);
-- 
1.8.2.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v5 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
  2014-08-19 14:49   ` Jonas Jensen
@ 2014-08-20 14:19     ` Jonas Jensen
  -1 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-20 14:19 UTC (permalink / raw)
  To: netdev
  Cc: davem, linux-arm-kernel, linux-kernel, f.fainelli, eric.dumazet,
	Jonas Jensen

build_skb() is used to make skbs out of existing RX ring memory
which is bad because the RX ring is allocated only once, on probe.
Memory corruption occur because said memory is reclaimed, i.e.
__kfree_skb() (and eventually put_page()).

Replace build_skb() with netdev_alloc_skb_ip_align(), use memcpy(),
and synchronize DMA memory before passing skb to napi_gro_receive().

Remove SKB_DATA_ALIGN() from RX buffer size while we're at it.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Changes since v4:
    
    1. remove SKB_DATA_ALIGN() from RX buffer size
    
    Applies to next-20140820

 drivers/net/ethernet/moxa/moxart_ether.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index aa45607..06a6fce 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -226,14 +226,21 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
 		if (len > RX_BUF_SIZE)
 			len = RX_BUF_SIZE;
 
-		skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
+		dma_sync_single_for_cpu(&ndev->dev,
+					priv->rx_mapping[rx_head],
+					priv->rx_buf_size, DMA_FROM_DEVICE);
+		skb = netdev_alloc_skb_ip_align(ndev, len);
 		if (unlikely(!skb)) {
-			net_dbg_ratelimited("build_skb failed\n");
+			net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
 			priv->stats.rx_dropped++;
 			priv->stats.rx_errors++;
 		}
-
+		memcpy(skb->data, priv->rx_buf[rx_head], len);
 		skb_put(skb, len);
+		dma_sync_single_for_device(&ndev->dev,
+					   priv->rx_mapping[rx_head],
+					   priv->rx_buf_size, DMA_FROM_DEVICE);
+
 		skb->protocol = eth_type_trans(skb, ndev);
 		napi_gro_receive(&priv->napi, skb);
 		rx++;
@@ -466,8 +473,7 @@ static int moxart_mac_probe(struct platform_device *pdev)
 	spin_lock_init(&priv->txlock);
 
 	priv->tx_buf_size = TX_BUF_SIZE;
-	priv->rx_buf_size = RX_BUF_SIZE +
-			    SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+	priv->rx_buf_size = RX_BUF_SIZE;
 
 	priv->tx_desc_base = dma_alloc_coherent(NULL, TX_REG_DESC_SIZE *
 						TX_DESC_NUM, &priv->tx_base,
-- 
1.8.2.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v5 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-20 14:19     ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-20 14:19 UTC (permalink / raw)
  To: linux-arm-kernel

build_skb() is used to make skbs out of existing RX ring memory
which is bad because the RX ring is allocated only once, on probe.
Memory corruption occur because said memory is reclaimed, i.e.
__kfree_skb() (and eventually put_page()).

Replace build_skb() with netdev_alloc_skb_ip_align(), use memcpy(),
and synchronize DMA memory before passing skb to napi_gro_receive().

Remove SKB_DATA_ALIGN() from RX buffer size while we're at it.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Changes since v4:
    
    1. remove SKB_DATA_ALIGN() from RX buffer size
    
    Applies to next-20140820

 drivers/net/ethernet/moxa/moxart_ether.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index aa45607..06a6fce 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -226,14 +226,21 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
 		if (len > RX_BUF_SIZE)
 			len = RX_BUF_SIZE;
 
-		skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
+		dma_sync_single_for_cpu(&ndev->dev,
+					priv->rx_mapping[rx_head],
+					priv->rx_buf_size, DMA_FROM_DEVICE);
+		skb = netdev_alloc_skb_ip_align(ndev, len);
 		if (unlikely(!skb)) {
-			net_dbg_ratelimited("build_skb failed\n");
+			net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
 			priv->stats.rx_dropped++;
 			priv->stats.rx_errors++;
 		}
-
+		memcpy(skb->data, priv->rx_buf[rx_head], len);
 		skb_put(skb, len);
+		dma_sync_single_for_device(&ndev->dev,
+					   priv->rx_mapping[rx_head],
+					   priv->rx_buf_size, DMA_FROM_DEVICE);
+
 		skb->protocol = eth_type_trans(skb, ndev);
 		napi_gro_receive(&priv->napi, skb);
 		rx++;
@@ -466,8 +473,7 @@ static int moxart_mac_probe(struct platform_device *pdev)
 	spin_lock_init(&priv->txlock);
 
 	priv->tx_buf_size = TX_BUF_SIZE;
-	priv->rx_buf_size = RX_BUF_SIZE +
-			    SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+	priv->rx_buf_size = RX_BUF_SIZE;
 
 	priv->tx_desc_base = dma_alloc_coherent(NULL, TX_REG_DESC_SIZE *
 						TX_DESC_NUM, &priv->tx_base,
-- 
1.8.2.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
  2014-08-19 18:31     ` Eric Dumazet
  (?)
@ 2014-08-20 14:24       ` Jonas Jensen
  -1 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-20 14:24 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: netdev, davem, linux-arm-kernel, linux-kernel, Florian Fainelli

On 19 August 2014 20:31, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Instead of :
>
> priv->rx_buf_size = RX_BUF_SIZE +
>                 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
>
> I think rx_buf_size can now be RX_BUF_SIZE

You're right, that's now a remnant, see update in v5.


> Another point is that priv->stats seems not needed, as ndev->stats could
> be used instead (and remove moxart_mac_get_stats())

I will fix that. I can add it to patches adding support for ethtool /
stats and PHY.

I think I'm supposed to post those closer to the merge window, which
would keep this set about bug fixes only.


Regards,


   Jonas

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-20 14:24       ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-20 14:24 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: netdev, davem, linux-arm-kernel, linux-kernel, Florian Fainelli

On 19 August 2014 20:31, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Instead of :
>
> priv->rx_buf_size = RX_BUF_SIZE +
>                 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
>
> I think rx_buf_size can now be RX_BUF_SIZE

You're right, that's now a remnant, see update in v5.


> Another point is that priv->stats seems not needed, as ndev->stats could
> be used instead (and remove moxart_mac_get_stats())

I will fix that. I can add it to patches adding support for ethtool /
stats and PHY.

I think I'm supposed to post those closer to the merge window, which
would keep this set about bug fixes only.


Regards,


   Jonas

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-20 14:24       ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-20 14:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 19 August 2014 20:31, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Instead of :
>
> priv->rx_buf_size = RX_BUF_SIZE +
>                 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
>
> I think rx_buf_size can now be RX_BUF_SIZE

You're right, that's now a remnant, see update in v5.


> Another point is that priv->stats seems not needed, as ndev->stats could
> be used instead (and remove moxart_mac_get_stats())

I will fix that. I can add it to patches adding support for ethtool /
stats and PHY.

I think I'm supposed to post those closer to the merge window, which
would keep this set about bug fixes only.


Regards,


   Jonas

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v5 1/2] net: moxa: clear TX descriptor length bits
  2014-08-20 14:18   ` Jonas Jensen
@ 2014-08-20 17:10     ` Eric Dumazet
  -1 siblings, 0 replies; 41+ messages in thread
From: Eric Dumazet @ 2014-08-20 17:10 UTC (permalink / raw)
  To: Jonas Jensen; +Cc: netdev, davem, linux-arm-kernel, linux-kernel, f.fainelli

On Wed, 2014-08-20 at 16:18 +0200, Jonas Jensen wrote:
> TX buffer length is not cleared on ndo_start_xmit().
> Failing to do so can bug/hang the controller and
> cause TX interrupts to stop altogether.

> 
> diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
> index 5020fd4..aa45607 100644
> --- a/drivers/net/ethernet/moxa/moxart_ether.c
> +++ b/drivers/net/ethernet/moxa/moxart_ether.c
> @@ -348,7 +348,8 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
>  
>  	txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
>  	txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
> -	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
> +	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE |
> +		    TX_DESC1_BUF_SIZE_MASK);
>  	txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
>  	writel(txdes1, desc + TX_REG_OFFSET_DESC1);
>  	writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);

Wouldnt it be faster to not use readl() at all here ?

readl() is only used to get TX_DESC1_END bit.

It seems you could replace the thing by :

txdes1 = TX_DESC1_LTS | TX_DESC1_FTS | (len & TX_DESC1_BUF_SIZE_MASK);
if (tx_head == TX_DESC_NUM_MASK)
	txdes1 |= TX_DESC1_END;




^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v5 1/2] net: moxa: clear TX descriptor length bits
@ 2014-08-20 17:10     ` Eric Dumazet
  0 siblings, 0 replies; 41+ messages in thread
From: Eric Dumazet @ 2014-08-20 17:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 2014-08-20 at 16:18 +0200, Jonas Jensen wrote:
> TX buffer length is not cleared on ndo_start_xmit().
> Failing to do so can bug/hang the controller and
> cause TX interrupts to stop altogether.

> 
> diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
> index 5020fd4..aa45607 100644
> --- a/drivers/net/ethernet/moxa/moxart_ether.c
> +++ b/drivers/net/ethernet/moxa/moxart_ether.c
> @@ -348,7 +348,8 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
>  
>  	txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
>  	txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
> -	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
> +	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE |
> +		    TX_DESC1_BUF_SIZE_MASK);
>  	txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
>  	writel(txdes1, desc + TX_REG_OFFSET_DESC1);
>  	writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);

Wouldnt it be faster to not use readl() at all here ?

readl() is only used to get TX_DESC1_END bit.

It seems you could replace the thing by :

txdes1 = TX_DESC1_LTS | TX_DESC1_FTS | (len & TX_DESC1_BUF_SIZE_MASK);
if (tx_head == TX_DESC_NUM_MASK)
	txdes1 |= TX_DESC1_END;

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
  2014-08-19 14:49   ` Jonas Jensen
  (?)
@ 2014-08-21 21:43     ` Michał Mirosław
  -1 siblings, 0 replies; 41+ messages in thread
From: Michał Mirosław @ 2014-08-21 21:43 UTC (permalink / raw)
  To: Jonas Jensen
  Cc: netdev, f.fainelli, Linux Kernel, Ben Hutchings, David Miller,
	linux-arm-kernel

2014-08-19 16:49 GMT+02:00 Jonas Jensen <jonas.jensen@gmail.com>:
[...]
> diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
> index aa45607..17c9f0e 100644
> --- a/drivers/net/ethernet/moxa/moxart_ether.c
> +++ b/drivers/net/ethernet/moxa/moxart_ether.c
> @@ -226,14 +226,21 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
>                 if (len > RX_BUF_SIZE)
>                         len = RX_BUF_SIZE;
>
> -               skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
> +               dma_sync_single_for_cpu(&ndev->dev,
> +                                       priv->rx_mapping[rx_head],
> +                                       priv->rx_buf_size, DMA_FROM_DEVICE);
> +               skb = netdev_alloc_skb_ip_align(ndev, len);
>                 if (unlikely(!skb)) {
> -                       net_dbg_ratelimited("build_skb failed\n");
> +                       net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
>                         priv->stats.rx_dropped++;
>                         priv->stats.rx_errors++;
>                 }
> -
> +               memcpy(skb->data, priv->rx_buf[rx_head], len);

This has implicit: if (!skb) BUG(); There should probably be a return
or continue inside the if (!skb).

>                 skb_put(skb, len);
> +               dma_sync_single_for_device(&ndev->dev,
> +                                          priv->rx_mapping[rx_head],
> +                                          priv->rx_buf_size, DMA_FROM_DEVICE);
> +

dma_sync_single_for_device() is not needed here as CPU does not and
should not write to the DMA_FROM_DEVICE mapping.


>                 skb->protocol = eth_type_trans(skb, ndev);
>                 napi_gro_receive(&priv->napi, skb);
>                 rx++;

Best Regards,
Michał Mirosław

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-21 21:43     ` Michał Mirosław
  0 siblings, 0 replies; 41+ messages in thread
From: Michał Mirosław @ 2014-08-21 21:43 UTC (permalink / raw)
  To: Jonas Jensen
  Cc: netdev, f.fainelli, Linux Kernel, Ben Hutchings, David Miller,
	linux-arm-kernel

2014-08-19 16:49 GMT+02:00 Jonas Jensen <jonas.jensen@gmail.com>:
[...]
> diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
> index aa45607..17c9f0e 100644
> --- a/drivers/net/ethernet/moxa/moxart_ether.c
> +++ b/drivers/net/ethernet/moxa/moxart_ether.c
> @@ -226,14 +226,21 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
>                 if (len > RX_BUF_SIZE)
>                         len = RX_BUF_SIZE;
>
> -               skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
> +               dma_sync_single_for_cpu(&ndev->dev,
> +                                       priv->rx_mapping[rx_head],
> +                                       priv->rx_buf_size, DMA_FROM_DEVICE);
> +               skb = netdev_alloc_skb_ip_align(ndev, len);
>                 if (unlikely(!skb)) {
> -                       net_dbg_ratelimited("build_skb failed\n");
> +                       net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
>                         priv->stats.rx_dropped++;
>                         priv->stats.rx_errors++;
>                 }
> -
> +               memcpy(skb->data, priv->rx_buf[rx_head], len);

This has implicit: if (!skb) BUG(); There should probably be a return
or continue inside the if (!skb).

>                 skb_put(skb, len);
> +               dma_sync_single_for_device(&ndev->dev,
> +                                          priv->rx_mapping[rx_head],
> +                                          priv->rx_buf_size, DMA_FROM_DEVICE);
> +

dma_sync_single_for_device() is not needed here as CPU does not and
should not write to the DMA_FROM_DEVICE mapping.


>                 skb->protocol = eth_type_trans(skb, ndev);
>                 napi_gro_receive(&priv->napi, skb);
>                 rx++;

Best Regards,
Michał Mirosław

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-21 21:43     ` Michał Mirosław
  0 siblings, 0 replies; 41+ messages in thread
From: Michał Mirosław @ 2014-08-21 21:43 UTC (permalink / raw)
  To: linux-arm-kernel

2014-08-19 16:49 GMT+02:00 Jonas Jensen <jonas.jensen@gmail.com>:
[...]
> diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
> index aa45607..17c9f0e 100644
> --- a/drivers/net/ethernet/moxa/moxart_ether.c
> +++ b/drivers/net/ethernet/moxa/moxart_ether.c
> @@ -226,14 +226,21 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
>                 if (len > RX_BUF_SIZE)
>                         len = RX_BUF_SIZE;
>
> -               skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
> +               dma_sync_single_for_cpu(&ndev->dev,
> +                                       priv->rx_mapping[rx_head],
> +                                       priv->rx_buf_size, DMA_FROM_DEVICE);
> +               skb = netdev_alloc_skb_ip_align(ndev, len);
>                 if (unlikely(!skb)) {
> -                       net_dbg_ratelimited("build_skb failed\n");
> +                       net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
>                         priv->stats.rx_dropped++;
>                         priv->stats.rx_errors++;
>                 }
> -
> +               memcpy(skb->data, priv->rx_buf[rx_head], len);

This has implicit: if (!skb) BUG(); There should probably be a return
or continue inside the if (!skb).

>                 skb_put(skb, len);
> +               dma_sync_single_for_device(&ndev->dev,
> +                                          priv->rx_mapping[rx_head],
> +                                          priv->rx_buf_size, DMA_FROM_DEVICE);
> +

dma_sync_single_for_device() is not needed here as CPU does not and
should not write to the DMA_FROM_DEVICE mapping.


>                 skb->protocol = eth_type_trans(skb, ndev);
>                 napi_gro_receive(&priv->napi, skb);
>                 rx++;

Best Regards,
Micha? Miros?aw

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v5 1/2] net: moxa: clear TX descriptor length bits
  2014-08-20 14:18   ` Jonas Jensen
@ 2014-08-22  4:39     ` David Miller
  -1 siblings, 0 replies; 41+ messages in thread
From: David Miller @ 2014-08-22  4:39 UTC (permalink / raw)
  To: jonas.jensen
  Cc: netdev, linux-arm-kernel, linux-kernel, f.fainelli, eric.dumazet

From: Jonas Jensen <jonas.jensen@gmail.com>
Date: Wed, 20 Aug 2014 16:18:42 +0200

> @@ -348,7 +348,8 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
>  
>  	txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
>  	txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
> -	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
> +	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE |
> +		    TX_DESC1_BUF_SIZE_MASK);
>  	txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
>  	writel(txdes1, desc + TX_REG_OFFSET_DESC1);
>  	writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);

Like others I wonder why the existing descriptor value is being read
at all.

It's inefficient and completely unnecessary, you can just compute a new
value from scratch, and that way all of these "uncleared field" issues
just automatically disappear.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v5 1/2] net: moxa: clear TX descriptor length bits
@ 2014-08-22  4:39     ` David Miller
  0 siblings, 0 replies; 41+ messages in thread
From: David Miller @ 2014-08-22  4:39 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jonas Jensen <jonas.jensen@gmail.com>
Date: Wed, 20 Aug 2014 16:18:42 +0200

> @@ -348,7 +348,8 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
>  
>  	txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
>  	txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
> -	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
> +	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE |
> +		    TX_DESC1_BUF_SIZE_MASK);
>  	txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
>  	writel(txdes1, desc + TX_REG_OFFSET_DESC1);
>  	writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);

Like others I wonder why the existing descriptor value is being read
at all.

It's inefficient and completely unnecessary, you can just compute a new
value from scratch, and that way all of these "uncleared field" issues
just automatically disappear.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v6 1/4] net: moxa: clear DESC1 on ndo_start_xmit()
  2014-08-20 14:18   ` Jonas Jensen
@ 2014-08-25 14:22     ` Jonas Jensen
  -1 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-25 14:22 UTC (permalink / raw)
  To: netdev
  Cc: davem, linux-arm-kernel, linux-kernel, f.fainelli, eric.dumazet,
	mirqus, Jonas Jensen

TX buffer length is not cleared on ndo_start_xmit().
Failing to do so can bug/hang the controller and
cause TX interrupts to stop altogether.

Remove the readl() and compute a new value for DESC1.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69031

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Changes since v5:
    
    1. remove readl(desc + TX_REG_OFFSET_DESC1) in moxart_mac_start_xmit()
    2. compute entirely new values for DESC1
    3. set TX_DESC1_END if (tx_head == TX_DESC_NUM_MASK)
    
    Applies to next-20140825

 drivers/net/ethernet/moxa/moxart_ether.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 5020fd4..eed70d9 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -346,10 +346,9 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 		len = ETH_ZLEN;
 	}
 
-	txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
-	txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
-	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
-	txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
+	txdes1 = TX_DESC1_LTS | TX_DESC1_FTS | (len & TX_DESC1_BUF_SIZE_MASK);
+	if (tx_head == TX_DESC_NUM_MASK)
+		txdes1 |= TX_DESC1_END;
 	writel(txdes1, desc + TX_REG_OFFSET_DESC1);
 	writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);
 
-- 
1.8.2.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v6 1/4] net: moxa: clear DESC1 on ndo_start_xmit()
@ 2014-08-25 14:22     ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-25 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

TX buffer length is not cleared on ndo_start_xmit().
Failing to do so can bug/hang the controller and
cause TX interrupts to stop altogether.

Remove the readl() and compute a new value for DESC1.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69031

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Changes since v5:
    
    1. remove readl(desc + TX_REG_OFFSET_DESC1) in moxart_mac_start_xmit()
    2. compute entirely new values for DESC1
    3. set TX_DESC1_END if (tx_head == TX_DESC_NUM_MASK)
    
    Applies to next-20140825

 drivers/net/ethernet/moxa/moxart_ether.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index 5020fd4..eed70d9 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -346,10 +346,9 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 		len = ETH_ZLEN;
 	}
 
-	txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
-	txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
-	txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
-	txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
+	txdes1 = TX_DESC1_LTS | TX_DESC1_FTS | (len & TX_DESC1_BUF_SIZE_MASK);
+	if (tx_head == TX_DESC_NUM_MASK)
+		txdes1 |= TX_DESC1_END;
 	writel(txdes1, desc + TX_REG_OFFSET_DESC1);
 	writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);
 
-- 
1.8.2.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
  2014-08-20 14:19     ` Jonas Jensen
@ 2014-08-25 14:22       ` Jonas Jensen
  -1 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-25 14:22 UTC (permalink / raw)
  To: netdev
  Cc: davem, linux-arm-kernel, linux-kernel, f.fainelli, eric.dumazet,
	mirqus, Jonas Jensen

build_skb() is used to make skbs out of existing RX ring memory
which is bad because the RX ring is allocated only once, on probe.
Memory corruption occur because said memory is reclaimed, i.e.
__kfree_skb() (and eventually put_page()).

Replace build_skb() with netdev_alloc_skb_ip_align() and use memcpy().

Remove SKB_DATA_ALIGN() from RX buffer size while we're at it.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Changes since v5:
    
    1. broke out DMA synchronization to separate patch
    
    Applies to next-20140825

 drivers/net/ethernet/moxa/moxart_ether.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index eed70d9..d66058d 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -226,13 +226,15 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
 		if (len > RX_BUF_SIZE)
 			len = RX_BUF_SIZE;
 
-		skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
+		skb = netdev_alloc_skb_ip_align(ndev, len);
+
 		if (unlikely(!skb)) {
-			net_dbg_ratelimited("build_skb failed\n");
+			net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
 			priv->stats.rx_dropped++;
 			priv->stats.rx_errors++;
 		}
 
+		memcpy(skb->data, priv->rx_buf[rx_head], len);
 		skb_put(skb, len);
 		skb->protocol = eth_type_trans(skb, ndev);
 		napi_gro_receive(&priv->napi, skb);
@@ -464,8 +466,7 @@ static int moxart_mac_probe(struct platform_device *pdev)
 	spin_lock_init(&priv->txlock);
 
 	priv->tx_buf_size = TX_BUF_SIZE;
-	priv->rx_buf_size = RX_BUF_SIZE +
-			    SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+	priv->rx_buf_size = RX_BUF_SIZE;
 
 	priv->tx_desc_base = dma_alloc_coherent(NULL, TX_REG_DESC_SIZE *
 						TX_DESC_NUM, &priv->tx_base,
-- 
1.8.2.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-25 14:22       ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-25 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

build_skb() is used to make skbs out of existing RX ring memory
which is bad because the RX ring is allocated only once, on probe.
Memory corruption occur because said memory is reclaimed, i.e.
__kfree_skb() (and eventually put_page()).

Replace build_skb() with netdev_alloc_skb_ip_align() and use memcpy().

Remove SKB_DATA_ALIGN() from RX buffer size while we're at it.

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---

Notes:
    Changes since v5:
    
    1. broke out DMA synchronization to separate patch
    
    Applies to next-20140825

 drivers/net/ethernet/moxa/moxart_ether.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c
index eed70d9..d66058d 100644
--- a/drivers/net/ethernet/moxa/moxart_ether.c
+++ b/drivers/net/ethernet/moxa/moxart_ether.c
@@ -226,13 +226,15 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
 		if (len > RX_BUF_SIZE)
 			len = RX_BUF_SIZE;
 
-		skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
+		skb = netdev_alloc_skb_ip_align(ndev, len);
+
 		if (unlikely(!skb)) {
-			net_dbg_ratelimited("build_skb failed\n");
+			net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
 			priv->stats.rx_dropped++;
 			priv->stats.rx_errors++;
 		}
 
+		memcpy(skb->data, priv->rx_buf[rx_head], len);
 		skb_put(skb, len);
 		skb->protocol = eth_type_trans(skb, ndev);
 		napi_gro_receive(&priv->napi, skb);
@@ -464,8 +466,7 @@ static int moxart_mac_probe(struct platform_device *pdev)
 	spin_lock_init(&priv->txlock);
 
 	priv->tx_buf_size = TX_BUF_SIZE;
-	priv->rx_buf_size = RX_BUF_SIZE +
-			    SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+	priv->rx_buf_size = RX_BUF_SIZE;
 
 	priv->tx_desc_base = dma_alloc_coherent(NULL, TX_REG_DESC_SIZE *
 						TX_DESC_NUM, &priv->tx_base,
-- 
1.8.2.1

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
  2014-08-21 21:43     ` Michał Mirosław
  (?)
@ 2014-08-25 14:23       ` Jonas Jensen
  -1 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-25 14:23 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: netdev, Florian Fainelli, Linux Kernel, David Miller,
	linux-arm-kernel, Eric Dumazet

Thanks for giving feedback.

On 21 August 2014 23:43, Michał Mirosław <mirqus@gmail.com> wrote:
> This has implicit: if (!skb) BUG(); There should probably be a return
> or continue inside the if (!skb).

Fixed, see v6 update (broken out to separate patch) which now includes
increment to RX head counter

> dma_sync_single_for_device() is not needed here as CPU does not and
> should not write to the DMA_FROM_DEVICE mapping.

Fixed, this was also broken out, dma_sync_single_for_device() moved to TX path.
Maybe someone can verify this is the correct thing to do.


Regards,

   Jonas

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-25 14:23       ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-25 14:23 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: netdev, Florian Fainelli, Linux Kernel, David Miller,
	linux-arm-kernel, Eric Dumazet

Thanks for giving feedback.

On 21 August 2014 23:43, Michał Mirosław <mirqus@gmail.com> wrote:
> This has implicit: if (!skb) BUG(); There should probably be a return
> or continue inside the if (!skb).

Fixed, see v6 update (broken out to separate patch) which now includes
increment to RX head counter

> dma_sync_single_for_device() is not needed here as CPU does not and
> should not write to the DMA_FROM_DEVICE mapping.

Fixed, this was also broken out, dma_sync_single_for_device() moved to TX path.
Maybe someone can verify this is the correct thing to do.


Regards,

   Jonas

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-25 14:23       ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-25 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks for giving feedback.

On 21 August 2014 23:43, Micha? Miros?aw <mirqus@gmail.com> wrote:
> This has implicit: if (!skb) BUG(); There should probably be a return
> or continue inside the if (!skb).

Fixed, see v6 update (broken out to separate patch) which now includes
increment to RX head counter

> dma_sync_single_for_device() is not needed here as CPU does not and
> should not write to the DMA_FROM_DEVICE mapping.

Fixed, this was also broken out, dma_sync_single_for_device() moved to TX path.
Maybe someone can verify this is the correct thing to do.


Regards,

   Jonas

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v5 1/2] net: moxa: clear TX descriptor length bits
  2014-08-20 17:10     ` Eric Dumazet
@ 2014-08-25 14:23       ` Jonas Jensen
  -1 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-25 14:23 UTC (permalink / raw)
  To: Eric Dumazet, davem
  Cc: netdev, linux-arm-kernel, linux-kernel, Florian Fainelli,
	Michał Mirosław

Thanks for giving feedback.

On 20 August 2014 19:10, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Wouldnt it be faster to not use readl() at all here ?

On 22 August 2014 06:39, David Miller <davem@davemloft.net> wrote:
> Like others I wonder why the existing descriptor value is being read
> at all.

It makes sense and I have verified, transfers continue to work
clearing the whole thing, see update in v6.


Regards,

   Jonas

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v5 1/2] net: moxa: clear TX descriptor length bits
@ 2014-08-25 14:23       ` Jonas Jensen
  0 siblings, 0 replies; 41+ messages in thread
From: Jonas Jensen @ 2014-08-25 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks for giving feedback.

On 20 August 2014 19:10, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Wouldnt it be faster to not use readl() at all here ?

On 22 August 2014 06:39, David Miller <davem@davemloft.net> wrote:
> Like others I wonder why the existing descriptor value is being read
> at all.

It makes sense and I have verified, transfers continue to work
clearing the whole thing, see update in v6.


Regards,

   Jonas

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6 1/4] net: moxa: clear DESC1 on ndo_start_xmit()
  2014-08-25 14:22     ` Jonas Jensen
@ 2014-08-26  0:25       ` David Miller
  -1 siblings, 0 replies; 41+ messages in thread
From: David Miller @ 2014-08-26  0:25 UTC (permalink / raw)
  To: jonas.jensen
  Cc: netdev, linux-arm-kernel, linux-kernel, f.fainelli, eric.dumazet, mirqus

From: Jonas Jensen <jonas.jensen@gmail.com>
Date: Mon, 25 Aug 2014 16:22:11 +0200

> TX buffer length is not cleared on ndo_start_xmit().
> Failing to do so can bug/hang the controller and
> cause TX interrupts to stop altogether.
> 
> Remove the readl() and compute a new value for DESC1.
> 
> Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69031
> 
> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>

Applied.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v6 1/4] net: moxa: clear DESC1 on ndo_start_xmit()
@ 2014-08-26  0:25       ` David Miller
  0 siblings, 0 replies; 41+ messages in thread
From: David Miller @ 2014-08-26  0:25 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jonas Jensen <jonas.jensen@gmail.com>
Date: Mon, 25 Aug 2014 16:22:11 +0200

> TX buffer length is not cleared on ndo_start_xmit().
> Failing to do so can bug/hang the controller and
> cause TX interrupts to stop altogether.
> 
> Remove the readl() and compute a new value for DESC1.
> 
> Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69031
> 
> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>

Applied.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
  2014-08-25 14:22       ` Jonas Jensen
@ 2014-08-26  0:26         ` David Miller
  -1 siblings, 0 replies; 41+ messages in thread
From: David Miller @ 2014-08-26  0:26 UTC (permalink / raw)
  To: jonas.jensen
  Cc: netdev, linux-arm-kernel, linux-kernel, f.fainelli, eric.dumazet, mirqus

From: Jonas Jensen <jonas.jensen@gmail.com>
Date: Mon, 25 Aug 2014 16:22:22 +0200

> build_skb() is used to make skbs out of existing RX ring memory
> which is bad because the RX ring is allocated only once, on probe.
> Memory corruption occur because said memory is reclaimed, i.e.
> __kfree_skb() (and eventually put_page()).
> 
> Replace build_skb() with netdev_alloc_skb_ip_align() and use memcpy().
> 
> Remove SKB_DATA_ALIGN() from RX buffer size while we're at it.
> 
> Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041
> 
> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>

Applied.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-26  0:26         ` David Miller
  0 siblings, 0 replies; 41+ messages in thread
From: David Miller @ 2014-08-26  0:26 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jonas Jensen <jonas.jensen@gmail.com>
Date: Mon, 25 Aug 2014 16:22:22 +0200

> build_skb() is used to make skbs out of existing RX ring memory
> which is bad because the RX ring is allocated only once, on probe.
> Memory corruption occur because said memory is reclaimed, i.e.
> __kfree_skb() (and eventually put_page()).
> 
> Replace build_skb() with netdev_alloc_skb_ip_align() and use memcpy().
> 
> Remove SKB_DATA_ALIGN() from RX buffer size while we're at it.
> 
> Addresses https://bugzilla.kernel.org/show_bug.cgi?id=69041
> 
> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>

Applied.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
  2014-08-25 14:22       ` Jonas Jensen
@ 2014-08-26  9:04         ` Arnd Bergmann
  -1 siblings, 0 replies; 41+ messages in thread
From: Arnd Bergmann @ 2014-08-26  9:04 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Jonas Jensen, netdev, f.fainelli, eric.dumazet, linux-kernel,
	mirqus, davem

On Monday 25 August 2014 16:22:22 Jonas Jensen wrote:
> @@ -226,13 +226,15 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
>                 if (len > RX_BUF_SIZE)
>                         len = RX_BUF_SIZE;
>  
> -               skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
> +               skb = netdev_alloc_skb_ip_align(ndev, len);
> +
>                 if (unlikely(!skb)) {
> -                       net_dbg_ratelimited("build_skb failed\n");
> +                       net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
>                         priv->stats.rx_dropped++;
>                         priv->stats.rx_errors++;
>                 }
>  
> +               memcpy(skb->data, priv->rx_buf[rx_head], len);
>                 skb_put(skb, len);
>                 skb->protocol = eth_type_trans(skb, ndev);
>                 napi_gro_receive(&priv->napi, skb);

While this seems correct, I wonder why you don't do the normal approach of
dequeuing the skb from the chain and adding a newly allocated skb to it to
save the memcpy.

	Arnd

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-26  9:04         ` Arnd Bergmann
  0 siblings, 0 replies; 41+ messages in thread
From: Arnd Bergmann @ 2014-08-26  9:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 25 August 2014 16:22:22 Jonas Jensen wrote:
> @@ -226,13 +226,15 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
>                 if (len > RX_BUF_SIZE)
>                         len = RX_BUF_SIZE;
>  
> -               skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
> +               skb = netdev_alloc_skb_ip_align(ndev, len);
> +
>                 if (unlikely(!skb)) {
> -                       net_dbg_ratelimited("build_skb failed\n");
> +                       net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
>                         priv->stats.rx_dropped++;
>                         priv->stats.rx_errors++;
>                 }
>  
> +               memcpy(skb->data, priv->rx_buf[rx_head], len);
>                 skb_put(skb, len);
>                 skb->protocol = eth_type_trans(skb, ndev);
>                 napi_gro_receive(&priv->napi, skb);

While this seems correct, I wonder why you don't do the normal approach of
dequeuing the skb from the chain and adding a newly allocated skb to it to
save the memcpy.

	Arnd

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
  2014-08-26  9:04         ` Arnd Bergmann
  (?)
@ 2014-08-26  9:10           ` David Laight
  -1 siblings, 0 replies; 41+ messages in thread
From: David Laight @ 2014-08-26  9:10 UTC (permalink / raw)
  To: 'Arnd Bergmann', linux-arm-kernel
  Cc: Jonas Jensen, netdev, f.fainelli, eric.dumazet, linux-kernel,
	mirqus, davem

From: Arnd Bergmann
> On Monday 25 August 2014 16:22:22 Jonas Jensen wrote:
> > @@ -226,13 +226,15 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
> >                 if (len > RX_BUF_SIZE)
> >                         len = RX_BUF_SIZE;
> >
> > -               skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
> > +               skb = netdev_alloc_skb_ip_align(ndev, len);
> > +
> >                 if (unlikely(!skb)) {
> > -                       net_dbg_ratelimited("build_skb failed\n");
> > +                       net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
> >                         priv->stats.rx_dropped++;
> >                         priv->stats.rx_errors++;
> >                 }
> >
> > +               memcpy(skb->data, priv->rx_buf[rx_head], len);

Is this memcpy() aligned?
If the hardware can receive to a 4n+2 offset it is probably better to
copy the two bytes before the frame data and to round the length of to
a whole number of words.

> >                 skb_put(skb, len);
> >                 skb->protocol = eth_type_trans(skb, ndev);
> >                 napi_gro_receive(&priv->napi, skb);
> 
> While this seems correct, I wonder why you don't do the normal approach of
> dequeuing the skb from the chain and adding a newly allocated skb to it to
> save the memcpy.

Because the receive buffer area isn't made of skbs.
Post-allocating the skb also reduces the 'true size' of the skb.

	David




^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-26  9:10           ` David Laight
  0 siblings, 0 replies; 41+ messages in thread
From: David Laight @ 2014-08-26  9:10 UTC (permalink / raw)
  To: 'Arnd Bergmann', linux-arm-kernel
  Cc: Jonas Jensen, netdev, f.fainelli, eric.dumazet, linux-kernel,
	mirqus, davem

From: Arnd Bergmann
> On Monday 25 August 2014 16:22:22 Jonas Jensen wrote:
> > @@ -226,13 +226,15 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
> >                 if (len > RX_BUF_SIZE)
> >                         len = RX_BUF_SIZE;
> >
> > -               skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
> > +               skb = netdev_alloc_skb_ip_align(ndev, len);
> > +
> >                 if (unlikely(!skb)) {
> > -                       net_dbg_ratelimited("build_skb failed\n");
> > +                       net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
> >                         priv->stats.rx_dropped++;
> >                         priv->stats.rx_errors++;
> >                 }
> >
> > +               memcpy(skb->data, priv->rx_buf[rx_head], len);

Is this memcpy() aligned?
If the hardware can receive to a 4n+2 offset it is probably better to
copy the two bytes before the frame data and to round the length of to
a whole number of words.

> >                 skb_put(skb, len);
> >                 skb->protocol = eth_type_trans(skb, ndev);
> >                 napi_gro_receive(&priv->napi, skb);
> 
> While this seems correct, I wonder why you don't do the normal approach of
> dequeuing the skb from the chain and adding a newly allocated skb to it to
> save the memcpy.

Because the receive buffer area isn't made of skbs.
Post-allocating the skb also reduces the 'true size' of the skb.

	David

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-26  9:10           ` David Laight
  0 siblings, 0 replies; 41+ messages in thread
From: David Laight @ 2014-08-26  9:10 UTC (permalink / raw)
  To: linux-arm-kernel

From: Arnd Bergmann
> On Monday 25 August 2014 16:22:22 Jonas Jensen wrote:
> > @@ -226,13 +226,15 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
> >                 if (len > RX_BUF_SIZE)
> >                         len = RX_BUF_SIZE;
> >
> > -               skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
> > +               skb = netdev_alloc_skb_ip_align(ndev, len);
> > +
> >                 if (unlikely(!skb)) {
> > -                       net_dbg_ratelimited("build_skb failed\n");
> > +                       net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
> >                         priv->stats.rx_dropped++;
> >                         priv->stats.rx_errors++;
> >                 }
> >
> > +               memcpy(skb->data, priv->rx_buf[rx_head], len);

Is this memcpy() aligned?
If the hardware can receive to a 4n+2 offset it is probably better to
copy the two bytes before the frame data and to round the length of to
a whole number of words.

> >                 skb_put(skb, len);
> >                 skb->protocol = eth_type_trans(skb, ndev);
> >                 napi_gro_receive(&priv->napi, skb);
> 
> While this seems correct, I wonder why you don't do the normal approach of
> dequeuing the skb from the chain and adding a newly allocated skb to it to
> save the memcpy.

Because the receive buffer area isn't made of skbs.
Post-allocating the skb also reduces the 'true size' of the skb.

	David

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
  2014-08-26  9:10           ` David Laight
  (?)
@ 2014-08-26 10:55             ` Eric Dumazet
  -1 siblings, 0 replies; 41+ messages in thread
From: Eric Dumazet @ 2014-08-26 10:55 UTC (permalink / raw)
  To: David Laight
  Cc: 'Arnd Bergmann',
	linux-arm-kernel, Jonas Jensen, netdev, f.fainelli, linux-kernel,
	mirqus, davem

On Tue, 2014-08-26 at 09:10 +0000, David Laight wrote:
> From: Arnd Bergmann

> > While this seems correct, I wonder why you don't do the normal approach of
> > dequeuing the skb from the chain and adding a newly allocated skb to it to
> > save the memcpy.
> 
> Because the receive buffer area isn't made of skbs.
> Post-allocating the skb also reduces the 'true size' of the skb.

This strategy assumes this is not a 10Gbe NIC.

We try to avoid copies because they are generally not needed.

Wifi devices are usually slow, and packet losses are more frequent, so
the copybreak gives better chance to not doing the collapses [1] later
in the TCP stack.

[1] collapses : reducing skb overhead (skb->len / skb->truesize ratio)



^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-26 10:55             ` Eric Dumazet
  0 siblings, 0 replies; 41+ messages in thread
From: Eric Dumazet @ 2014-08-26 10:55 UTC (permalink / raw)
  To: David Laight
  Cc: 'Arnd Bergmann',
	linux-arm-kernel, Jonas Jensen, netdev, f.fainelli, linux-kernel,
	mirqus, davem

On Tue, 2014-08-26 at 09:10 +0000, David Laight wrote:
> From: Arnd Bergmann

> > While this seems correct, I wonder why you don't do the normal approach of
> > dequeuing the skb from the chain and adding a newly allocated skb to it to
> > save the memcpy.
> 
> Because the receive buffer area isn't made of skbs.
> Post-allocating the skb also reduces the 'true size' of the skb.

This strategy assumes this is not a 10Gbe NIC.

We try to avoid copies because they are generally not needed.

Wifi devices are usually slow, and packet losses are more frequent, so
the copybreak gives better chance to not doing the collapses [1] later
in the TCP stack.

[1] collapses : reducing skb overhead (skb->len / skb->truesize ratio)

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v6 2/4] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()
@ 2014-08-26 10:55             ` Eric Dumazet
  0 siblings, 0 replies; 41+ messages in thread
From: Eric Dumazet @ 2014-08-26 10:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2014-08-26 at 09:10 +0000, David Laight wrote:
> From: Arnd Bergmann

> > While this seems correct, I wonder why you don't do the normal approach of
> > dequeuing the skb from the chain and adding a newly allocated skb to it to
> > save the memcpy.
> 
> Because the receive buffer area isn't made of skbs.
> Post-allocating the skb also reduces the 'true size' of the skb.

This strategy assumes this is not a 10Gbe NIC.

We try to avoid copies because they are generally not needed.

Wifi devices are usually slow, and packet losses are more frequent, so
the copybreak gives better chance to not doing the collapses [1] later
in the TCP stack.

[1] collapses : reducing skb overhead (skb->len / skb->truesize ratio)

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2014-08-26 10:55 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-19 14:49 [PATCH v4 1/2] net: moxa: clear TX descriptor length bits Jonas Jensen
2014-08-19 14:49 ` Jonas Jensen
2014-08-19 14:49 ` [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy() Jonas Jensen
2014-08-19 14:49   ` Jonas Jensen
2014-08-19 18:31   ` Eric Dumazet
2014-08-19 18:31     ` Eric Dumazet
2014-08-20 14:24     ` Jonas Jensen
2014-08-20 14:24       ` Jonas Jensen
2014-08-20 14:24       ` Jonas Jensen
2014-08-20 14:19   ` [PATCH v5 " Jonas Jensen
2014-08-20 14:19     ` Jonas Jensen
2014-08-25 14:22     ` [PATCH v6 2/4] " Jonas Jensen
2014-08-25 14:22       ` Jonas Jensen
2014-08-26  0:26       ` David Miller
2014-08-26  0:26         ` David Miller
2014-08-26  9:04       ` Arnd Bergmann
2014-08-26  9:04         ` Arnd Bergmann
2014-08-26  9:10         ` David Laight
2014-08-26  9:10           ` David Laight
2014-08-26  9:10           ` David Laight
2014-08-26 10:55           ` Eric Dumazet
2014-08-26 10:55             ` Eric Dumazet
2014-08-26 10:55             ` Eric Dumazet
2014-08-21 21:43   ` [PATCH v4 2/2] " Michał Mirosław
2014-08-21 21:43     ` Michał Mirosław
2014-08-21 21:43     ` Michał Mirosław
2014-08-25 14:23     ` Jonas Jensen
2014-08-25 14:23       ` Jonas Jensen
2014-08-25 14:23       ` Jonas Jensen
2014-08-20 14:18 ` [PATCH v5 1/2] net: moxa: clear TX descriptor length bits Jonas Jensen
2014-08-20 14:18   ` Jonas Jensen
2014-08-20 17:10   ` Eric Dumazet
2014-08-20 17:10     ` Eric Dumazet
2014-08-25 14:23     ` Jonas Jensen
2014-08-25 14:23       ` Jonas Jensen
2014-08-22  4:39   ` David Miller
2014-08-22  4:39     ` David Miller
2014-08-25 14:22   ` [PATCH v6 1/4] net: moxa: clear DESC1 on ndo_start_xmit() Jonas Jensen
2014-08-25 14:22     ` Jonas Jensen
2014-08-26  0:25     ` David Miller
2014-08-26  0:25       ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.