netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Honglei Wang <redsky110@gmail.com>
To: davem@davemloft.net, edumazet@google.com
Cc: netdev@vger.kernel.org, redsky110@gmail.com
Subject: [PATCH] tcp: avoid unnecessary loop if even ports are used up
Date: Sat, 20 Feb 2021 19:03:56 +0800	[thread overview]
Message-ID: <20210220110356.84399-1-redsky110@gmail.com> (raw)

We are getting port for connect() from even ports firstly now. This
makes bind() users have more available slots at odd part. But there is a
problem here when the even ports are used up. This happens when there
is a flood of short life cycle connections. In this scenario, it starts
getting ports from the odd part, but each requirement has to walk all of
the even port and the related hash buckets (it probably gets nothing
before the workload pressure's gone) before go to the odd part. This
makes the code path __inet_hash_connect()->__inet_check_established()
and the locks there hot.

This patch tries to improve the strategy so we can go faster when the
even part is used up. It'll record the last gotten port was odd or even,
if it's an odd one, it means there is no available even port for us and
we probably can't get an even port this time, neither. So we just walk
1/16 of the whole even ports. If we can get one in this way, it probably
means there are more available even part, we'll go back to the old
strategy and walk all of them when next connect() comes. If still can't
get even port in the 1/16 part, we just go to the odd part directly and
avoid doing unnecessary loop.

Signed-off-by: Honglei Wang <redsky110@gmail.com>
---
 net/ipv4/inet_hashtables.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 45fb450b4522..c95bf5cf9323 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -721,9 +721,10 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 	struct net *net = sock_net(sk);
 	struct inet_bind_bucket *tb;
 	u32 remaining, offset;
-	int ret, i, low, high;
+	int ret, i, low, high, span;
 	static u32 hint;
 	int l3mdev;
+	static bool last_port_is_odd;
 
 	if (port) {
 		head = &hinfo->bhash[inet_bhashfn(net, port,
@@ -756,8 +757,19 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 	 */
 	offset &= ~1U;
 other_parity_scan:
+	/* If the last available port is odd, it means
+	 * we walked all of the even ports, but got
+	 * nothing last time. It's telling us the even
+	 * part is busy to get available port. In this
+	 * case, we can go a bit faster.
+	 */
+	if (last_port_is_odd && !(offset & 1) && remaining > 32)
+		span = 32;
+	else
+		span = 2;
+
 	port = low + offset;
-	for (i = 0; i < remaining; i += 2, port += 2) {
+	for (i = 0; i < remaining; i += span, port += span) {
 		if (unlikely(port >= high))
 			port -= remaining;
 		if (inet_is_local_reserved_port(net, port))
@@ -806,6 +818,11 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 ok:
 	hint += i + 2;
 
+	if (offset & 1)
+		last_port_is_odd = true;
+	else
+		last_port_is_odd = false;
+
 	/* Head lock still held and bh's disabled */
 	inet_bind_hash(sk, tb, port);
 	if (sk_unhashed(sk)) {
-- 
2.14.1


             reply	other threads:[~2021-02-20 11:05 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-20 11:03 Honglei Wang [this message]
2021-02-20 21:44 ` [PATCH] tcp: avoid unnecessary loop if even ports are used up David Miller
2021-02-20 22:06   ` Jeremy Sowden
2021-02-22  1:11     ` Honglei Wang
2021-02-22  7:47 ` Eric Dumazet
2021-02-22 11:09   ` Honglei Wang
2021-02-22 11:29     ` Eric Dumazet
2021-02-22 11:57       ` Honglei Wang
2021-03-03  9:00 ` [tcp] ff0d41306d: stress-ng.sockmany.ops_per_sec 338.2% improvement kernel test robot

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=20210220110356.84399-1-redsky110@gmail.com \
    --to=redsky110@gmail.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=netdev@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).