[SRU][Xenial][PATCH 0/1] s390/qeth: fix underestimated count of buffer elements

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[SRU][Xenial][PATCH 0/1] s390/qeth: fix underestimated count of buffer elements

Joseph Salisbury-3
BugLink: http://bugs.launchpad.net/bugs/1750810

== SRU Justification ==
Mainline commit 89271c65ed fixes the calculation of required buffer elements for skb.

Problem: skbs of certain lengths cause qeth to miscalculate the
              number of needed IO buffer elements, resulting in
              malformed TX buffer descriptors. When such a buffer is
              presented to the HW, it triggers a Subchannel Program
              Check. qeth handles this by starting device recovery.

Solution: Fix the buffer element calculation, so that qeth builds
              proper TX buffer descriptors.

== Fix ==
commit 89271c65edd599207dd982007900506283c90ae3
Author: Ursula Braun <[hidden email]>
Date:   Fri Feb 9 11:03:49 2018 +0100

    s390/qeth: fix underestimated count of buffer elements


== Regression Potential ==
Low.  Limited to s390.

Ursula Braun (1):
  s390/qeth: fix underestimated count of buffer elements

 drivers/s390/net/qeth_core_main.c | 4 ++--
 drivers/s390/net/qeth_l3_main.c   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

--
2.7.4


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][Xenial][PATCH 1/1] s390/qeth: fix underestimated count of buffer elements

Joseph Salisbury-3
From: Ursula Braun <[hidden email]>

BugLink: http://bugs.launchpad.net/bugs/1750810

For a memory range/skb where the last byte falls onto a page boundary
(ie. 'end' is of the form xxx...xxx001), the PFN_UP() part of the
calculation currently doesn't round up to the next PFN due to an
off-by-one error.
Thus qeth believes that the skb occupies one page less than it
actually does, and may select a IO buffer that doesn't have enough spare
buffer elements to fit all of the skb's data.
HW detects this as a malformed buffer descriptor, and raises an
exception which then triggers device recovery.

Fixes: 2863c61334aa ("qeth: refactor calculation of SBALE count")
Signed-off-by: Ursula Braun <[hidden email]>
Signed-off-by: Julian Wiedmann <[hidden email]>
Signed-off-by: David S. Miller <[hidden email]>
(back ported from commit 89271c65edd599207dd982007900506283c90ae3)
[jwi: backport to older kernels, so that it also
 Fixes: 51aa165c9f27 ("qeth: fix page breaks in hw headers")]
Signed-off-by: Joseph Salisbury <[hidden email]>
---
 drivers/s390/net/qeth_core_main.c | 4 ++--
 drivers/s390/net/qeth_l3_main.c   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index e5b9506..63f8583 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3822,7 +3822,7 @@ int qeth_get_elements_for_frags(struct sk_buff *skb)
  data = (char *)page_to_phys(skb_frag_page(frag)) +
  frag->page_offset;
  length = frag->size;
- e = PFN_UP((unsigned long)data + length - 1) -
+ e = PFN_UP((unsigned long)data + length) -
  PFN_DOWN((unsigned long)data);
  elements += e;
  }
@@ -3834,7 +3834,7 @@ int qeth_get_elements_no(struct qeth_card *card,
      struct sk_buff *skb, int elems)
 {
  int dlen = skb->len - skb->data_len;
- int elements_needed = PFN_UP((unsigned long)skb->data + dlen - 1) -
+ int elements_needed = PFN_UP((unsigned long)skb->data + dlen) -
  PFN_DOWN((unsigned long)skb->data);
 
  elements_needed += qeth_get_elements_for_frags(skb);
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index bf3c1b2..e313127 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2819,7 +2819,7 @@ static inline int qeth_l3_tso_elements(struct sk_buff *skb)
  unsigned long tcpd = (unsigned long)tcp_hdr(skb) +
  tcp_hdr(skb)->doff * 4;
  int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data);
- int elements = PFN_UP(tcpd + tcpd_len - 1) - PFN_DOWN(tcpd);
+ int elements = PFN_UP(tcpd + tcpd_len) - PFN_DOWN(tcpd);
 
  elements += qeth_get_elements_for_frags(skb);
 
--
2.7.4


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

ACK: [SRU][Xenial][PATCH 1/1] s390/qeth: fix underestimated count of buffer elements

Stefan Bader-2
On 07.03.2018 10:43, Joseph Salisbury wrote:

