public inbox for mptcp@lists.linux.dev
 help / color / mirror / Atom feed
From: Matthieu Baerts <matttbe@kernel.org>
To: Gang Yan <gang.yan@linux.dev>, mptcp@lists.linux.dev, pabeni@redhat.com
Cc: Gang Yan <yangang@kylinos.cn>, Geliang Tang <tanggeliang@kylinos.cn>
Subject: Re: [Patch mptcp-net 1/3] mptcp: add backlog_list bug reproducer test
Date: Thu, 5 Feb 2026 19:01:49 +0100	[thread overview]
Message-ID: <a57b0254-2e3d-4e5b-8f2d-4ce6d36f5af8@kernel.org> (raw)
In-Reply-To: <500a8fe690cb8718ea32c33ae8cdcb2df203ecd0.1770273341.git.yangang@kylinos.cn>

Hi Gang,

Thank you for looking at this.

Small detail: I'm not sure what you are using to generate the patches
(b4 prep/send is great BTW), but it is strange to have 'Patch' instead
of PATCH in the subjects.

On 05/02/2026 07:41, Gang Yan wrote:
> From: Gang Yan <yangang@kylinos.cn>
> 
> This patch introduces a test program to reproduce bugs related to the
> backlog_list in MPTCP. The test is derived from tls.c in the selftests
> suite, but adapted to work without TLS configuration specifically for
> MPTCP testing.
> 
> The program performs chunked sendfile operations with various payload
> sizes to exercise different code paths and trigger backlog_list-related
> issues.

I understood it was just a tmp patch just to show how to reproduce the
issue, but I think it is good to make sure such regression is not
reintroduced. So if this test is quick to run, it should be kept. No?

Except if the error could be reproduced with packetdrill? Or eventually
if mptcp_connect.(c|sh) could be easily adapted to reproduce the issue
instead?

> 
> It can be run in .virtme-exec-run:
>         run_loop run_selftest_one ./multi_chunk.sh

(That's specific to the MPTCP docker image, no need to specify this here
to avoid confusions)

> 
> '''
> selftest Test: ./multi_chunk.sh
> TAP version 13
> 1..1
> [stalls for a while]
> ^C
> 
> '''
> 
> Co-developed-by: Geliang Tang <tanggeliang@kylinos.cn>
> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
> Signed-off-by: Gang Yan <yangang@kylinos.cn>
> ---
>  tools/testing/selftests/net/mptcp/Makefile    |   1 +
>  .../testing/selftests/net/mptcp/multi_chunk.c | 148 ++++++++++++++++++
>  .../selftests/net/mptcp/multi_chunk.sh        |  37 +++++
>  3 files changed, 186 insertions(+)
>  create mode 100644 tools/testing/selftests/net/mptcp/multi_chunk.c
>  create mode 100755 tools/testing/selftests/net/mptcp/multi_chunk.sh
> 
> diff --git a/tools/testing/selftests/net/mptcp/Makefile b/tools/testing/selftests/net/mptcp/Makefile
> index 22ba0da2adb8..087e6ae6f0b8 100644
> --- a/tools/testing/selftests/net/mptcp/Makefile
> +++ b/tools/testing/selftests/net/mptcp/Makefile
> @@ -24,6 +24,7 @@ TEST_GEN_FILES := \
>  	mptcp_diag \
>  	mptcp_inq \
>  	mptcp_sockopt \
> +	multi_chunk \
>  	pm_nl_ctl \
>  # end of TEST_GEN_FILES
>  
> diff --git a/tools/testing/selftests/net/mptcp/multi_chunk.c b/tools/testing/selftests/net/mptcp/multi_chunk.c
> new file mode 100644
> index 000000000000..8c97db58a6db
> --- /dev/null
> +++ b/tools/testing/selftests/net/mptcp/multi_chunk.c
> @@ -0,0 +1,148 @@
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/socket.h>
> +#include <netinet/in.h>
> +#include <sys/sendfile.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <errno.h>
> +#include <arpa/inet.h>
> +#include <sys/wait.h>

