diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2022-03-18 12:18:19 +0100 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2022-03-29 15:35:38 +0200 |
commit | be5bbb9b06811b98f677460fd2b89001db580582 (patch) | |
tree | 51bdd9b9e918649776806605436fc2bde3878810 /passt.c | |
parent | 3eb19cfd8a7c03920aeecae6692048429288af88 (diff) | |
download | passt-be5bbb9b06811b98f677460fd2b89001db580582.tar passt-be5bbb9b06811b98f677460fd2b89001db580582.tar.gz passt-be5bbb9b06811b98f677460fd2b89001db580582.tar.bz2 passt-be5bbb9b06811b98f677460fd2b89001db580582.tar.lz passt-be5bbb9b06811b98f677460fd2b89001db580582.tar.xz passt-be5bbb9b06811b98f677460fd2b89001db580582.tar.zst passt-be5bbb9b06811b98f677460fd2b89001db580582.zip |
tcp: Rework timers to use timerfd instead of periodic bitmap scan
With a lot of concurrent connections, the bitmap scan approach is
not really sustainable.
Switch to per-connection timerfd timers, set based on events and on
two new flags, ACK_FROM_TAP_DUE and ACK_TO_TAP_DUE. Timers are added
to the common epoll list, and implement the existing timeouts.
While at it, drop the CONN_ prefix from flag names, otherwise they
get quite long, and fix the logic to decide if a connection has a
local, possibly unreachable endpoint: we shouldn't go through the
rest of tcp_conn_from_tap() if we reset the connection due to a
successful bind(2), and we'll get EACCES if the port number is low.
Suggested by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'passt.c')
-rw-r--r-- | passt.c | 12 |
1 files changed, 8 insertions, 4 deletions
@@ -119,12 +119,12 @@ static void post_handler(struct ctx *c, struct timespec *now) #define CALL_PROTO_HANDLER(c, now, lc, uc) \ do { \ extern void \ - lc ## _defer_handler (struct ctx *, struct timespec *) \ + lc ## _defer_handler (struct ctx *c) \ __attribute__ ((weak)); \ \ if (!c->no_ ## lc) { \ if (lc ## _defer_handler) \ - lc ## _defer_handler(c, now); \ + lc ## _defer_handler(c); \ \ if (timespec_diff_ms((now), &c->lc.timer_run) \ >= uc ## _TIMER_INTERVAL) { \ @@ -134,8 +134,11 @@ static void post_handler(struct ctx *c, struct timespec *now) } \ } while (0) + /* NOLINTNEXTLINE(bugprone-branch-clone): intervals can be the same */ CALL_PROTO_HANDLER(c, now, tcp, TCP); + /* NOLINTNEXTLINE(bugprone-branch-clone): intervals can be the same */ CALL_PROTO_HANDLER(c, now, udp, UDP); + /* NOLINTNEXTLINE(bugprone-branch-clone): intervals can be the same */ CALL_PROTO_HANDLER(c, now, icmp, ICMP); #undef CALL_PROTO_HANDLER @@ -380,8 +383,8 @@ int main(int argc, char **argv) clock_gettime(CLOCK_MONOTONIC, &now); - if ((!c.no_udp && udp_sock_init(&c, &now)) || - (!c.no_tcp && tcp_sock_init(&c, &now))) + if ((!c.no_udp && udp_sock_init(&c)) || + (!c.no_tcp && tcp_sock_init(&c))) exit(EXIT_FAILURE); proto_update_l2_buf(c.mac_guest, c.mac, &c.addr4); @@ -425,6 +428,7 @@ int main(int argc, char **argv) timer_init(&c, &now); loop: + /* NOLINTNEXTLINE(bugprone-branch-clone): intervals can be the same */ nfds = epoll_wait(c.epollfd, events, EPOLL_EVENTS, TIMER_INTERVAL); if (nfds == -1 && errno != EINTR) { perror("epoll_wait"); |