mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Zhewei Yuan <yzwlhm@gmail.com>
To: netdev@vger.kernel.org
Cc: Zhewei Yuan <yzwlhm@gmail.com>,
	linux-kernel@vger.kernel.org,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@kernel.org>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Simon Horman <horms@kernel.org>,
	Neal Cardwell <ncardwell@google.com>,
	Kuniyuki Iwashima <kuniyu@google.com>
Subject: [PATCH net 0/2] tcp: Fix fastreuse cache initialization on first bind
Date: Sun, 25 Oct 2026 09:00:46 +0000	[thread overview]
Message-ID: <20261025090048.27870-1-yzwlhm@gmail.com> (raw)

This series fixes TCP bind reuse cache initialization and adds eight
KUnit regression cases.

Since commit 8002d44fe84d, tb2 is already linked to tb->bhash2 when
inet_csk_update_fastreuse() checks for an empty list. First binds miss
fastreuse=1 for SO_REUSEADDR and FASTREUSEPORT_ANY for SO_REUSEPORT,
causing unnecessary conflict scans. Patch 1 recognizes the sole,
ownerless address bucket; patch 2 tests initialization and conflicts.

Bind-only results on historical net f4377bf85887 (not the submission
base): TCP/IPv4, one-vCPU KVM, GCC 11.5.0, identical configs/programs.
Means of 3 guest boots x 3 rounds; only bind() is timed, with all sockets
kept open. Each case uses one reuse option, the same UID and port.
"same" uses 127.0.0.1; "alternate" interleaves 127.0.0.1/127.0.0.2.

  16000 sockets                 before (ms)    after (ms)
  SO_REUSEADDR, same                 4256.956        20.004
  SO_REUSEADDR, alternate            2476.914        19.983
  SO_REUSEPORT, same                   20.600        19.557
  SO_REUSEPORT, alternate            2491.294        19.830

Same-IP SO_REUSEPORT measurements overlap, so no stable gain is claimed
there. These are bind microbenchmarks, not application throughput.
A minimal reproducer is included at the end of this letter.

Validation on submission base 7076f684d513:
- KUnit: six expected first-bind failures and two passing conflict
  guards before the fix; all eight pass after it (same tests/config).
- bind_wildcard, reuseaddr_conflict, reuseport_addr_any,
  reuseaddr_ports_exhausted and tcp_port_share: pass without skips.
- Full x86_64 allmodconfig W=1: baseline and patched builds pass with
  identical configs, GCC 11.5.0 and CONFIG_WERROR=n. Existing warnings
  remain, but normalized diagnostics and counts match: no new warnings.
- Full allyesconfig is blocked by the MCTP KUnit static_assert at
  drivers/net/mctp/mctp-usblib-test.c:819. A targeted unpatched build
  reproduces the same error; this is not a full allyesconfig pass.

KUnit A/B and patched allyesconfig/allmodconfig W=1 builds also passed
on historical f4377bf85887 (GCC 11.5.0, CONFIG_WERROR=n); those builds
are auxiliary evidence, not substitutes for the submission-base checks.

Found during manual code inspection and GDB tracing. Codex assisted
with analysis, test/benchmark development, validation and patch text.
Requests covered real first binds, cache flags, automatic ports,
conflict preservation and separate reuseaddr/reuseport measurements.
No failure injection was used; KUnit inspects state after real binds.

Reproducer (not for the merge commit). It gives matching results on
the submission base 7076f684d513 (16000 sockets, same order as the
table, before/after in ms: 4178/19.4, 2416/19.4, 19.8/19.4,
2428/19.5). It needs loopback up and an fd limit above N, e.g.
"ulimit -n 70000; ./bind_bench reuseaddr same 16000".

  // Time bind() of N TCP sockets with one reuse option to one port.
  // Usage: bind_bench reuseaddr|reuseport same|alternate N
  // same: 127.0.0.1; alternate: 127.0.0.1/127.0.0.2. Sockets stay open.
  #include <netinet/in.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <sys/socket.h>
  #include <time.h>

  int main(int argc, char **argv)
  {
  	struct sockaddr_in sa = { .sin_family = AF_INET,
  				  .sin_port = htons(40000) };
  	int opt, alt, n, one = 1, i, fd;
  	struct timespec a, b;
  	long long ns = 0;

  	if (argc != 4)
  		return fprintf(stderr, "usage: %s reuseaddr|reuseport same|alternate N\n",
  			       argv[0]), 1;
  	opt = strcmp(argv[1], "reuseport") ? SO_REUSEADDR : SO_REUSEPORT;
  	alt = !strcmp(argv[2], "alternate");
  	n = atoi(argv[3]);

  	for (i = 0; i < n; i++) {
  		fd = socket(AF_INET, SOCK_STREAM, 0);
  		if (fd < 0 || setsockopt(fd, SOL_SOCKET, opt, &one, sizeof(one)))
  			return perror("socket/setsockopt"), 1;
  		sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK + (alt ? i % 2 : 0));
  		clock_gettime(CLOCK_MONOTONIC, &a);
  		if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)))
  			return perror("bind"), 1;
  		clock_gettime(CLOCK_MONOTONIC, &b);
  		ns += (b.tv_sec - a.tv_sec) * 1000000000LL + b.tv_nsec - a.tv_nsec;
  	}
  	printf("%s %s %d: %.3f ms\n", argv[1], argv[2], n, ns / 1e6);
  	return 0;
  }

Zhewei Yuan (2):
  tcp: Fix fastreuse cache initialization on first bind
  tcp: Add KUnit tests for bind fastreuse caches

 net/ipv4/.kunitconfig                |   8 +
 net/ipv4/Kconfig                     |  14 ++
 net/ipv4/Makefile                    |   1 +
 net/ipv4/inet_connection_sock.c      |   3 +-
 net/ipv4/inet_connection_sock_test.c | 303 +++++++++++++++++++++++++++
 5 files changed, 328 insertions(+), 1 deletion(-)
 create mode 100644 net/ipv4/.kunitconfig
 create mode 100644 net/ipv4/inet_connection_sock_test.c


base-commit: 7076f684d5132e6a6145e1da2fa74771ecd052e5
-- 
2.52.0


             reply	other threads:[~2026-10-25  9:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-25  9:00 Zhewei Yuan [this message]
2026-10-25  9:00 ` [PATCH net 1/2] " Zhewei Yuan
2026-10-25 11:06   ` Eric Dumazet
2026-10-25  9:00 ` [PATCH net 2/2] tcp: Add KUnit tests for bind fastreuse caches Zhewei Yuan
2026-10-25 11:08   ` Eric Dumazet

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=20261025090048.27870-1-yzwlhm@gmail.com \
    --to=yzwlhm@gmail.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=kuniyu@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ncardwell@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /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

all inboxes | Powered by JetHome®