* [PATCH mptcp-next v4 0/2] mptcp: refactor MP_FAIL response @ 2022-06-09 0:00 Geliang Tang 2022-06-09 0:00 ` [PATCH mptcp-next v4 1/2] mptcp: refactor MP_FAIL response timeout Geliang Tang 2022-06-09 0:00 ` [PATCH mptcp-next v4 2/2] mptcp: trace MP_FAIL subflow in mptcp_sock Geliang Tang 0 siblings, 2 replies; 9+ messages in thread From: Geliang Tang @ 2022-06-09 0:00 UTC (permalink / raw) To: mptcp; +Cc: Geliang Tang v4: - rename fail_sock to fail_ssk, fail_timeout to fail_tout. - move fail_ssk and fail_tout check from mptcp_mp_fail_no_response to mptcp_worker - split into two patches. Geliang Tang (2): mptcp: refactor MP_FAIL response timeout mptcp: trace MP_FAIL subflow in mptcp_sock net/mptcp/pm.c | 7 ++----- net/mptcp/protocol.c | 37 +++++++++++-------------------------- net/mptcp/protocol.h | 3 ++- net/mptcp/subflow.c | 12 +++--------- 4 files changed, 18 insertions(+), 41 deletions(-) -- 2.35.3 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH mptcp-next v4 1/2] mptcp: refactor MP_FAIL response timeout 2022-06-09 0:00 [PATCH mptcp-next v4 0/2] mptcp: refactor MP_FAIL response Geliang Tang @ 2022-06-09 0:00 ` Geliang Tang 2022-06-09 15:03 ` Paolo Abeni 2022-06-09 0:00 ` [PATCH mptcp-next v4 2/2] mptcp: trace MP_FAIL subflow in mptcp_sock Geliang Tang 1 sibling, 1 reply; 9+ messages in thread From: Geliang Tang @ 2022-06-09 0:00 UTC (permalink / raw) To: mptcp; +Cc: Geliang Tang, Paolo Abeni mptcp_mp_fail_no_response shouldn't be invoked on each worker run, it should be invoked only when MP_FAIL response timeout occurs. This patch refactors the MP_FAIL response timeout logic. Add fail_tout in mptcp_sock to record the MP_FAIL timestamp. Check it in mptcp_worker() before invoking mptcp_mp_fail_no_response(). Drop the code to reuse sk_timer for MP_FAIL response. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/281 Fixes: d9fb797046c5 ("mptcp: Do not traverse the subflow connection list without lock") Acked-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Geliang Tang <geliang.tang@suse.com> --- net/mptcp/pm.c | 5 +---- net/mptcp/protocol.c | 4 +++- net/mptcp/protocol.h | 1 + net/mptcp/subflow.c | 10 ++-------- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 59a85220edc9..45a9e02abf24 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -299,7 +299,6 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); struct mptcp_sock *msk = mptcp_sk(subflow->conn); - struct sock *s = (struct sock *)msk; pr_debug("fail_seq=%llu", fail_seq); @@ -312,10 +311,8 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) subflow->send_mp_fail = 1; MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILTX); subflow->send_infinite_map = 1; - } else if (!sock_flag(sk, SOCK_DEAD)) { + } else { pr_debug("MP_FAIL response received"); - - sk_stop_timer(s, &s->sk_timer); } } diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index d6aef4b13b8a..917df5fb9708 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2562,7 +2562,8 @@ static void mptcp_worker(struct work_struct *work) if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags)) __mptcp_retrans(sk); - mptcp_mp_fail_no_response(msk); + if (time_after(jiffies, msk->fail_tout)) + mptcp_mp_fail_no_response(msk); unlock: release_sock(sk); @@ -2589,6 +2590,7 @@ static int __mptcp_init_sock(struct sock *sk) WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk))); WRITE_ONCE(msk->allow_infinite_fallback, true); msk->recovery = false; + msk->fail_tout = 0; mptcp_pm_data_init(msk); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index d406b5afbee4..f7b01275af94 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -306,6 +306,7 @@ struct mptcp_sock { u32 setsockopt_seq; char ca_name[TCP_CA_NAME_MAX]; + unsigned long fail_tout; }; #define mptcp_data_lock(sk) spin_lock_bh(&(sk)->sk_lock.slock) diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 8841e8cd9ad8..866d54a0e83c 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -974,7 +974,6 @@ static enum mapping_status get_mapping_status(struct sock *ssk, { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); bool csum_reqd = READ_ONCE(msk->csum_enabled); - struct sock *sk = (struct sock *)msk; struct mptcp_ext *mpext; struct sk_buff *skb; u16 data_len; @@ -1016,9 +1015,6 @@ static enum mapping_status get_mapping_status(struct sock *ssk, pr_debug("infinite mapping received"); MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPRX); subflow->map_data_len = 0; - if (!sock_flag(ssk, SOCK_DEAD)) - sk_stop_timer(sk, &sk->sk_timer); - return MAPPING_INVALID; } @@ -1238,11 +1234,9 @@ static bool subflow_check_data_avail(struct sock *ssk) tcp_send_active_reset(ssk, GFP_ATOMIC); while ((skb = skb_peek(&ssk->sk_receive_queue))) sk_eat_skb(ssk, skb); - } else if (!sock_flag(ssk, SOCK_DEAD)) { + } else { WRITE_ONCE(subflow->mp_fail_response_expect, true); - sk_reset_timer((struct sock *)msk, - &((struct sock *)msk)->sk_timer, - jiffies + TCP_RTO_MAX); + msk->fail_tout = jiffies + TCP_RTO_MAX; } WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA); return true; -- 2.35.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH mptcp-next v4 1/2] mptcp: refactor MP_FAIL response timeout 2022-06-09 0:00 ` [PATCH mptcp-next v4 1/2] mptcp: refactor MP_FAIL response timeout Geliang Tang @ 2022-06-09 15:03 ` Paolo Abeni 2022-06-09 17:29 ` Mat Martineau 0 siblings, 1 reply; 9+ messages in thread From: Paolo Abeni @ 2022-06-09 15:03 UTC (permalink / raw) To: Geliang Tang, mptcp On Thu, 2022-06-09 at 08:00 +0800, Geliang Tang wrote: > mptcp_mp_fail_no_response shouldn't be invoked on each worker run, it > should be invoked only when MP_FAIL response timeout occurs. > > This patch refactors the MP_FAIL response timeout logic. Add fail_tout > in mptcp_sock to record the MP_FAIL timestamp. Check it in mptcp_worker() > before invoking mptcp_mp_fail_no_response(). Drop the code to reuse > sk_timer for MP_FAIL response. I'm sorry for not noticing it on the previous version - likely for the lack of clarity on my side: we still need to start the timer for mp_fail response: otherwise we are not assured that the mptcp_worker will be triggered. Additionally we need some more care to manipulate the timer reset. I think it's easier if I send a squash-to patch - assuming I'll have some time for that early next week. /P ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH mptcp-next v4 1/2] mptcp: refactor MP_FAIL response timeout 2022-06-09 15:03 ` Paolo Abeni @ 2022-06-09 17:29 ` Mat Martineau 0 siblings, 0 replies; 9+ messages in thread From: Mat Martineau @ 2022-06-09 17:29 UTC (permalink / raw) To: Paolo Abeni; +Cc: Geliang Tang, mptcp On Thu, 9 Jun 2022, Paolo Abeni wrote: > On Thu, 2022-06-09 at 08:00 +0800, Geliang Tang wrote: >> mptcp_mp_fail_no_response shouldn't be invoked on each worker run, it >> should be invoked only when MP_FAIL response timeout occurs. >> >> This patch refactors the MP_FAIL response timeout logic. Add fail_tout >> in mptcp_sock to record the MP_FAIL timestamp. Check it in mptcp_worker() >> before invoking mptcp_mp_fail_no_response(). Drop the code to reuse >> sk_timer for MP_FAIL response. > > I'm sorry for not noticing it on the previous version - likely for the > lack of clarity on my side: we still need to start the timer for > mp_fail response: otherwise we are not assured that the mptcp_worker > will be triggered. > (capturing this on the mailing list in addition to the recent meeting) Yes, I agree. I saw that the timer stop calls were removed but missed the timer reset removal. It is imporant for the timer to still be started. > Additionally we need some more care to manipulate the timer reset. I > think it's easier if I send a squash-to patch - assuming I'll have some > time for that early next week. > Thanks Paolo! -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH mptcp-next v4 2/2] mptcp: trace MP_FAIL subflow in mptcp_sock 2022-06-09 0:00 [PATCH mptcp-next v4 0/2] mptcp: refactor MP_FAIL response Geliang Tang 2022-06-09 0:00 ` [PATCH mptcp-next v4 1/2] mptcp: refactor MP_FAIL response timeout Geliang Tang @ 2022-06-09 0:00 ` Geliang Tang 2022-06-09 0:31 ` Mat Martineau 2022-06-09 1:25 ` mptcp: trace MP_FAIL subflow in mptcp_sock: Tests Results MPTCP CI 1 sibling, 2 replies; 9+ messages in thread From: Geliang Tang @ 2022-06-09 0:00 UTC (permalink / raw) To: mptcp; +Cc: Geliang Tang, Paolo Abeni This patch adds fail_ssk struct member in struct mptcp_sock to record the MP_FAIL subsocket. It can replace the mp_fail_response_expect flag in struct mptcp_subflow_context. Drop mp_fail_response_expect_subflow() helper too, just use this fail_ssk in mptcp_mp_fail_no_response() to reset the subflow. Acked-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Geliang Tang <geliang.tang@suse.com> --- net/mptcp/pm.c | 2 +- net/mptcp/protocol.c | 35 +++++++++-------------------------- net/mptcp/protocol.h | 2 +- net/mptcp/subflow.c | 2 +- 4 files changed, 12 insertions(+), 29 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 45a9e02abf24..2a57d95d5492 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -305,7 +305,7 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) if (!READ_ONCE(msk->allow_infinite_fallback)) return; - if (!READ_ONCE(subflow->mp_fail_response_expect)) { + if (!msk->fail_ssk) { pr_debug("send MP_FAIL response and infinite map"); subflow->send_mp_fail = 1; diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 917df5fb9708..58427fabb061 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2167,21 +2167,6 @@ static void mptcp_retransmit_timer(struct timer_list *t) sock_put(sk); } -static struct mptcp_subflow_context * -mp_fail_response_expect_subflow(struct mptcp_sock *msk) -{ - struct mptcp_subflow_context *subflow, *ret = NULL; - - mptcp_for_each_subflow(msk, subflow) { - if (READ_ONCE(subflow->mp_fail_response_expect)) { - ret = subflow; - break; - } - } - - return ret; -} - static void mptcp_timeout_timer(struct timer_list *t) { struct sock *sk = from_timer(sk, t, sk_timer); @@ -2507,19 +2492,16 @@ static void __mptcp_retrans(struct sock *sk) static void mptcp_mp_fail_no_response(struct mptcp_sock *msk) { - struct mptcp_subflow_context *subflow; - struct sock *ssk; + struct sock *ssk = msk->fail_ssk; bool slow; - subflow = mp_fail_response_expect_subflow(msk); - if (subflow) { - pr_debug("MP_FAIL doesn't respond, reset the subflow"); + pr_debug("MP_FAIL doesn't respond, reset the subflow"); - ssk = mptcp_subflow_tcp_sock(subflow); - slow = lock_sock_fast(ssk); - mptcp_subflow_reset(ssk); - unlock_sock_fast(ssk, slow); - } + slow = lock_sock_fast(ssk); + mptcp_subflow_reset(ssk); + unlock_sock_fast(ssk, slow); + + msk->fail_ssk = NULL; } static void mptcp_worker(struct work_struct *work) @@ -2562,7 +2544,7 @@ static void mptcp_worker(struct work_struct *work) if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags)) __mptcp_retrans(sk); - if (time_after(jiffies, msk->fail_tout)) + if (msk->fail_ssk && time_after(jiffies, msk->fail_tout)) mptcp_mp_fail_no_response(msk); unlock: @@ -2590,6 +2572,7 @@ static int __mptcp_init_sock(struct sock *sk) WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk))); WRITE_ONCE(msk->allow_infinite_fallback, true); msk->recovery = false; + msk->fail_ssk = NULL; msk->fail_tout = 0; mptcp_pm_data_init(msk); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index f7b01275af94..bef7dea9f358 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -306,6 +306,7 @@ struct mptcp_sock { u32 setsockopt_seq; char ca_name[TCP_CA_NAME_MAX]; + struct sock *fail_ssk; unsigned long fail_tout; }; @@ -469,7 +470,6 @@ struct mptcp_subflow_context { local_id_valid : 1, /* local_id is correctly initialized */ valid_csum_seen : 1; /* at least one csum validated */ enum mptcp_data_avail data_avail; - bool mp_fail_response_expect; bool scheduled; u32 remote_nonce; u64 thmac; diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 866d54a0e83c..5351d54e514a 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -1235,7 +1235,7 @@ static bool subflow_check_data_avail(struct sock *ssk) while ((skb = skb_peek(&ssk->sk_receive_queue))) sk_eat_skb(ssk, skb); } else { - WRITE_ONCE(subflow->mp_fail_response_expect, true); + msk->fail_ssk = ssk; msk->fail_tout = jiffies + TCP_RTO_MAX; } WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA); -- 2.35.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH mptcp-next v4 2/2] mptcp: trace MP_FAIL subflow in mptcp_sock 2022-06-09 0:00 ` [PATCH mptcp-next v4 2/2] mptcp: trace MP_FAIL subflow in mptcp_sock Geliang Tang @ 2022-06-09 0:31 ` Mat Martineau 2022-06-09 1:23 ` Geliang Tang 2022-06-09 1:25 ` mptcp: trace MP_FAIL subflow in mptcp_sock: Tests Results MPTCP CI 1 sibling, 1 reply; 9+ messages in thread From: Mat Martineau @ 2022-06-09 0:31 UTC (permalink / raw) To: Geliang Tang; +Cc: mptcp, Paolo Abeni On Thu, 9 Jun 2022, Geliang Tang wrote: > This patch adds fail_ssk struct member in struct mptcp_sock to record > the MP_FAIL subsocket. It can replace the mp_fail_response_expect flag > in struct mptcp_subflow_context. > > Drop mp_fail_response_expect_subflow() helper too, just use this fail_ssk > in mptcp_mp_fail_no_response() to reset the subflow. > > Acked-by: Paolo Abeni <pabeni@redhat.com> > Signed-off-by: Geliang Tang <geliang.tang@suse.com> > --- > net/mptcp/pm.c | 2 +- > net/mptcp/protocol.c | 35 +++++++++-------------------------- > net/mptcp/protocol.h | 2 +- > net/mptcp/subflow.c | 2 +- > 4 files changed, 12 insertions(+), 29 deletions(-) > > diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c > index 45a9e02abf24..2a57d95d5492 100644 > --- a/net/mptcp/pm.c > +++ b/net/mptcp/pm.c > @@ -305,7 +305,7 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) > if (!READ_ONCE(msk->allow_infinite_fallback)) > return; > > - if (!READ_ONCE(subflow->mp_fail_response_expect)) { > + if (!msk->fail_ssk) { > pr_debug("send MP_FAIL response and infinite map"); > > subflow->send_mp_fail = 1; > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c > index 917df5fb9708..58427fabb061 100644 > --- a/net/mptcp/protocol.c > +++ b/net/mptcp/protocol.c > @@ -2167,21 +2167,6 @@ static void mptcp_retransmit_timer(struct timer_list *t) > sock_put(sk); > } > > -static struct mptcp_subflow_context * > -mp_fail_response_expect_subflow(struct mptcp_sock *msk) > -{ > - struct mptcp_subflow_context *subflow, *ret = NULL; > - > - mptcp_for_each_subflow(msk, subflow) { > - if (READ_ONCE(subflow->mp_fail_response_expect)) { > - ret = subflow; > - break; > - } > - } > - > - return ret; > -} > - > static void mptcp_timeout_timer(struct timer_list *t) > { > struct sock *sk = from_timer(sk, t, sk_timer); > @@ -2507,19 +2492,16 @@ static void __mptcp_retrans(struct sock *sk) > > static void mptcp_mp_fail_no_response(struct mptcp_sock *msk) > { > - struct mptcp_subflow_context *subflow; > - struct sock *ssk; > + struct sock *ssk = msk->fail_ssk; > bool slow; > > - subflow = mp_fail_response_expect_subflow(msk); > - if (subflow) { > - pr_debug("MP_FAIL doesn't respond, reset the subflow"); > + pr_debug("MP_FAIL doesn't respond, reset the subflow"); > > - ssk = mptcp_subflow_tcp_sock(subflow); > - slow = lock_sock_fast(ssk); > - mptcp_subflow_reset(ssk); > - unlock_sock_fast(ssk, slow); > - } > + slow = lock_sock_fast(ssk); > + mptcp_subflow_reset(ssk); > + unlock_sock_fast(ssk, slow); > + > + msk->fail_ssk = NULL; > } > > static void mptcp_worker(struct work_struct *work) > @@ -2562,7 +2544,7 @@ static void mptcp_worker(struct work_struct *work) > if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags)) > __mptcp_retrans(sk); > > - if (time_after(jiffies, msk->fail_tout)) Hi Geliang - This condition could be unexpectedly true depending on how close 'jiffies' is to wrapping around, if msk->fail_tout remains at its default 0 value... > + if (msk->fail_ssk && time_after(jiffies, msk->fail_tout)) ...so it's important to fix it like this! I think the two patches should be re-squashed to avoid introducing the issue in the previous commit. Sound good? Also, I think the change should be for mptcp-net so we can get the fix in to 5.19-rcX Thanks! Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com> > mptcp_mp_fail_no_response(msk); > > unlock: > @@ -2590,6 +2572,7 @@ static int __mptcp_init_sock(struct sock *sk) > WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk))); > WRITE_ONCE(msk->allow_infinite_fallback, true); > msk->recovery = false; > + msk->fail_ssk = NULL; > msk->fail_tout = 0; > > mptcp_pm_data_init(msk); > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h > index f7b01275af94..bef7dea9f358 100644 > --- a/net/mptcp/protocol.h > +++ b/net/mptcp/protocol.h > @@ -306,6 +306,7 @@ struct mptcp_sock { > > u32 setsockopt_seq; > char ca_name[TCP_CA_NAME_MAX]; > + struct sock *fail_ssk; > unsigned long fail_tout; > }; > > @@ -469,7 +470,6 @@ struct mptcp_subflow_context { > local_id_valid : 1, /* local_id is correctly initialized */ > valid_csum_seen : 1; /* at least one csum validated */ > enum mptcp_data_avail data_avail; > - bool mp_fail_response_expect; > bool scheduled; > u32 remote_nonce; > u64 thmac; > diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c > index 866d54a0e83c..5351d54e514a 100644 > --- a/net/mptcp/subflow.c > +++ b/net/mptcp/subflow.c > @@ -1235,7 +1235,7 @@ static bool subflow_check_data_avail(struct sock *ssk) > while ((skb = skb_peek(&ssk->sk_receive_queue))) > sk_eat_skb(ssk, skb); > } else { > - WRITE_ONCE(subflow->mp_fail_response_expect, true); > + msk->fail_ssk = ssk; > msk->fail_tout = jiffies + TCP_RTO_MAX; > } > WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA); > -- > 2.35.3 > > > -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH mptcp-next v4 2/2] mptcp: trace MP_FAIL subflow in mptcp_sock 2022-06-09 0:31 ` Mat Martineau @ 2022-06-09 1:23 ` Geliang Tang 2022-06-09 15:01 ` Matthieu Baerts 0 siblings, 1 reply; 9+ messages in thread From: Geliang Tang @ 2022-06-09 1:23 UTC (permalink / raw) To: Mat Martineau; +Cc: mptcp On Wed, Jun 08, 2022 at 05:31:00PM -0700, Mat Martineau wrote: > On Thu, 9 Jun 2022, Geliang Tang wrote: > > > This patch adds fail_ssk struct member in struct mptcp_sock to record > > the MP_FAIL subsocket. It can replace the mp_fail_response_expect flag > > in struct mptcp_subflow_context. > > > > Drop mp_fail_response_expect_subflow() helper too, just use this fail_ssk > > in mptcp_mp_fail_no_response() to reset the subflow. > > > > Acked-by: Paolo Abeni <pabeni@redhat.com> > > Signed-off-by: Geliang Tang <geliang.tang@suse.com> > > --- > > net/mptcp/pm.c | 2 +- > > net/mptcp/protocol.c | 35 +++++++++-------------------------- > > net/mptcp/protocol.h | 2 +- > > net/mptcp/subflow.c | 2 +- > > 4 files changed, 12 insertions(+), 29 deletions(-) > > > > diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c > > index 45a9e02abf24..2a57d95d5492 100644 > > --- a/net/mptcp/pm.c > > +++ b/net/mptcp/pm.c > > @@ -305,7 +305,7 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) > > if (!READ_ONCE(msk->allow_infinite_fallback)) > > return; > > > > - if (!READ_ONCE(subflow->mp_fail_response_expect)) { > > + if (!msk->fail_ssk) { > > pr_debug("send MP_FAIL response and infinite map"); > > > > subflow->send_mp_fail = 1; > > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c > > index 917df5fb9708..58427fabb061 100644 > > --- a/net/mptcp/protocol.c > > +++ b/net/mptcp/protocol.c > > @@ -2167,21 +2167,6 @@ static void mptcp_retransmit_timer(struct timer_list *t) > > sock_put(sk); > > } > > > > -static struct mptcp_subflow_context * > > -mp_fail_response_expect_subflow(struct mptcp_sock *msk) > > -{ > > - struct mptcp_subflow_context *subflow, *ret = NULL; > > - > > - mptcp_for_each_subflow(msk, subflow) { > > - if (READ_ONCE(subflow->mp_fail_response_expect)) { > > - ret = subflow; > > - break; > > - } > > - } > > - > > - return ret; > > -} > > - > > static void mptcp_timeout_timer(struct timer_list *t) > > { > > struct sock *sk = from_timer(sk, t, sk_timer); > > @@ -2507,19 +2492,16 @@ static void __mptcp_retrans(struct sock *sk) > > > > static void mptcp_mp_fail_no_response(struct mptcp_sock *msk) > > { > > - struct mptcp_subflow_context *subflow; > > - struct sock *ssk; > > + struct sock *ssk = msk->fail_ssk; > > bool slow; > > > > - subflow = mp_fail_response_expect_subflow(msk); > > - if (subflow) { > > - pr_debug("MP_FAIL doesn't respond, reset the subflow"); > > + pr_debug("MP_FAIL doesn't respond, reset the subflow"); > > > > - ssk = mptcp_subflow_tcp_sock(subflow); > > - slow = lock_sock_fast(ssk); > > - mptcp_subflow_reset(ssk); > > - unlock_sock_fast(ssk, slow); > > - } > > + slow = lock_sock_fast(ssk); > > + mptcp_subflow_reset(ssk); > > + unlock_sock_fast(ssk, slow); > > + > > + msk->fail_ssk = NULL; > > } > > > > static void mptcp_worker(struct work_struct *work) > > @@ -2562,7 +2544,7 @@ static void mptcp_worker(struct work_struct *work) > > if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags)) > > __mptcp_retrans(sk); > > > > - if (time_after(jiffies, msk->fail_tout)) > > Hi Geliang - > > This condition could be unexpectedly true depending on how close 'jiffies' > is to wrapping around, if msk->fail_tout remains at its default 0 value... > > > + if (msk->fail_ssk && time_after(jiffies, msk->fail_tout)) > > ...so it's important to fix it like this! > > I think the two patches should be re-squashed to avoid introducing the issue > in the previous commit. Sound good? Sure. Please update the subject and commit log when squashing this patch: ''' mptcp: refactor MP_FAIL response mptcp_mp_fail_no_response shouldn't be invoked on each worker run, it should be invoked only when MP_FAIL response timeout occurs. This patch refactors the MP_FAIL response logic. Add fail_tout in mptcp_sock to record the MP_FAIL timestamp. Check it in mptcp_worker() before invoking mptcp_mp_fail_no_response(). Drop the code to reuse sk_timer for MP_FAIL response. Add fail_ssk struct member in struct mptcp_sock to record the MP_FAIL subsocket. It can replace the mp_fail_response_expect flag in struct mptcp_subflow_context. Drop mp_fail_response_expect_subflow() helper, just use this fail_ssk in mptcp_mp_fail_no_response() to reset the subflow. ''' Thanks, -Geliang > > Also, I think the change should be for mptcp-net so we can get the fix in to > 5.19-rcX > > Thanks! > > Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com> > > > > mptcp_mp_fail_no_response(msk); > > > > unlock: > > @@ -2590,6 +2572,7 @@ static int __mptcp_init_sock(struct sock *sk) > > WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk))); > > WRITE_ONCE(msk->allow_infinite_fallback, true); > > msk->recovery = false; > > + msk->fail_ssk = NULL; > > msk->fail_tout = 0; > > > > mptcp_pm_data_init(msk); > > diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h > > index f7b01275af94..bef7dea9f358 100644 > > --- a/net/mptcp/protocol.h > > +++ b/net/mptcp/protocol.h > > @@ -306,6 +306,7 @@ struct mptcp_sock { > > > > u32 setsockopt_seq; > > char ca_name[TCP_CA_NAME_MAX]; > > + struct sock *fail_ssk; > > unsigned long fail_tout; > > }; > > > > @@ -469,7 +470,6 @@ struct mptcp_subflow_context { > > local_id_valid : 1, /* local_id is correctly initialized */ > > valid_csum_seen : 1; /* at least one csum validated */ > > enum mptcp_data_avail data_avail; > > - bool mp_fail_response_expect; > > bool scheduled; > > u32 remote_nonce; > > u64 thmac; > > diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c > > index 866d54a0e83c..5351d54e514a 100644 > > --- a/net/mptcp/subflow.c > > +++ b/net/mptcp/subflow.c > > @@ -1235,7 +1235,7 @@ static bool subflow_check_data_avail(struct sock *ssk) > > while ((skb = skb_peek(&ssk->sk_receive_queue))) > > sk_eat_skb(ssk, skb); > > } else { > > - WRITE_ONCE(subflow->mp_fail_response_expect, true); > > + msk->fail_ssk = ssk; > > msk->fail_tout = jiffies + TCP_RTO_MAX; > > } > > WRITE_ONCE(subflow->data_avail, MPTCP_SUBFLOW_NODATA); > > -- > > 2.35.3 > > > > > > > > -- > Mat Martineau > Intel > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH mptcp-next v4 2/2] mptcp: trace MP_FAIL subflow in mptcp_sock 2022-06-09 1:23 ` Geliang Tang @ 2022-06-09 15:01 ` Matthieu Baerts 0 siblings, 0 replies; 9+ messages in thread From: Matthieu Baerts @ 2022-06-09 15:01 UTC (permalink / raw) To: Geliang Tang, Mat Martineau; +Cc: mptcp Hi Geliang, Mat, Paolo, On 09/06/2022 03:23, Geliang Tang wrote: > On Wed, Jun 08, 2022 at 05:31:00PM -0700, Mat Martineau wrote: >> On Thu, 9 Jun 2022, Geliang Tang wrote: >> >>> This patch adds fail_ssk struct member in struct mptcp_sock to record >>> the MP_FAIL subsocket. It can replace the mp_fail_response_expect flag >>> in struct mptcp_subflow_context. >>> >>> Drop mp_fail_response_expect_subflow() helper too, just use this fail_ssk >>> in mptcp_mp_fail_no_response() to reset the subflow. >>> >>> Acked-by: Paolo Abeni <pabeni@redhat.com> >>> Signed-off-by: Geliang Tang <geliang.tang@suse.com> >>> --- >>> net/mptcp/pm.c | 2 +- >>> net/mptcp/protocol.c | 35 +++++++++-------------------------- >>> net/mptcp/protocol.h | 2 +- >>> net/mptcp/subflow.c | 2 +- >>> 4 files changed, 12 insertions(+), 29 deletions(-) >>> >>> diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c >>> index 45a9e02abf24..2a57d95d5492 100644 >>> --- a/net/mptcp/pm.c >>> +++ b/net/mptcp/pm.c >>> @@ -305,7 +305,7 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) >>> if (!READ_ONCE(msk->allow_infinite_fallback)) >>> return; >>> >>> - if (!READ_ONCE(subflow->mp_fail_response_expect)) { >>> + if (!msk->fail_ssk) { >>> pr_debug("send MP_FAIL response and infinite map"); >>> >>> subflow->send_mp_fail = 1; >>> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c >>> index 917df5fb9708..58427fabb061 100644 >>> --- a/net/mptcp/protocol.c >>> +++ b/net/mptcp/protocol.c >>> @@ -2167,21 +2167,6 @@ static void mptcp_retransmit_timer(struct timer_list *t) >>> sock_put(sk); >>> } >>> >>> -static struct mptcp_subflow_context * >>> -mp_fail_response_expect_subflow(struct mptcp_sock *msk) >>> -{ >>> - struct mptcp_subflow_context *subflow, *ret = NULL; >>> - >>> - mptcp_for_each_subflow(msk, subflow) { >>> - if (READ_ONCE(subflow->mp_fail_response_expect)) { >>> - ret = subflow; >>> - break; >>> - } >>> - } >>> - >>> - return ret; >>> -} >>> - >>> static void mptcp_timeout_timer(struct timer_list *t) >>> { >>> struct sock *sk = from_timer(sk, t, sk_timer); >>> @@ -2507,19 +2492,16 @@ static void __mptcp_retrans(struct sock *sk) >>> >>> static void mptcp_mp_fail_no_response(struct mptcp_sock *msk) >>> { >>> - struct mptcp_subflow_context *subflow; >>> - struct sock *ssk; >>> + struct sock *ssk = msk->fail_ssk; >>> bool slow; >>> >>> - subflow = mp_fail_response_expect_subflow(msk); >>> - if (subflow) { >>> - pr_debug("MP_FAIL doesn't respond, reset the subflow"); >>> + pr_debug("MP_FAIL doesn't respond, reset the subflow"); >>> >>> - ssk = mptcp_subflow_tcp_sock(subflow); >>> - slow = lock_sock_fast(ssk); >>> - mptcp_subflow_reset(ssk); >>> - unlock_sock_fast(ssk, slow); >>> - } >>> + slow = lock_sock_fast(ssk); >>> + mptcp_subflow_reset(ssk); >>> + unlock_sock_fast(ssk, slow); >>> + >>> + msk->fail_ssk = NULL; >>> } >>> >>> static void mptcp_worker(struct work_struct *work) >>> @@ -2562,7 +2544,7 @@ static void mptcp_worker(struct work_struct *work) >>> if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags)) >>> __mptcp_retrans(sk); >>> >>> - if (time_after(jiffies, msk->fail_tout)) >> >> Hi Geliang - >> >> This condition could be unexpectedly true depending on how close 'jiffies' >> is to wrapping around, if msk->fail_tout remains at its default 0 value... >> >>> + if (msk->fail_ssk && time_after(jiffies, msk->fail_tout)) >> >> ...so it's important to fix it like this! >> >> I think the two patches should be re-squashed to avoid introducing the issue >> in the previous commit. Sound good? > > Sure. Please update the subject and commit log when squashing this patch: > > ''' > mptcp: refactor MP_FAIL response > > mptcp_mp_fail_no_response shouldn't be invoked on each worker run, it > should be invoked only when MP_FAIL response timeout occurs. > > This patch refactors the MP_FAIL response logic. > > Add fail_tout in mptcp_sock to record the MP_FAIL timestamp. Check it > in mptcp_worker() before invoking mptcp_mp_fail_no_response(). Drop > the code to reuse sk_timer for MP_FAIL response. > > Add fail_ssk struct member in struct mptcp_sock to record the MP_FAIL > subsocket. It can replace the mp_fail_response_expect flag in struct > mptcp_subflow_context. Drop mp_fail_response_expect_subflow() helper, > just use this fail_ssk in mptcp_mp_fail_no_response() to reset the > subflow. > ''' > > Thanks, > -Geliang > >> >> Also, I think the change should be for mptcp-net so we can get the fix in to >> 5.19-rcX Thank you for the patches and the reviews! I just squashed these two patches and applied in "Fixed for -net" part. @Mat: careful that there is a conflict when merging with net-next, please see below: I also renamed the subject because "mptcp: refactor MP_FAIL response" didn't sound like a fix. Feel free to suggest better subject :) - 9f0b1fb5ff57: mptcp: invoke MP_FAIL response when needed - Results: 96aa91051266..5ffedd7d32e6 (export-net) - a87560169aa5: conflict in t/mptcp-add-scheduled-in-mptcp_subflow_context - Results: 91b7cc881cdd..19fb763aac71 (export) Builds and tests are now in progress: https://cirrus-ci.com/github/multipath-tcp/mptcp_net-next/export/20220609T145706 https://cirrus-ci.com/github/multipath-tcp/mptcp_net-next/export-net/20220609T145706 https://github.com/multipath-tcp/mptcp_net-next/actions/workflows/build-validation.yml?query=branch:export https://github.com/multipath-tcp/mptcp_net-next/actions/workflows/build-validation.yml?query=branch:export-net Cheers, Matt -- Tessares | Belgium | Hybrid Access Solutions www.tessares.net ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: mptcp: trace MP_FAIL subflow in mptcp_sock: Tests Results 2022-06-09 0:00 ` [PATCH mptcp-next v4 2/2] mptcp: trace MP_FAIL subflow in mptcp_sock Geliang Tang 2022-06-09 0:31 ` Mat Martineau @ 2022-06-09 1:25 ` MPTCP CI 1 sibling, 0 replies; 9+ messages in thread From: MPTCP CI @ 2022-06-09 1:25 UTC (permalink / raw) To: Geliang Tang; +Cc: mptcp Hi Geliang, Thank you for your modifications, that's great! Our CI did some validations and here is its report: - KVM Validation: normal: - Unstable: 1 failed test(s): packetdrill_add_addr 🔴: - Task: https://cirrus-ci.com/task/5388166994591744 - Summary: https://api.cirrus-ci.com/v1/artifact/task/5388166994591744/summary/summary.txt - KVM Validation: debug: - Unstable: 2 failed test(s): selftest_diag selftest_simult_flows 🔴: - Task: https://cirrus-ci.com/task/6514066901434368 - Summary: https://api.cirrus-ci.com/v1/artifact/task/6514066901434368/summary/summary.txt Initiator: Patchew Applier Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/1da22c975795 If there are some issues, you can reproduce them using the same environment as the one used by the CI thanks to a docker image, e.g.: $ cd [kernel source code] $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \ --pull always mptcp/mptcp-upstream-virtme-docker:latest \ auto-debug For more details: https://github.com/multipath-tcp/mptcp-upstream-virtme-docker Please note that despite all the efforts that have been already done to have a stable tests suite when executed on a public CI like here, it is possible some reported issues are not due to your modifications. Still, do not hesitate to help us improve that ;-) Cheers, MPTCP GH Action bot Bot operated by Matthieu Baerts (Tessares) ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-06-09 17:29 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-06-09 0:00 [PATCH mptcp-next v4 0/2] mptcp: refactor MP_FAIL response Geliang Tang 2022-06-09 0:00 ` [PATCH mptcp-next v4 1/2] mptcp: refactor MP_FAIL response timeout Geliang Tang 2022-06-09 15:03 ` Paolo Abeni 2022-06-09 17:29 ` Mat Martineau 2022-06-09 0:00 ` [PATCH mptcp-next v4 2/2] mptcp: trace MP_FAIL subflow in mptcp_sock Geliang Tang 2022-06-09 0:31 ` Mat Martineau 2022-06-09 1:23 ` Geliang Tang 2022-06-09 15:01 ` Matthieu Baerts 2022-06-09 1:25 ` mptcp: trace MP_FAIL subflow in mptcp_sock: Tests Results MPTCP CI
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.