Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()

2014-08-25 Thread Jonas Jensen
Thanks for giving feedback.

On 21 August 2014 23:43, Michał Mirosław  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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()

2014-08-25 Thread Jonas Jensen
Thanks for giving feedback.

On 21 August 2014 23:43, Michał Mirosław mir...@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
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()

2014-08-21 Thread Michał Mirosław
2014-08-19 16:49 GMT+02:00 Jonas Jensen :
[...]
> 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(>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(>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(>napi, skb);
> rx++;

Best Regards,
Michał Mirosław
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()

2014-08-21 Thread Michał Mirosław
2014-08-19 16:49 GMT+02:00 Jonas Jensen jonas.jen...@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
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()

2014-08-20 Thread Jonas Jensen
On 19 August 2014 20:31, Eric Dumazet  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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()

2014-08-20 Thread Jonas Jensen
On 19 August 2014 20:31, Eric Dumazet eric.duma...@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
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()

2014-08-19 Thread Eric Dumazet
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())



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()

2014-08-19 Thread 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 
---

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(>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(>dev,
+  priv->rx_mapping[rx_head],
+  priv->rx_buf_size, DMA_FROM_DEVICE);
+
skb->protocol = eth_type_trans(skb, ndev);
napi_gro_receive(>napi, skb);
rx++;
-- 
1.8.2.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()

2014-08-19 Thread 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.jen...@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

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 2/2] net: moxa: replace build_skb() with netdev_alloc_skb_ip_align() / memcpy()

2014-08-19 Thread Eric Dumazet
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())



--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/