It was reported that on RTL8125 network breaks under heavy UDP load,
e.g. torrent traffic ([0], from comment 27). Realtek confirmed a hw bug
and provided me with a test version of the r8125 driver including a
workaround. Tests confirmed that the workaround fixes the issue.
I modified the original version of the workaround to meet mainline
code style.
[0] https://bugzilla.kernel.org/show_bug.cgi?id=209839
v2:
- rebased to net
v3:
- make rtl_skb_is_udp() more robust and use skb_header_pointer()
to access the ip(v6) header
Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125")
Tested-by: xplo <redacted>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
drivers/net/ethernet/realtek/r8169_main.c | 70 +++++++++++++++++++++--
1 file changed, 64 insertions(+), 6 deletions(-)
@@ -4046,17 +4047,70 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,return-EIO;}-staticboolrtl_test_hw_pad_bug(structrtl8169_private*tp)+staticboolrtl_skb_is_udp(structsk_buff*skb){+intno=skb_network_offset(skb);+structipv6hdr*i6h,_i6h;+structiphdr*ih,_ih;++switch(vlan_get_protocol(skb)){+casehtons(ETH_P_IP):+ih=skb_header_pointer(skb,no,sizeof(_ih),&_ih);+returnih&&ih->protocol==IPPROTO_UDP;+casehtons(ETH_P_IPV6):+i6h=skb_header_pointer(skb,no,sizeof(_i6h),&_i6h);+returni6h&&i6h->nexthdr==IPPROTO_UDP;+default:+returnfalse;+}+}++#define RTL_MIN_PATCH_LEN 47+#define PTP_GEN_PORT 320++/* see rtl8125_get_patch_pad_len() in r8125 vendor driver */+staticunsignedintrtl8125_quirk_udp_padto(structrtl8169_private*tp,+structsk_buff*skb)+{+unsignedintpadto=0,len=skb->len;++if(rtl_is_8125(tp)&&len<128+RTL_MIN_PATCH_LEN&&+rtl_skb_is_udp(skb)&&skb_transport_header_was_set(skb)){+unsignedinttrans_data_len=skb_tail_pointer(skb)-+skb_transport_header(skb);++if(trans_data_len>3&&trans_data_len<RTL_MIN_PATCH_LEN){+u16dest=ntohs(udp_hdr(skb)->dest);++if(dest==PTP_EV_PORT||dest==PTP_GEN_PORT)+padto=len+RTL_MIN_PATCH_LEN-trans_data_len;+}++if(trans_data_len<UDP_HLEN)+padto=max(padto,len+UDP_HLEN-trans_data_len);+}++returnpadto;+}++staticunsignedintrtl_quirk_packet_padto(structrtl8169_private*tp,+structsk_buff*skb)+{+unsignedintpadto;++padto=rtl8125_quirk_udp_padto(tp,skb);+switch(tp->mac_version){caseRTL_GIGA_MAC_VER_34:caseRTL_GIGA_MAC_VER_60:caseRTL_GIGA_MAC_VER_61:caseRTL_GIGA_MAC_VER_63:-returntrue;+padto=max_t(unsignedint,padto,ETH_ZLEN);default:-returnfalse;+break;}++returnpadto;}staticvoidrtl8169_tso_csum_v1(structsk_buff*skb,u32*opts)
@@ -4128,9 +4182,10 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,opts[1]|=transport_offset<<TCPHO_SHIFT;}else{-if(unlikely(skb->len<ETH_ZLEN&&rtl_test_hw_pad_bug(tp)))-/* eth_skb_pad would free the skb on error */-return!__skb_put_padto(skb,ETH_ZLEN,false);+unsignedintpadto=rtl_quirk_packet_padto(tp,skb);++/* skb_padto would free the skb on error */+return!__skb_put_padto(skb,padto,false);}returntrue;
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com> Date: 2021-01-28 18:40:21
On Thu, Jan 28, 2021 at 2:44 AM Heiner Kallweit [off-list ref] wrote:
quoted hunk
It was reported that on RTL8125 network breaks under heavy UDP load,
e.g. torrent traffic ([0], from comment 27). Realtek confirmed a hw bug
and provided me with a test version of the r8125 driver including a
workaround. Tests confirmed that the workaround fixes the issue.
I modified the original version of the workaround to meet mainline
code style.
[0] https://bugzilla.kernel.org/show_bug.cgi?id=209839
v2:
- rebased to net
v3:
- make rtl_skb_is_udp() more robust and use skb_header_pointer()
to access the ip(v6) header
Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125")
Tested-by: xplo <redacted>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
drivers/net/ethernet/realtek/r8169_main.c | 70 +++++++++++++++++++++--
1 file changed, 64 insertions(+), 6 deletions(-)
On Thu, Jan 28, 2021 at 2:44 AM Heiner Kallweit [off-list ref] wrote:
quoted
It was reported that on RTL8125 network breaks under heavy UDP load,
e.g. torrent traffic ([0], from comment 27). Realtek confirmed a hw bug
and provided me with a test version of the r8125 driver including a
workaround. Tests confirmed that the workaround fixes the issue.
I modified the original version of the workaround to meet mainline
code style.
[0] https://bugzilla.kernel.org/show_bug.cgi?id=209839
v2:
- rebased to net
v3:
- make rtl_skb_is_udp() more robust and use skb_header_pointer()
to access the ip(v6) header
Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125")
Tested-by: xplo <redacted>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
drivers/net/ethernet/realtek/r8169_main.c | 70 +++++++++++++++++++++--
1 file changed, 64 insertions(+), 6 deletions(-)
@@ -4128,9 +4182,10 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, opts[1] |= transport_offset << TCPHO_SHIFT; } else {- if (unlikely(skb->len < ETH_ZLEN && rtl_test_hw_pad_bug(tp)))- /* eth_skb_pad would free the skb on error */- return !__skb_put_padto(skb, ETH_ZLEN, false);+ unsigned int padto = rtl_quirk_packet_padto(tp, skb);++ /* skb_padto would free the skb on error */+ return !__skb_put_padto(skb, padto, false);
should this path still pad to ETH_ZLEN as a minimum when the other
cases do not hit?
For most chip versions that's not needed because hw does the padding
to ETH_ZLEN. Few chip versions have a hw bug and padding needs to be
done in sw, that's handled in rtl_quirk_packet_padto().
quoted
}
return true;
@@ -4307,6 +4362,9 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb, if (skb->len < ETH_ZLEN) features &= ~NETIF_F_CSUM_MASK;+ if (rtl_quirk_packet_padto(tp, skb))+ features &= ~NETIF_F_CSUM_MASK;+ if (transport_offset > TCPHO_MAX && rtl_chip_supports_csum_v2(tp)) features &= ~NETIF_F_CSUM_MASK;--
On Thu, Jan 28, 2021 at 2:44 AM Heiner Kallweit [off-list ref] wrote:
quoted
It was reported that on RTL8125 network breaks under heavy UDP load,
e.g. torrent traffic ([0], from comment 27). Realtek confirmed a hw bug
and provided me with a test version of the r8125 driver including a
workaround. Tests confirmed that the workaround fixes the issue.
I modified the original version of the workaround to meet mainline
code style.
[0] https://bugzilla.kernel.org/show_bug.cgi?id=209839
v2:
- rebased to net
v3:
- make rtl_skb_is_udp() more robust and use skb_header_pointer()
to access the ip(v6) header
Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125")
Tested-by: xplo <redacted>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
drivers/net/ethernet/realtek/r8169_main.c | 70 +++++++++++++++++++++--
1 file changed, 64 insertions(+), 6 deletions(-)
@@ -4128,9 +4182,10 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, opts[1] |= transport_offset << TCPHO_SHIFT; } else {- if (unlikely(skb->len < ETH_ZLEN && rtl_test_hw_pad_bug(tp)))- /* eth_skb_pad would free the skb on error */- return !__skb_put_padto(skb, ETH_ZLEN, false);+ unsigned int padto = rtl_quirk_packet_padto(tp, skb);++ /* skb_padto would free the skb on error */+ return !__skb_put_padto(skb, padto, false);
should this path still pad to ETH_ZLEN as a minimum when the other
cases do not hit?
For most chip versions that's not needed because hw does the padding
to ETH_ZLEN. Few chip versions have a hw bug and padding needs to be
done in sw, that's handled in rtl_quirk_packet_padto().
quoted
quoted
}
return true;
@@ -4307,6 +4362,9 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb, if (skb->len < ETH_ZLEN) features &= ~NETIF_F_CSUM_MASK;+ if (rtl_quirk_packet_padto(tp, skb))+ features &= ~NETIF_F_CSUM_MASK;+ if (transport_offset > TCPHO_MAX && rtl_chip_supports_csum_v2(tp)) features &= ~NETIF_F_CSUM_MASK;--