> From: Ursula Braun <[hidden email]>
>
> BugLink: http://bugs.launchpad.net/bugs/1750810
>
> For a memory range/skb where the last byte falls onto a page boundary
> (ie. 'end' is of the form xxx...xxx001), the PFN_UP() part of the
> calculation currently doesn't round up to the next PFN due to an
> off-by-one error.
> Thus qeth believes that the skb occupies one page less than it
> actually does, and may select a IO buffer that doesn't have enough spare
> buffer elements to fit all of the skb's data.
> HW detects this as a malformed buffer descriptor, and raises an
> exception which then triggers device recovery.
>
> Fixes: 2863c61334aa ("qeth: refactor calculation of SBALE count")
> Signed-off-by: Ursula Braun <[hidden email]>
> Signed-off-by: Julian Wiedmann <[hidden email]>
> Signed-off-by: David S. Miller <[hidden email]>
> (back ported from commit 89271c65edd599207dd982007900506283c90ae3)
> [jwi: backport to older kernels, so that it also
>  Fixes: 51aa165c9f27 ("qeth: fix page breaks in hw headers")]
> Signed-off-by: Joseph Salisbury <[hidden email]>
Acked-by: Stefan Bader <[hidden email]>

> ---
>  drivers/s390/net/qeth_core_main.c | 4 ++--
>  drivers/s390/net/qeth_l3_main.c   | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
> index e5b9506..63f8583 100644
> --- a/drivers/s390/net/qeth_core_main.c
> +++ b/drivers/s390/net/qeth_core_main.c
> @@ -3822,7 +3822,7 @@ int qeth_get_elements_for_frags(struct sk_buff *skb)
>   data = (char *)page_to_phys(skb_frag_page(frag)) +
>   frag->page_offset;
>   length = frag->size;
> - e = PFN_UP((unsigned long)data + length - 1) -
> + e = PFN_UP((unsigned long)data + length) -
>   PFN_DOWN((unsigned long)data);
>   elements += e;
>   }
> @@ -3834,7 +3834,7 @@ int qeth_get_elements_no(struct qeth_card *card,
>       struct sk_buff *skb, int elems)
>  {
>   int dlen = skb->len - skb->data_len;
> - int elements_needed = PFN_UP((unsigned long)skb->data + dlen - 1) -
> + int elements_needed = PFN_UP((unsigned long)skb->data + dlen) -
>   PFN_DOWN((unsigned long)skb->data);
>  
>   elements_needed += qeth_get_elements_for_frags(skb);
> diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
> index bf3c1b2..e313127 100644
> --- a/drivers/s390/net/qeth_l3_main.c
> +++ b/drivers/s390/net/qeth_l3_main.c
> @@ -2819,7 +2819,7 @@ static inline int qeth_l3_tso_elements(struct sk_buff *skb)
>   unsigned long tcpd = (unsigned long)tcp_hdr(skb) +
>   tcp_hdr(skb)->doff * 4;
>   int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data);
> - int elements = PFN_UP(tcpd + tcpd_len - 1) - PFN_DOWN(tcpd);
> + int elements = PFN_UP(tcpd + tcpd_len) - PFN_DOWN(tcpd);
>  
>   elements += qeth_get_elements_for_frags(skb);
>  
>


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

ACK: [SRU][Xenial][PATCH 1/1] s390/qeth: fix underestimated count of buffer elements

Kleber Souza
In reply to this post by Joseph Salisbury-3
On 03/07/18 10:43, Joseph Salisbury wrote:

> From: Ursula Braun <[hidden email]>
>
> BugLink: http://bugs.launchpad.net/bugs/1750810
>
> For a memory range/skb where the last byte falls onto a page boundary
> (ie. 'end' is of the form xxx...xxx001), the PFN_UP() part of the
> calculation currently doesn't round up to the next PFN due to an
> off-by-one error.
> Thus qeth believes that the skb occupies one page less than it
> actually does, and may select a IO buffer that doesn't have enough spare
> buffer elements to fit all of the skb's data.
> HW detects this as a malformed buffer descriptor, and raises an
> exception which then triggers device recovery.
>
> Fixes: 2863c61334aa ("qeth: refactor calculation of SBALE count")
> Signed-off-by: Ursula Braun <[hidden email]>
> Signed-off-by: Julian Wiedmann <[hidden email]>
> Signed-off-by: David S. Miller <[hidden email]>
> (back ported from commit 89271c65edd599207dd982007900506283c90ae3)
> [jwi: backport to older kernels, so that it also
>  Fixes: 51aa165c9f27 ("qeth: fix page breaks in hw headers")]
> Signed-off-by: Joseph Salisbury <[hidden email]>

Acked-by: Kleber Sacilotto de Souza <[hidden email]>

