On Tue, Jun 16, 2026 at 07:10:51PM +0200, Laurent Vivier wrote:
The pre-opened socket pools init_sock_pool4/6 are consumed by tcp_conn_pool_sock() when creating new connections from any worker thread, and refilled by tcp_sock_refill_pool() from tcp_timer() in post_handler(). These can run concurrently on different threads.
Add a mutex protecting both operations in tcp_conn_sock() and tcp_sock_refill_init(), where init namespace pools are accessed.
I wonder if we might be better off with a per-qpair/thread socket pool instead of a mutexed common pool. The obvious tradeoff would be that the pool is smaller so a thread could run out of sockets while we still have some available on another thread. But, having a common pool only gains us there if the mutex lock is significantly cheaper than the system calls to refill the pool. That might be the case, but I'm not certain.
Signed-off-by: Laurent Vivier
--- tcp.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tcp.c b/tcp.c index 955012355d69..019340c1c348 100644 --- a/tcp.c +++ b/tcp.c @@ -293,6 +293,7 @@ #include
#include #include +#include #include
#include @@ -439,6 +440,7 @@ static socklen_t tcp_info_size; /* Pools for pre-opened sockets (in init) */ int init_sock_pool4 [TCP_SOCK_POOL_SIZE]; int init_sock_pool6 [TCP_SOCK_POOL_SIZE]; +static pthread_mutex_t sock_pool_lock = PTHREAD_MUTEX_INITIALIZER; /** * conn_at_sidx() - Get TCP connection specific flow at given sidx @@ -1568,7 +1570,11 @@ int tcp_conn_sock(sa_family_t af) int *pool = af == AF_INET6 ? init_sock_pool6 : init_sock_pool4; int s;
- if ((s = tcp_conn_pool_sock(pool)) >= 0) + pthread_mutex_lock(&sock_pool_lock); + s = tcp_conn_pool_sock(pool); + pthread_mutex_unlock(&sock_pool_lock); + + if (s >= 0) return s;
/* If the pool is empty we just open a new one without refilling the @@ -2857,6 +2863,7 @@ int tcp_sock_refill_pool(int pool[], sa_family_t af) */ static void tcp_sock_refill_init(const struct ctx *c) { + pthread_mutex_lock(&sock_pool_lock); if (c->ifi4) { int rc = tcp_sock_refill_pool(init_sock_pool4, AF_INET); if (rc < 0) @@ -2869,6 +2876,7 @@ static void tcp_sock_refill_init(const struct ctx *c) warn("TCP: Error refilling IPv6 host socket pool: %s", strerror_(-rc)); } + pthread_mutex_unlock(&sock_pool_lock); }
/** -- 2.54.0
-- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson