From: Willy Tarreau Date: Thu, 30 Jan 2025 14:59:11 +0000 (+0100) Subject: DEBUG: fd: add a counter of takeovers of an FD since it was last opened X-Git-Tag: v3.2-dev5~72 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=44ac7a7e731537c9388a141b69cff7074afe2376;p=thirdparty%2Fhaproxy.git DEBUG: fd: add a counter of takeovers of an FD since it was last opened That's essentially in order to help with debugging strange cases like the occasional epoll issues/races, by keeping a counter of how many times an FD was taken over since last inserted. The room is available so let's use it. If it's needed later, this patch can easily be reverted. The counter is also reported in "show fd" as "tkov". --- diff --git a/include/haproxy/fd-t.h b/include/haproxy/fd-t.h index c5e94cbec..c2b2aee20 100644 --- a/include/haproxy/fd-t.h +++ b/include/haproxy/fd-t.h @@ -193,6 +193,11 @@ struct fdtab { void *owner; /* the connection or listener associated with this fd, NULL if closed */ unsigned int state; /* FD state for read and write directions (FD_EV_*) + FD_POLL_* */ unsigned int refc_tgid; /* refcounted tgid, updated atomically */ + /* the info below are mainly used for epoll debugging/strengthening. + * they're filling the rest of the cache line but may easily be dropped + * if the room is needed for more important stuff. + */ + unsigned int nb_takeover; /* number of times this FD was taken over since inserted (used for debugging) */ #ifdef DEBUG_FD unsigned int event_count; /* number of events reported */ #endif diff --git a/include/haproxy/fd.h b/include/haproxy/fd.h index faaeaa645..a83539e48 100644 --- a/include/haproxy/fd.h +++ b/include/haproxy/fd.h @@ -500,6 +500,10 @@ static inline void fd_insert(int fd, void *owner, void (*iocb)(int fd), int tgid fdtab[fd].iocb = iocb; fdtab[fd].state = newstate; fdtab[fd].thread_mask = thread_mask; + + /* just for debugging: how many times taken over since last fd_insert() */ + fdtab[fd].nb_takeover = 0; + fd_drop_tgid(fd); #ifdef DEBUG_FD diff --git a/src/cli.c b/src/cli.c index d5cc34499..d00b5b241 100644 --- a/src/cli.c +++ b/src/cli.c @@ -1415,7 +1415,7 @@ static int cli_io_handler_show_fd(struct appctx *appctx) suspicious = 1; chunk_printf(&trash, - " %5d : st=0x%06x(%c%c %c%c%c%c%c W:%c%c%c R:%c%c%c) ref=%#x gid=%d tmask=0x%lx umask=0x%lx prmsk=0x%lx pwmsk=0x%lx owner=%p iocb=%p(", + " %5d : st=0x%06x(%c%c %c%c%c%c%c W:%c%c%c R:%c%c%c) ref=%#x gid=%d tmask=0x%lx umask=0x%lx prmsk=0x%lx pwmsk=0x%lx owner=%p tkov=%u iocb=%p(", fd, fdt.state, (fdt.state & FD_CLONED) ? 'C' : 'c', @@ -1437,6 +1437,7 @@ static int cli_io_handler_show_fd(struct appctx *appctx) polled_mask[fd].poll_recv, polled_mask[fd].poll_send, fdt.owner, + fdt.nb_takeover, fdt.iocb); resolve_sym_name(&trash, NULL, fdt.iocb); diff --git a/src/fd.c b/src/fd.c index cf77884b1..bf4241ba2 100644 --- a/src/fd.c +++ b/src/fd.c @@ -542,6 +542,9 @@ int fd_takeover(int fd, void *expected_owner) */ fd_stop_recv(fd); + /* essentially for debugging */ + fdtab[fd].nb_takeover++; + /* we're done with it */ HA_ATOMIC_AND(&fdtab[fd].running_mask, ~ti->ltid_bit);