From ddba52024fdac1405b44a5f885681e4e6c123958 Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Mon, 18 Sep 2023 10:32:05 +0200 Subject: [PATCH] backport thunderbolt-net fixes A user of ours reported an issue with p2p thunderbolt-net w.r.t. IPv6 and failure to reestablish the connection after a reboot of a peer node, in the forum [0] and the relayed it upstream, so lets cherry-pick those two patches to our 6.2. Especially the IPv6 one seems straight forward, and the other one makes it actually spec conform and should only improve things. [0]: https://forum.proxmox.com/threads/133104/ Signed-off-by: Thomas Lamprecht --- ...t-Fix-TCPv6-GSO-checksum-calculation.patch | 42 ++++++ ...art-XDomain-discovery-handshake-afte.patch | 134 ++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 patches/kernel/0014-net-thunderbolt-Fix-TCPv6-GSO-checksum-calculation.patch create mode 100644 patches/kernel/0015-thunderbolt-Restart-XDomain-discovery-handshake-afte.patch diff --git a/patches/kernel/0014-net-thunderbolt-Fix-TCPv6-GSO-checksum-calculation.patch b/patches/kernel/0014-net-thunderbolt-Fix-TCPv6-GSO-checksum-calculation.patch new file mode 100644 index 0000000..4bae939 --- /dev/null +++ b/patches/kernel/0014-net-thunderbolt-Fix-TCPv6-GSO-checksum-calculation.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Wed, 13 Sep 2023 08:26:47 +0300 +Subject: [PATCH] net: thunderbolt: Fix TCPv6 GSO checksum calculation + +Alex reported that running ssh over IPv6 does not work with +Thunderbolt/USB4 networking driver. The reason for that is that driver +should call skb_is_gso() before calling skb_is_gso_v6(), and it should +not return false after calculates the checksum successfully. This probably +was a copy paste error from the original driver where it was done properly. + +Reported-by: Alex Balcanquall +Fixes: e69b6c02b4c3 ("net: Add support for networking over Thunderbolt cable") +Cc: stable@vger.kernel.org +Signed-off-by: Mika Westerberg +Reviewed-by: Eric Dumazet +Reviewed-by: Jiri Pirko +Reviewed-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Thomas Lamprecht +--- + drivers/net/thunderbolt.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c +index 990484776f2d..0c554a7a5ce4 100644 +--- a/drivers/net/thunderbolt.c ++++ b/drivers/net/thunderbolt.c +@@ -1005,12 +1005,11 @@ static bool tbnet_xmit_csum_and_map(struct tbnet *net, struct sk_buff *skb, + *tucso = ~csum_tcpudp_magic(ip_hdr(skb)->saddr, + ip_hdr(skb)->daddr, 0, + ip_hdr(skb)->protocol, 0); +- } else if (skb_is_gso_v6(skb)) { ++ } else if (skb_is_gso(skb) && skb_is_gso_v6(skb)) { + tucso = dest + ((void *)&(tcp_hdr(skb)->check) - data); + *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, 0, + IPPROTO_TCP, 0); +- return false; + } else if (protocol == htons(ETH_P_IPV6)) { + tucso = dest + skb_checksum_start_offset(skb) + skb->csum_offset; + *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, diff --git a/patches/kernel/0015-thunderbolt-Restart-XDomain-discovery-handshake-afte.patch b/patches/kernel/0015-thunderbolt-Restart-XDomain-discovery-handshake-afte.patch new file mode 100644 index 0000000..d15296e --- /dev/null +++ b/patches/kernel/0015-thunderbolt-Restart-XDomain-discovery-handshake-afte.patch @@ -0,0 +1,134 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Thu, 7 Sep 2023 16:02:30 +0300 +Subject: [PATCH] thunderbolt: Restart XDomain discovery handshake after + failure + +Alex reported that after rebooting the other host the peer-to-peer link +does not come up anymore. The reason for this is that the host that was +not rebooted tries to send the UUID request only 10 times according to +the USB4 Inter-Domain spec and gives up if it does not get reply. Then +when the other side is actually ready it cannot get the link established +anymore. The USB4 Inter-Domain spec requires that the discovery protocol +is restarted in that case so implement this now. + +Reported-by: Alex Balcanquall +Fixes: 8e1de7042596 ("thunderbolt: Add support for XDomain lane bonding") +Cc: stable@vger.kernel.org +Signed-off-by: Mika Westerberg +Signed-off-by: Thomas Lamprecht +--- + drivers/thunderbolt/xdomain.c | 58 +++++++++++++++++++++++++---------- + 1 file changed, 41 insertions(+), 17 deletions(-) + +diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c +index 3c51e47dd86b..0b17a4d4e9b9 100644 +--- a/drivers/thunderbolt/xdomain.c ++++ b/drivers/thunderbolt/xdomain.c +@@ -704,6 +704,27 @@ static void update_property_block(struct tb_xdomain *xd) + mutex_unlock(&xdomain_lock); + } + ++static void start_handshake(struct tb_xdomain *xd) ++{ ++ xd->state = XDOMAIN_STATE_INIT; ++ queue_delayed_work(xd->tb->wq, &xd->state_work, ++ msecs_to_jiffies(XDOMAIN_SHORT_TIMEOUT)); ++} ++ ++/* Can be called from state_work */ ++static void __stop_handshake(struct tb_xdomain *xd) ++{ ++ cancel_delayed_work_sync(&xd->properties_changed_work); ++ xd->properties_changed_retries = 0; ++ xd->state_retries = 0; ++} ++ ++static void stop_handshake(struct tb_xdomain *xd) ++{ ++ cancel_delayed_work_sync(&xd->state_work); ++ __stop_handshake(xd); ++} ++ + static void tb_xdp_handle_request(struct work_struct *work) + { + struct xdomain_request_work *xw = container_of(work, typeof(*xw), work); +@@ -766,6 +787,15 @@ static void tb_xdp_handle_request(struct work_struct *work) + case UUID_REQUEST: + tb_dbg(tb, "%llx: received XDomain UUID request\n", route); + ret = tb_xdp_uuid_response(ctl, route, sequence, uuid); ++ /* ++ * If we've stopped the discovery with an error such as ++ * timing out, we will restart the handshake now that we ++ * received UUID request from the remote host. ++ */ ++ if (!ret && xd && xd->state == XDOMAIN_STATE_ERROR) { ++ dev_dbg(&xd->dev, "restarting handshake\n"); ++ start_handshake(xd); ++ } + break; + + case LINK_STATE_STATUS_REQUEST: +@@ -1522,6 +1552,13 @@ static void tb_xdomain_queue_properties_changed(struct tb_xdomain *xd) + msecs_to_jiffies(XDOMAIN_SHORT_TIMEOUT)); + } + ++static void tb_xdomain_failed(struct tb_xdomain *xd) ++{ ++ xd->state = XDOMAIN_STATE_ERROR; ++ queue_delayed_work(xd->tb->wq, &xd->state_work, ++ msecs_to_jiffies(XDOMAIN_DEFAULT_TIMEOUT)); ++} ++ + static void tb_xdomain_state_work(struct work_struct *work) + { + struct tb_xdomain *xd = container_of(work, typeof(*xd), state_work.work); +@@ -1548,7 +1585,7 @@ static void tb_xdomain_state_work(struct work_struct *work) + if (ret) { + if (ret == -EAGAIN) + goto retry_state; +- xd->state = XDOMAIN_STATE_ERROR; ++ tb_xdomain_failed(xd); + } else { + tb_xdomain_queue_properties_changed(xd); + if (xd->bonding_possible) +@@ -1613,7 +1650,7 @@ static void tb_xdomain_state_work(struct work_struct *work) + if (ret) { + if (ret == -EAGAIN) + goto retry_state; +- xd->state = XDOMAIN_STATE_ERROR; ++ tb_xdomain_failed(xd); + } else { + xd->state = XDOMAIN_STATE_ENUMERATED; + } +@@ -1624,6 +1661,8 @@ static void tb_xdomain_state_work(struct work_struct *work) + break; + + case XDOMAIN_STATE_ERROR: ++ dev_dbg(&xd->dev, "discovery failed, stopping handshake\n"); ++ __stop_handshake(xd); + break; + + default: +@@ -1793,21 +1832,6 @@ static void tb_xdomain_release(struct device *dev) + kfree(xd); + } + +-static void start_handshake(struct tb_xdomain *xd) +-{ +- xd->state = XDOMAIN_STATE_INIT; +- queue_delayed_work(xd->tb->wq, &xd->state_work, +- msecs_to_jiffies(XDOMAIN_SHORT_TIMEOUT)); +-} +- +-static void stop_handshake(struct tb_xdomain *xd) +-{ +- cancel_delayed_work_sync(&xd->properties_changed_work); +- cancel_delayed_work_sync(&xd->state_work); +- xd->properties_changed_retries = 0; +- xd->state_retries = 0; +-} +- + static int __maybe_unused tb_xdomain_suspend(struct device *dev) + { + stop_handshake(tb_to_xdomain(dev)); -- 2.39.2