All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH 0/5 net-next] Rework inet_csk_get_port
@ 2016-12-20 20:06 Josef Bacik
  2016-12-20 20:07 ` [PATCH 1/5 net-next] inet: replace ->bind_conflict with ->rcv_saddr_equal Josef Bacik
                   ` (4 more replies)
  0 siblings, 5 replies; 18+ messages in thread
From: Josef Bacik @ 2016-12-20 20:06 UTC (permalink / raw)
  To: davem, hannes, kraigatgoog, eric.dumazet, tom, netdev, kernel-team

At some point recently the guys working on our load balancer added the ability
to use SO_REUSEPORT.  When they restarted their app with this option enabled
they immediately hit a softlockup on what appeared to be the
inet_bind_bucket->lock.  Eventually what all of our debugging and discussion led
us to was the fact that the application comes up without SO_REUSEPORT, shuts
down which creates around 100k twsk's, and then comes up and tries to open a
bunch of sockets using SO_REUSEPORT, which meant traversing the inet_bind_bucket
owners list under the lock.  Since this lock is needed for dealing with the
twsk's and basically anything else related to connections we would softlockup,
and sometimes not ever recover.

To solve this problem I did what you see in Path 5/5.  Once we have a
SO_REUSEPORT socket on the tb->owners list we know that the socket has no
conflicts with any of the other sockets on that list.  So we can add a copy of
the sock_common (really all we need is the recv_saddr but it seemed ugly to copy
just the ipv6, ipv4, and flag to indicate if we were ipv6 only in there so I've
copied the whole common) in order to check subsequent SO_REUSEPORT sockets.  If
they match the previous one then we can skip the expensive
inet_csk_bind_conflict check.  This is what eliminated the soft lockup that we
were seeing.

Patches 1-4 are cleanups and re-workings.  For instance when we specify port ==
0 we need to find an open port, but we would do two passes through
inet_csk_bind_conflict every time we found a possible port.  We would also keep
track of the smallest_port value in order to try and use it if we found no
port our first run through.  This however made no sense as it would have had to
fail the first pass through inet_csk_bind_conflict, so would not actually pass
the second pass through either.  Finally I split the function into two functions
in order to make it easier to read and to distinguish between the two behaviors.

I have tested this on one of our load balancing boxes during peak traffic and it
hasn't fallen over.  But this is not my area, so obviously feel free to point
out where I'm being stupid and I'll get it fixed up and retested.  Thanks,

Josef

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2016-12-22 20:00 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-20 20:06 [RFC][PATCH 0/5 net-next] Rework inet_csk_get_port Josef Bacik
2016-12-20 20:07 ` [PATCH 1/5 net-next] inet: replace ->bind_conflict with ->rcv_saddr_equal Josef Bacik
2016-12-21 15:06   ` Hannes Frederic Sowa
2016-12-21 15:16     ` Josef Bacik
2016-12-22 20:00       ` Hannes Frederic Sowa
2016-12-21 15:23   ` Hannes Frederic Sowa
2016-12-21 15:59     ` Josef Bacik
2016-12-21 18:28   ` David Miller
2016-12-20 20:07 ` [PATCH 2/5 net-next] inet: kill smallest_size and smallest_port Josef Bacik
2016-12-21 18:30   ` David Miller
2016-12-21 19:29     ` Eric Dumazet
2016-12-21 19:32     ` Josef Bacik
2016-12-20 20:07 ` [PATCH 3/5 net-next] inet: don't check for bind conflicts twice when searching for a port Josef Bacik
2016-12-21 15:08   ` Hannes Frederic Sowa
2016-12-21 15:12     ` Josef Bacik
2016-12-20 20:07 ` [PATCH 4/5 net-next] inet: split inet_csk_get_port into two functions Josef Bacik
2016-12-20 20:07 ` [PATCH 5/5 net-next] inet: reset tb->fastreuseport when adding a reuseport sk Josef Bacik
2016-12-21 16:49   ` Craig Gallek

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.