tcp_splice_epoll_ctl() removes both sockets from the epoll set if called when conn->flags & CLOSING. This will always happen immediately after setting that flag, since conn_flag_do() makes the call itself. That's also the _only_ time it can happen: we perform the EPOLL_CTL_DEL without clearing the conn->in_epoll flag, meaning that any further calls to tcp_splice_epoll_ctl() would attempt EPOLL_CTL_MOD, which would necessarily fail since the fds are no longer in the epoll. The EPOLL_CTL_DEL path in tcp_splice_epoll_ctl() has essentially zero overlap with anything else the function does, so just move them to be open coded in conn_flag_do(). Caveat: this does require kernel 2.6.9 or later, in order to pass NULL as the event structure for epoll_ctl(). I _think_ we already require newer kernels than that for other features. We could work around that if support for such old kernels is important. Given that, simply directly perform the EPOLL_CTL_DEL operations from conn_flag_do() rather than unnecessarily multiplexini Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- tcp_splice.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tcp_splice.c b/tcp_splice.c index 22a854e..e9ce268 100644 --- a/tcp_splice.c +++ b/tcp_splice.c @@ -152,8 +152,10 @@ static void conn_flag_do(const struct ctx *c, struct tcp_splice_conn *conn, } } - if (flag == CLOSING) - tcp_splice_epoll_ctl(c, conn); + if (flag == CLOSING) { + epoll_ctl(c->epollfd, EPOLL_CTL_DEL, conn->a, NULL); + epoll_ctl(c->epollfd, EPOLL_CTL_DEL, conn->b, NULL); + } } #define conn_flag(c, conn, flag) \ @@ -182,12 +184,6 @@ static int tcp_splice_epoll_ctl(const struct ctx *c, struct epoll_event ev_b = { .data.u64 = ref_b.u64 }; uint32_t events_a, events_b; - if (conn->flags & CLOSING) { - epoll_ctl(c->epollfd, EPOLL_CTL_DEL, conn->a, &ev_a); - epoll_ctl(c->epollfd, EPOLL_CTL_DEL, conn->b, &ev_b); - return 0; - } - tcp_splice_conn_epoll_events(conn->events, &events_a, &events_b); ev_a.events = events_a; ev_b.events = events_b; -- 2.41.0