diff mbox series

[mptcp-next] mptcp: fix divide error in mptcp_subflow_get_send

Message ID 20221022075412.471-1-geliang.tang@suse.com (mailing list archive)
State Superseded, archived
Delegated to: Mat Martineau
Headers show
Series [mptcp-next] mptcp: fix divide error in mptcp_subflow_get_send | expand

Checks

Context Check Description
matttbe/checkpatch warning total: 0 errors, 2 warnings, 0 checks, 17 lines checked
matttbe/build success Build and static analysis OK
matttbe/KVM_Validation__normal warning Unstable: 1 failed test(s): packetdrill_add_addr

Commit Message

Geliang Tang Oct. 22, 2022, 7:54 a.m. UTC
Fix this divide error:

----
divide error: 0000 [#1] PREEMPT SMP KASAN NOPTI
CPU: 0 PID: 14336 Comm: syz-executor.6 Not tainted 6.1.0-rc1-00215-g47aa7f23f440 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
RIP: 0010:div_u64_rem include/linux/math64.h:29 [inline]
RIP: 0010:div_u64 include/linux/math64.h:128 [inline]
RIP: 0010:mptcp_subflow_get_send+0xa87/0x1200 net/mptcp/protocol.c:1486
----

Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/314
Reported-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Geliang Tang <geliang.tang@suse.com>
---
 net/mptcp/protocol.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

Comments

MPTCP CI Oct. 22, 2022, 9:58 a.m. UTC | #1
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 
Mat Martineau Oct. 24, 2022, 11:37 p.m. UTC | #2
On Sat, 22 Oct 2022, Geliang Tang wrote:

> Fix this divide error:
>
> ----
> divide error: 0000 [#1] PREEMPT SMP KASAN NOPTI
> CPU: 0 PID: 14336 Comm: syz-executor.6 Not tainted 6.1.0-rc1-00215-g47aa7f23f440 #1
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
> RIP: 0010:div_u64_rem include/linux/math64.h:29 [inline]
> RIP: 0010:div_u64 include/linux/math64.h:128 [inline]
> RIP: 0010:mptcp_subflow_get_send+0xa87/0x1200 net/mptcp/protocol.c:1486
> ----
>
> Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/314
> Reported-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
> Signed-off-by: Geliang Tang <geliang.tang@suse.com>
> ---
> net/mptcp/protocol.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index ddeb8b36a677..3a07c0d197d4 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -1475,13 +1475,14 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk)
> 	if (!ssk || !sk_stream_memory_free(ssk))
> 		return NULL;
>
> -	burst = min_t(int, MPTCP_SEND_BURST_SIZE, mptcp_wnd_end(msk) - msk->snd_nxt);
> -	wmem = READ_ONCE(ssk->sk_wmem_queued);
> -	if (!burst) {
> +	if (mptcp_wnd_end(msk) <= msk->snd_nxt) {
> 		msk->last_snd = NULL;
> 		return ssk;
> 	}
>
> +	burst = min_t(u32, MPTCP_SEND_BURST_SIZE, mptcp_wnd_end(msk) - msk->snd_nxt);
> +	wmem = READ_ONCE(ssk->sk_wmem_queued);
> +
> 	subflow = mptcp_subflow_ctx(ssk);
> 	subflow->avg_pacing_rate = div_u64((u64)subflow->avg_pacing_rate * wmem +
> 					   READ_ONCE(ssk->sk_pacing_rate) * burst,
> -- 
> 2.35.3

Hi Geliang -

I haven't been able to reproduce the problem using commit id c3917837f483 
(export/20221024T065054 without the "features other trees" patches), and 
the only change in mptcp_subflow_get_send() is the removal of the fallback 
check in "mptcp: add get_subflow wrappers". The stack trace shows that 
mptcp_subflow_get_send() is called directly by __mptcp_push_pending():

RIP: 0010:mptcp_subflow_get_send+0xa87/0x1200 net/mptcp/protocol.c:1486
...
Call Trace:
  <TASK>
  __mptcp_push_pending+0x19e/0x770 net/mptcp/protocol.c:1550
  mptcp_sendmsg+0x694/0x19d0 net/mptcp/protocol.c:1813

So I think the divide by zero is due to the missing fallback check. Seems 
like the fallback check should be moved only when mptcp_subflow_get_send() 
is only called using the wrapper? WDYT?

--
Mat Martineau
Intel
diff mbox series

Patch

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index ddeb8b36a677..3a07c0d197d4 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1475,13 +1475,14 @@  struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk)
 	if (!ssk || !sk_stream_memory_free(ssk))
 		return NULL;
 
-	burst = min_t(int, MPTCP_SEND_BURST_SIZE, mptcp_wnd_end(msk) - msk->snd_nxt);
-	wmem = READ_ONCE(ssk->sk_wmem_queued);
-	if (!burst) {
+	if (mptcp_wnd_end(msk) <= msk->snd_nxt) {
 		msk->last_snd = NULL;
 		return ssk;
 	}
 
+	burst = min_t(u32, MPTCP_SEND_BURST_SIZE, mptcp_wnd_end(msk) - msk->snd_nxt);
+	wmem = READ_ONCE(ssk->sk_wmem_queued);
+
 	subflow = mptcp_subflow_ctx(ssk);
 	subflow->avg_pacing_rate = div_u64((u64)subflow->avg_pacing_rate * wmem +
 					   READ_ONCE(ssk->sk_pacing_rate) * burst,