> ---
>  drivers/s390/net/qeth_core_main.c | 4 ++--
>  drivers/s390/net/qeth_l3_main.c   | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
> index e5b9506..63f8583 100644
> --- a/drivers/s390/net/qeth_core_main.c
> +++ b/drivers/s390/net/qeth_core_main.c
> @@ -3822,7 +3822,7 @@ int qeth_get_elements_for_frags(struct sk_buff *skb)
>   data = (char *)page_to_phys(skb_frag_page(frag)) +
>   frag->page_offset;
>   length = frag->size;
> - e = PFN_UP((unsigned long)data + length - 1) -
> + e = PFN_UP((unsigned long)data + length) -
>   PFN_DOWN((unsigned long)data);
>   elements += e;
>   }
> @@ -3834,7 +3834,7 @@ int qeth_get_elements_no(struct qeth_card *card,
>       struct sk_buff *skb, int elems)
>  {
>   int dlen = skb->len - skb->data_len;
> - int elements_needed = PFN_UP((unsigned long)skb->data + dlen - 1) -
> + int elements_needed = PFN_UP((unsigned long)skb->data + dlen) -
>   PFN_DOWN((unsigned long)skb->data);
>  
>   elements_needed += qeth_get_elements_for_frags(skb);
> diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
> index bf3c1b2..e313127 100644
> --- a/drivers/s390/net/qeth_l3_main.c
> +++ b/drivers/s390/net/qeth_l3_main.c
> @@ -2819,7 +2819,7 @@ static inline int qeth_l3_tso_elements(struct sk_buff *skb)
>   unsigned long tcpd = (unsigned long)tcp_hdr(skb) +
>   tcp_hdr(skb)->doff * 4;
>   int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data);
> - int elements = PFN_UP(tcpd + tcpd_len - 1) - PFN_DOWN(tcpd);
> + int elements = PFN_UP(tcpd + tcpd_len) - PFN_DOWN(tcpd);
>  
>   elements += qeth_get_elements_for_frags(skb);
>  
>

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

APPLIED: [SRU][Xenial][PATCH 1/1] s390/qeth: fix underestimated count of buffer elements

Kleber Souza
In reply to this post by Joseph Salisbury-3
On 03/07/18 10:43, Joseph Salisbury wrote:

> From: Ursula Braun <[hidden email]>
>
> BugLink: http://bugs.launchpad.net/bugs/1750810
>
> For a memory range/skb where the last byte falls onto a page boundary
> (ie. 'end' is of the form xxx...xxx001), the PFN_UP() part of the
> calculation currently doesn't round up to the next PFN due to an
> off-by-one error.
> Thus qeth believes that the skb occupies one page less than it
> actually does, and may select a IO buffer that doesn't have enough spare
> buffer elements to fit all of the skb's data.
> HW detects this as a malformed buffer descriptor, and raises an
> exception which then triggers device recovery.
>
> Fixes: 2863c61334aa ("qeth: refactor calculation of SBALE count")
> Signed-off-by: Ursula Braun <[hidden email]>
> Signed-off-by: Julian Wiedmann <[hidden email]>
> Signed-off-by: David S. Miller <[hidden email]>
> (back ported from commit 89271c65edd599207dd982007900506283c90ae3)
> [jwi: backport to older kernels, so that it also
>  Fixes: 51aa165c9f27 ("qeth: fix page breaks in hw headers")]
> Signed-off-by: Joseph Salisbury <[hidden email]>
> ---
>  drivers/s390/net/qeth_core_main.c | 4 ++--
>  drivers/s390/net/qeth_l3_main.c   | 2 +-
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
> index e5b9506..63f8583 100644
> --- a/drivers/s390/net/qeth_core_main.c
> +++ b/drivers/s390/net/qeth_core_main.c
> @@ -3822,7 +3822,7 @@ int qeth_get_elements_for_frags(struct sk_buff *skb)
>   data = (char *)page_to_phys(skb_frag_page(frag)) +
>   frag->page_offset;
>   length = frag->size;
> - e = PFN_UP((unsigned long)data + length - 1) -
> + e = PFN_UP((unsigned long)data + length) -
>   PFN_DOWN((unsigned long)data);
>   elements += e;
>   }
> @@ -3834,7 +3834,7 @@ int qeth_get_elements_no(struct qeth_card *card,
>       struct sk_buff *skb, int elems)
>  {
>   int dlen = skb->len - skb->data_len;
> - int elements_needed = PFN_UP((unsigned long)skb->data + dlen - 1) -
> + int elements_needed = PFN_UP((unsigned long)skb->data + dlen) -
>   PFN_DOWN((unsigned long)skb->data);
>  
>   elements_needed += qeth_get_elements_for_frags(skb);
> diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
> index bf3c1b2..e313127 100644
> --- a/drivers/s390/net/qeth_l3_main.c
> +++ b/drivers/s390/net/qeth_l3_main.c
> @@ -2819,7 +2819,7 @@ static inline int qeth_l3_tso_elements(struct sk_buff *skb)
>   unsigned long tcpd = (unsigned long)tcp_hdr(skb) +
>   tcp_hdr(skb)->doff * 4;
>   int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data);
> - int elements = PFN_UP(tcpd + tcpd_len - 1) - PFN_DOWN(tcpd);
> + int elements = PFN_UP(tcpd + tcpd_len) - PFN_DOWN(tcpd);
>  
>   elements += qeth_get_elements_for_frags(skb);
>  
>

Applied to xenial/master-next branch.

Thanks,
Kleber

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team