Re: [PATCH net] net/mlx5e: fix csum adjustments caused by RXFCS

2018-10-31 Thread David Miller
From: Eric Dumazet 
Date: Tue, 30 Oct 2018 00:57:25 -0700

> As shown by Dmitris, we need to use csum_block_add() instead of csum_add()
> when adding the FCS contribution to skb csum.
> 
> Before 4.18 (more exactly commit 88078d98d1bb "net: pskb_trim_rcsum()
> and CHECKSUM_COMPLETE are friends"), the whole skb csum was thrown away,
> so RXFCS changes were ignored.
> 
> Then before commit d55bef5059dd ("net: fix pskb_trim_rcsum_slow() with
> odd trim offset") both mlx5 and pskb_trim_rcsum_slow() bugs were canceling
> each other.
> 
> Now we fixed pskb_trim_rcsum_slow() we need to fix mlx5.
> 
> Note that this patch also rewrites mlx5e_get_fcs() to :
> 
> - Use skb_header_pointer() instead of reinventing it.
> - Use __get_unaligned_cpu32() to avoid possible non aligned accesses
>   as Dmitris pointed out.
> 
> Fixes: 902a545904c7 ("net/mlx5e: When RXFCS is set, add FCS data into 
> checksum calculation")
> Reported-by: Paweł Staszewski 
> Signed-off-by: Eric Dumazet 

Applied and queued up for -stable.


Re: [PATCH net] net/mlx5e: fix csum adjustments caused by RXFCS

2018-10-31 Thread Eran Ben Elisha


On 10/30/2018 9:57 AM, Eric Dumazet wrote:
> As shown by Dmitris, we need to use csum_block_add() instead of csum_add()
> when adding the FCS contribution to skb csum.
> 
> Before 4.18 (more exactly commit 88078d98d1bb "net: pskb_trim_rcsum()
> and CHECKSUM_COMPLETE are friends"), the whole skb csum was thrown away,
> so RXFCS changes were ignored.
> 
> Then before commit d55bef5059dd ("net: fix pskb_trim_rcsum_slow() with
> odd trim offset") both mlx5 and pskb_trim_rcsum_slow() bugs were canceling
> each other.
> 
> Now we fixed pskb_trim_rcsum_slow() we need to fix mlx5.
> 
> Note that this patch also rewrites mlx5e_get_fcs() to :
> 
> - Use skb_header_pointer() instead of reinventing it.
> - Use __get_unaligned_cpu32() to avoid possible non aligned accesses
>as Dmitris pointed out.
> 
> Fixes: 902a545904c7 ("net/mlx5e: When RXFCS is set, add FCS data into 
> checksum calculation")
> Reported-by: Paweł Staszewski 
> Signed-off-by: Eric Dumazet 
> Cc: Eran Ben Elisha 
> Cc: Saeed Mahameed 
> Cc: Dimitris Michailidis 
> Cc: Cong Wang 
> Cc: Paweł Staszewski 
> ---
>   .../net/ethernet/mellanox/mlx5/core/en_rx.c   | 45 ---
>   1 file changed, 9 insertions(+), 36 deletions(-)

Thanks for the modification!
We run a direct test we had for this scenario and it passed.

Reviewed-by: Eran Ben Elisha 
Tested-By: Maria Pasechnik 


Re: [PATCH net] net/mlx5e: fix csum adjustments caused by RXFCS

2018-10-30 Thread Eric Dumazet
On Tue, Oct 30, 2018 at 11:59 AM Cong Wang  wrote:

> I wonder how compiler recognizes it as "never fail" when marked with
> __must_check.

__must_check means that you can not ignore the return value of a function.

Here we do use the return value.

Also prior code was not checking skb->length so really my patch does
add explicit
check if in the future skb->len gets wrong after a bug is added in this driver.

(A NULL deref will trap the bug, instead of potentially reading
garbage from skb->data)


Re: [PATCH net] net/mlx5e: fix csum adjustments caused by RXFCS

2018-10-30 Thread Cong Wang
On Tue, Oct 30, 2018 at 11:42 AM Eric Dumazet  wrote:
>
> On Tue, Oct 30, 2018 at 11:09 AM Cong Wang  wrote:
>
> > At least skb_header_pointer() is marked as __must_check, I don't see
> > you check its return value here.
>
> This can not fail here.
>
> skb->length must be above 14+4 at this point.

Never say it is wrong, just saying what compiler thinks.

>
> My compiler seems to be okay with that.

I wonder how compiler recognizes it as "never fail" when marked with
__must_check.


Re: [PATCH net] net/mlx5e: fix csum adjustments caused by RXFCS

2018-10-30 Thread David Miller
From: Cong Wang 
Date: Tue, 30 Oct 2018 11:09:21 -0700

> On Tue, Oct 30, 2018 at 12:57 AM Eric Dumazet  wrote:
>> -static __be32 mlx5e_get_fcs(struct sk_buff *skb)
>> +static u32 mlx5e_get_fcs(const struct sk_buff *skb)
>>  {
>> -   int last_frag_sz, bytes_in_prev, nr_frags;
>> -   u8 *fcs_p1, *fcs_p2;
>> -   skb_frag_t *last_frag;
>> -   __be32 fcs_bytes;
>> +   const void *fcs_bytes;
>> +   u32 _fcs_bytes;
>>
>> -   if (!skb_is_nonlinear(skb))
>> -   return *(__be32 *)(skb->data + skb->len - ETH_FCS_LEN);
>> +   fcs_bytes = skb_header_pointer(skb, skb->len - ETH_FCS_LEN,
>> +  ETH_FCS_LEN, &_fcs_bytes);
> 
> At least skb_header_pointer() is marked as __must_check, I don't see
> you check its return value here.

In this case we reasonably know it is guaranteed to succeed though.

We know skb->len is non-zero and we are asking for the skb->len - 1
byte or something like that.


Re: [PATCH net] net/mlx5e: fix csum adjustments caused by RXFCS

2018-10-30 Thread Eric Dumazet
On Tue, Oct 30, 2018 at 11:09 AM Cong Wang  wrote:

> At least skb_header_pointer() is marked as __must_check, I don't see
> you check its return value here.

This can not fail here.

skb->length must be above 14+4 at this point.

My compiler seems to be okay with that.


Re: [PATCH net] net/mlx5e: fix csum adjustments caused by RXFCS

2018-10-30 Thread Cong Wang
On Tue, Oct 30, 2018 at 12:57 AM Eric Dumazet  wrote:
> -static __be32 mlx5e_get_fcs(struct sk_buff *skb)
> +static u32 mlx5e_get_fcs(const struct sk_buff *skb)
>  {
> -   int last_frag_sz, bytes_in_prev, nr_frags;
> -   u8 *fcs_p1, *fcs_p2;
> -   skb_frag_t *last_frag;
> -   __be32 fcs_bytes;
> +   const void *fcs_bytes;
> +   u32 _fcs_bytes;
>
> -   if (!skb_is_nonlinear(skb))
> -   return *(__be32 *)(skb->data + skb->len - ETH_FCS_LEN);
> +   fcs_bytes = skb_header_pointer(skb, skb->len - ETH_FCS_LEN,
> +  ETH_FCS_LEN, &_fcs_bytes);

At least skb_header_pointer() is marked as __must_check, I don't see
you check its return value here.


[PATCH net] net/mlx5e: fix csum adjustments caused by RXFCS

2018-10-30 Thread Eric Dumazet
As shown by Dmitris, we need to use csum_block_add() instead of csum_add()
when adding the FCS contribution to skb csum.

Before 4.18 (more exactly commit 88078d98d1bb "net: pskb_trim_rcsum()
and CHECKSUM_COMPLETE are friends"), the whole skb csum was thrown away,
so RXFCS changes were ignored.

Then before commit d55bef5059dd ("net: fix pskb_trim_rcsum_slow() with
odd trim offset") both mlx5 and pskb_trim_rcsum_slow() bugs were canceling
each other.

Now we fixed pskb_trim_rcsum_slow() we need to fix mlx5.

Note that this patch also rewrites mlx5e_get_fcs() to :

- Use skb_header_pointer() instead of reinventing it.
- Use __get_unaligned_cpu32() to avoid possible non aligned accesses
  as Dmitris pointed out.

Fixes: 902a545904c7 ("net/mlx5e: When RXFCS is set, add FCS data into checksum 
calculation")
Reported-by: Paweł Staszewski 
Signed-off-by: Eric Dumazet 
Cc: Eran Ben Elisha 
Cc: Saeed Mahameed 
Cc: Dimitris Michailidis 
Cc: Cong Wang 
Cc: Paweł Staszewski 
---
 .../net/ethernet/mellanox/mlx5/core/en_rx.c   | 45 ---
 1 file changed, 9 insertions(+), 36 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c 
b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 
94224c22ecc310a87b6715051e335446f29bec03..79638dcbae78395fb723c9bf3fa877e7a42d91cd
 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -713,43 +713,15 @@ static inline void mlx5e_enable_ecn(struct mlx5e_rq *rq, 
struct sk_buff *skb)
rq->stats->ecn_mark += !!rc;
 }
 
-static __be32 mlx5e_get_fcs(struct sk_buff *skb)
+static u32 mlx5e_get_fcs(const struct sk_buff *skb)
 {
-   int last_frag_sz, bytes_in_prev, nr_frags;
-   u8 *fcs_p1, *fcs_p2;
-   skb_frag_t *last_frag;
-   __be32 fcs_bytes;
+   const void *fcs_bytes;
+   u32 _fcs_bytes;
 
-   if (!skb_is_nonlinear(skb))
-   return *(__be32 *)(skb->data + skb->len - ETH_FCS_LEN);
+   fcs_bytes = skb_header_pointer(skb, skb->len - ETH_FCS_LEN,
+  ETH_FCS_LEN, &_fcs_bytes);
 
-   nr_frags = skb_shinfo(skb)->nr_frags;
-   last_frag = &skb_shinfo(skb)->frags[nr_frags - 1];
-   last_frag_sz = skb_frag_size(last_frag);
-
-   /* If all FCS data is in last frag */
-   if (last_frag_sz >= ETH_FCS_LEN)
-   return *(__be32 *)(skb_frag_address(last_frag) +
-  last_frag_sz - ETH_FCS_LEN);
-
-   fcs_p2 = (u8 *)skb_frag_address(last_frag);
-   bytes_in_prev = ETH_FCS_LEN - last_frag_sz;
-
-   /* Find where the other part of the FCS is - Linear or another frag */
-   if (nr_frags == 1) {
-   fcs_p1 = skb_tail_pointer(skb);
-   } else {
-   skb_frag_t *prev_frag = &skb_shinfo(skb)->frags[nr_frags - 2];
-
-   fcs_p1 = skb_frag_address(prev_frag) +
-   skb_frag_size(prev_frag);
-   }
-   fcs_p1 -= bytes_in_prev;
-
-   memcpy(&fcs_bytes, fcs_p1, bytes_in_prev);
-   memcpy(((u8 *)&fcs_bytes) + bytes_in_prev, fcs_p2, last_frag_sz);
-
-   return fcs_bytes;
+   return __get_unaligned_cpu32(fcs_bytes);
 }
 
 static u8 get_ip_proto(struct sk_buff *skb, __be16 proto)
@@ -797,8 +769,9 @@ static inline void mlx5e_handle_csum(struct net_device 
*netdev,
 network_depth - ETH_HLEN,
 skb->csum);
if (unlikely(netdev->features & NETIF_F_RXFCS))
-   skb->csum = csum_add(skb->csum,
-(__force 
__wsum)mlx5e_get_fcs(skb));
+   skb->csum = csum_block_add(skb->csum,
+  (__force 
__wsum)mlx5e_get_fcs(skb),
+  skb->len - ETH_FCS_LEN);
stats->csum_complete++;
return;
}
-- 
2.19.1.568.g152ad8e336-goog