From: Willy Tarreau Date: Sat, 9 Jul 2022 21:38:46 +0000 (+0200) Subject: MEDIUM: poller: disable thread-groups for poll() and select() X-Git-Tag: v2.7-dev2~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e5715bfacec7ce312bb6a297c534e8bbed2f8025;p=thirdparty%2Fhaproxy.git MEDIUM: poller: disable thread-groups for poll() and select() These old legacy pollers are not designed for this. They're still using a shared list of events for all threads, this will not scale at all, so there's no point in enabling thread-groups there. Modern systems have epoll, kqueue or event ports and do not need these ones. We arrange for failing at boot time, only when thread-groups > 1 so that existing setups will remain unaffected. If there's a compelling reason for supporting thread groups with these pollers in the future, the rework should not be too hard, it would just consume a lot of memory to have an fd_evts[] array per thread, but that is doable. --- diff --git a/src/ev_poll.c b/src/ev_poll.c index 3cc41dc687..b25d1dc328 100644 --- a/src/ev_poll.c +++ b/src/ev_poll.c @@ -264,6 +264,13 @@ static int _do_init(struct poller *p) int fd_evts_bytes; p->private = NULL; + + /* this old poller uses a process-wide FD list that cannot work with + * groups. + */ + if (global.nbtgroups > 1) + goto fail_srevt; + fd_evts_bytes = (global.maxsock + sizeof(**fd_evts) * 8 - 1) / (sizeof(**fd_evts) * 8) * sizeof(**fd_evts); if ((fd_evts[DIR_RD] = calloc(1, fd_evts_bytes)) == NULL) diff --git a/src/ev_select.c b/src/ev_select.c index b3e1b40e6e..af14b2e9e7 100644 --- a/src/ev_select.c +++ b/src/ev_select.c @@ -247,6 +247,12 @@ static int _do_init(struct poller *p) p->private = NULL; + /* this old poller uses a process-wide FD list that cannot work with + * groups. + */ + if (global.nbtgroups > 1) + goto fail_srevt; + if (global.maxsock > FD_SETSIZE) goto fail_srevt; diff --git a/src/haproxy.c b/src/haproxy.c index 513a967f20..3f03826a6d 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -2533,7 +2533,8 @@ static void init(int argc, char **argv) if (!init_pollers()) { ha_alert("No polling mechanism available.\n" - " It is likely that haproxy was built with TARGET=generic and that FD_SETSIZE\n" + " This may happen when using thread-groups with old pollers (poll/select), or\n" + " it is possible that haproxy was built with TARGET=generic and that FD_SETSIZE\n" " is too low on this platform to support maxconn and the number of listeners\n" " and servers. You should rebuild haproxy specifying your system using TARGET=\n" " in order to support other polling systems (poll, epoll, kqueue) or reduce the\n"