From d20f2b44e242266873ad9d06b2a18a8d7a9f9105 Mon Sep 17 00:00:00 2001 From: Kyle Stanfield Date: Mon, 15 Sep 2025 14:56:25 -0700 Subject: [PATCH 1/2] Add no_delay flag to neper to set TCP_NODELAY sockopt --- common.c | 7 +++++++ common.h | 1 + define_all_flags.c | 1 + lib.h | 1 + socket.c | 2 ++ 5 files changed, 12 insertions(+) diff --git a/common.c b/common.c index c8c2e29..66a7478 100644 --- a/common.c +++ b/common.c @@ -233,6 +233,13 @@ void set_tcp_tx_delay(int fd, int delay, struct callbacks *cb) PLOG_ERROR(cb, "setsockopt(TCP_TX_DELAY)"); } +void set_tcp_no_delay(int fd, struct callbacks *cb) +{ + int value = true; + if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &value, sizeof(value))) + PLOG_ERROR(cb, "setsockopt(TCP_NODELAY)"); +} + void fill_random(char *buf, int size) { int fd, chunk, done = 0; diff --git a/common.h b/common.h index 3da948f..3d17ac3 100644 --- a/common.h +++ b/common.h @@ -157,6 +157,7 @@ void set_freebind(int fd, struct callbacks *cb); void set_debug(int fd, int onoff, struct callbacks *cb); void set_mark(int fd, int mark, struct callbacks *cb); void set_tcp_tx_delay(int fd, int delay, struct callbacks *cb); +void set_tcp_no_delay(int fd, struct callbacks *cb); void fill_random(char *buf, int size); int do_close(int fd); struct addrinfo *copy_addrinfo(const struct addrinfo *); diff --git a/define_all_flags.c b/define_all_flags.c index cf9ea82..fc71234 100644 --- a/define_all_flags.c +++ b/define_all_flags.c @@ -72,6 +72,7 @@ struct flags_parser *add_flags_tcp(struct flags_parser *fp) DEFINE_FLAG(fp, bool, pin_numa, false, 'N', "Pin threads to CPU cores"); #endif DEFINE_FLAG(fp, int, tcp_tx_delay, 0, 't', "Force usec delay in TCP flows"); + DEFINE_FLAG(fp, bool, no_delay, false, 0, "Set TCP_NODELAY sockopt on data sockets to disable Nagle's algorithm"); /* Return the updated fp */ return (fp); diff --git a/lib.h b/lib.h index 5483ce2..7db0e79 100644 --- a/lib.h +++ b/lib.h @@ -94,6 +94,7 @@ struct options { bool skip_rx_copy; bool tx_zerocopy; bool rx_zerocopy; + bool no_delay; bool time_wait; double interval; long long max_pacing_rate; diff --git a/socket.c b/socket.c index bcef7cb..3238c4e 100644 --- a/socket.c +++ b/socket.c @@ -61,6 +61,8 @@ static void socket_init_not_established(struct thread *t, int s) if (err) PLOG_ERROR(t->cb, "setsockopt(SO_LINGER)"); } + if (opts->no_delay) + set_tcp_no_delay(s, cb); } /* From 6cb4af093e814d7a9fd78c8ce9378aa757e97139 Mon Sep 17 00:00:00 2001 From: Kyle Stanfield Date: Mon, 15 Sep 2025 14:59:07 -0700 Subject: [PATCH 2/2] Add no_cork option to unset MSG_MORE on tcp data sockets --- define_all_flags.c | 1 + lib.h | 1 + tcp_stream_main.c | 2 ++ 3 files changed, 4 insertions(+) diff --git a/define_all_flags.c b/define_all_flags.c index fc71234..e00c6f6 100644 --- a/define_all_flags.c +++ b/define_all_flags.c @@ -150,6 +150,7 @@ struct flags_parser *add_flags_tcp_stream(struct flags_parser *fp) DEFINE_FLAG(fp, bool, split_bidir , false, 0, "Bidirectional using separate tx/rx sockets"); DEFINE_FLAG(fp, bool, enable_tcp_maerts, false, 'M', "Enables TCP_MAERTS test (server writes and client reads). It overrides enable_read, and enable_write"); DEFINE_FLAG(fp, bool, async_connect, false, 0, "use non blocking connect"); + DEFINE_FLAG(fp, bool, no_cork, false, 0, "Do not set MSG_MORE when sending over data sockets."); /* Return the updated fp */ return (fp); diff --git a/lib.h b/lib.h index 7db0e79..cd3101b 100644 --- a/lib.h +++ b/lib.h @@ -95,6 +95,7 @@ struct options { bool tx_zerocopy; bool rx_zerocopy; bool no_delay; + bool no_cork; bool time_wait; double interval; long long max_pacing_rate; diff --git a/tcp_stream_main.c b/tcp_stream_main.c index 59366e3..937cc04 100644 --- a/tcp_stream_main.c +++ b/tcp_stream_main.c @@ -60,6 +60,8 @@ int main(int argc, char **argv) opts.recv_flags = MSG_TRUNC; if (opts.tx_zerocopy) opts.send_flags = MSG_ZEROCOPY; + if (!opts.no_cork) + opts.send_flags |= MSG_MORE; flags_parser_dump(fp); flags_parser_destroy(fp);