aboutgitcodebugslistschat
path: root/passt.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2022-03-18 12:18:19 +0100
committerStefano Brivio <sbrivio@redhat.com>2022-03-29 15:35:38 +0200
commitbe5bbb9b06811b98f677460fd2b89001db580582 (patch)
tree51bdd9b9e918649776806605436fc2bde3878810 /passt.c
parent3eb19cfd8a7c03920aeecae6692048429288af88 (diff)
downloadpasst-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.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/passt.c b/passt.c
index 6c04266..6550a22 100644
--- a/passt.c
+++ b/passt.c
@@ -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");