Please sort the headers, see:

https://lore.kernel.org/mptcp/20260130-mptcp-sft-sort-includes-v1-1-ab022fad9741@kernel.org/

> +
> +#ifndef IPPROTO_MPTCP
> +#define IPPROTO_MPTCP 262
> +#endif
> +
> +#define TLS_PAYLOAD_MAX_LEN 16384
> +#define TEST_PORT 12345
> +
> +static void chunked_sendfile(int cfd, int sfd,
> +			     size_t chunk_size,
> +			     size_t extra_payload_size)
> +{
> +	char buf[TLS_PAYLOAD_MAX_LEN];
> +	uint16_t test_payload_size;
> +	size_t recved = 0;
> +	size_t sent = 0;
> +	int size = 0;
> +	int ret;
> +	char filename[] = "/tmp/mytemp.XXXXXX";
> +	int fd = mkstemp(filename);
> +	off_t offset = 0;

Ideally keep the reverse XMAS tree for the order.

> +
> +	unlink(filename);
> +	if (fd <= 0) {
> +		perror("tempfile");
> +		exit(1);
> +	}
> +	if (chunk_size < 1) {
> +		perror("chunksize");
> +		exit(1);
> +	}
> +
> +	test_payload_size = chunk_size + extra_payload_size;
> +	if (test_payload_size > TLS_PAYLOAD_MAX_LEN) {
> +		perror("payload_size");
> +		exit(1);
> +	}
> +	memset(buf, 1, test_payload_size);
> +	size = write(fd, buf, test_payload_size);
> +	if (size != test_payload_size) {
> +		perror("file write");
> +		exit(1);
> +	}
> +	fsync(fd);
> +
> +	while (size > 0) {
> +		ret = sendfile(sfd, fd, &offset, chunk_size);
> +		if (ret <= 0)

It would be good to print an error to stderr.

Also, maybe you will need to at least close(fd) to be sure the tmp file
will be removed, no?


> +			exit(1);
> +		size -= ret;
> +		sent += ret;
> +	}
> +	printf("[client] sent %zu bytes\n", sent);
> +
> +	recved = recv(cfd, buf, test_payload_size, MSG_WAITALL);
> +	printf("[server] receieved %zu bytes\n", recved);
> +
> +	if (recved != test_payload_size)

Same here.

> +		exit(1);
> +
> +	close(fd);
> +}
> +
> +int main()
> +{
> +	int sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
> +	int cfd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
> +	struct sockaddr_in addr = {0};
> +	socklen_t addrlen = sizeof(addr);
> +
> +	printf("==== multi_chunk_sendfile MPTCP test ====\n");

Maybe these printf() here and at the bottom are not really needed?

> +
> +	if (sfd < 0 || cfd < 0) {
> +		perror("socket");
> +		exit(1);
> +	}
> +
> +	addr.sin_family = AF_INET;
> +	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
> +	addr.sin_port = htons(TEST_PORT);
> +
> +	if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
> +		perror("bind");
> +		exit(1);
> +	}
> +
> +	if (listen(sfd, 1) < 0) {
> +		perror("listen");
> +		exit(1);
> +	}
> +
> +	if (getsockname(sfd, (struct sockaddr *)&addr, &addrlen) < 0) {
> +		perror("getsockname");
> +		exit(1);
> +	}
> +
> +	if (connect(cfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
> +		perror("connect");
> +		exit(1);
> +	}
> +
> +	int nfd = accept(sfd, NULL, NULL);
> +	if (nfd < 0) {
> +		perror("accept");
> +		exit(1);
> +	}
> +
> +	chunked_sendfile(cfd, nfd, 4096, 4096);
> +	chunked_sendfile(cfd, nfd, 4096, 0);
> +	chunked_sendfile(cfd, nfd, 4096, 1);
> +	chunked_sendfile(cfd, nfd, 4096, 2048);
> +	chunked_sendfile(cfd, nfd, 8192, 2048);
> +	chunked_sendfile(cfd, nfd, 4096, 8192);
> +	chunked_sendfile(cfd, nfd, 8192, 4096);
> +	chunked_sendfile(cfd, nfd, 12288, 1024);
> +	chunked_sendfile(cfd, nfd, 12288, 2000);
> +	chunked_sendfile(cfd, nfd, 15360, 100);
> +	chunked_sendfile(cfd, nfd, 15360, 300);
> +	chunked_sendfile(cfd, nfd, 1, 4096);
> +	chunked_sendfile(cfd, nfd, 2048, 4096);
> +	chunked_sendfile(cfd, nfd, 2048, 8192);
> +	chunked_sendfile(cfd, nfd, 4096, 8192);
> +	chunked_sendfile(cfd, nfd, 1024, 12288);
> +	chunked_sendfile(cfd, nfd, 2000, 12288);
> +	chunked_sendfile(cfd, nfd, 100, 15360);
> +	chunked_sendfile(cfd, nfd, 300, 15360);
> +
> +	close(cfd);
> +	close(nfd);
> +	close(sfd);
> +
> +	printf("==== test ends ====\n");
> +	return 0;
> +}
> diff --git a/tools/testing/selftests/net/mptcp/multi_chunk.sh b/tools/testing/selftests/net/mptcp/multi_chunk.sh
> new file mode 100755
> index 000000000000..c0352c89087f
> --- /dev/null
> +++ b/tools/testing/selftests/net/mptcp/multi_chunk.sh
> @@ -0,0 +1,37 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +
> +. "$(dirname "${0}")/mptcp_lib.sh"
> +
> +cleanup()
> +{
> +	if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
> +		kill "$pid" 2>/dev/null
> +		wait "$pid" 2>/dev/null
> +	fi
> +
> +	mptcp_lib_ns_exit "${ns1}"
> +}
> +
> +init()
> +{
> +	mptcp_lib_ns_init ns1
> +
> +	local i
> +	for i in $(seq 1 4); do
> +		mptcp_lib_pm_nl_add_endpoint "${ns1}" "127.0.0.1" flags signal port 1000$i
> +	done
> +
> +	mptcp_lib_pm_nl_set_limits "${ns1}" 8 8
> +
> +	ip netns exec ${ns1} ip mptcp endpoint show
> +	ip netns exec ${ns1} ip mptcp limits

These two lines are not needed.

> +}
> +
> +init
> +trap cleanup EXIT
> +
> +ip netns exec $ns1 ./multi_chunk &
> +
> +pid=$!
> +wait $pid

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


  parent reply	other threads:[~2026-02-05 18:01 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-05  6:41 [Patch mptcp-net 0/3] Fix the transmission stall due to backlog Gang Yan
2026-02-05  6:41 ` [Patch mptcp-net 1/3] mptcp: add backlog_list bug reproducer test Gang Yan
2026-02-05  9:20   ` Paolo Abeni
2026-02-05 13:05     ` gang.yan
2026-02-05 18:01   ` Matthieu Baerts [this message]
2026-02-05  6:41 ` [Patch mptcp-net 2/3] mptcp: fix receive stalls when 'ack_seq' in backlog_list Gang Yan
2026-02-05  9:36   ` Paolo Abeni
     [not found]     ` <f9a2229cd1d69731db91a003ac1018f446be9572@linux.dev>
2026-02-09  9:02       ` gang.yan
2026-02-05  6:41 ` [Patch mptcp-net 3/3] mptcp: fix stall because of data_ready Gang Yan
2026-02-05 10:07   ` Paolo Abeni
2026-02-05 13:27     ` gang.yan
2026-02-09  8:56       ` gang.yan
2026-02-05  7:58 ` [Patch mptcp-net 0/3] Fix the transmission stall due to backlog MPTCP CI

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a57b0254-2e3d-4e5b-8f2d-4ce6d36f5af8@kernel.org \
    --to=matttbe@kernel.org \
    --cc=gang.yan@linux.dev \
    --cc=mptcp@lists.linux.dev \
    --cc=pabeni@redhat.com \
    --cc=tanggeliang@kylinos.cn \
    --cc=yangang@kylinos.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox