diff --git a/include/haproxy/fd.h b/include/haproxy/fd.h index 4ea24975b..faaeaa645 100644 --- a/include/haproxy/fd.h +++ b/include/haproxy/fd.h @@ -48,6 +48,7 @@ extern struct polled_mask *polled_mask; extern THREAD_LOCAL int *fd_updt; // FD updates list extern THREAD_LOCAL int fd_nbupdt; // number of updates in the list +extern THREAD_LOCAL int fd_highest;// highest FD known by the current thread extern int poller_wr_pipe[MAX_THREADS]; @@ -466,6 +467,19 @@ static inline void fd_insert(int fd, void *owner, void (*iocb)(int fd), int tgid if ((global.tune.options & GTUNE_FD_ET) && iocb == sock_conn_iocb) newstate |= FD_ET_POSSIBLE; + /* We must update fd_highest to reflect the highest known FD for this + * thread. It's important to note that it's not necessarily the highest + * FD the thread will see, it's the highest FD that was inserted by + * this thread or by the main thread. The purpose is essentially to + * let all threads know the highest known FD at boot, that will be + * cloned into each thread, in order to limit the work range for init + * functions such as fork_poller() and fd_reregister_all(). Keeping the + * value thread-local substantially limits the cost, since after a few + * thousand calls the value will just stop changing. + */ + if (unlikely(fd > fd_highest)) + fd_highest = fd; + /* This must never happen and would definitely indicate a bug, in * addition to overwriting some unexpected memory areas. */ diff --git a/src/fd.c b/src/fd.c index 2dd265527..cf77884b1 100644 --- a/src/fd.c +++ b/src/fd.c @@ -112,6 +112,7 @@ volatile struct fdlist update_list[MAX_TGROUPS]; // Global update list THREAD_LOCAL int *fd_updt = NULL; // FD updates list THREAD_LOCAL int fd_nbupdt = 0; // number of updates in the list +THREAD_LOCAL int fd_highest = -1; // highest FD known by the current thread THREAD_LOCAL int poller_rd_pipe = -1; // Pipe to wake the thread int poller_wr_pipe[MAX_THREADS] __read_mostly; // Pipe to wake the threads @@ -836,7 +837,7 @@ void fd_reregister_all(int tgrp, ulong mask) { int fd; - for (fd = 0; fd < global.maxsock; fd++) { + for (fd = 0; fd < fd_highest; fd++) { if (!fdtab[fd].owner) continue; @@ -1271,7 +1272,7 @@ int list_pollers(FILE *out) int fork_poller() { int fd; - for (fd = 0; fd < global.maxsock; fd++) { + for (fd = 0; fd < fd_highest; fd++) { if (fdtab[fd].owner) { HA_ATOMIC_OR(&fdtab[fd].state, FD_CLONED); }