Both udp_buf_reply_sock_data() and udp_vu_reply_sock_data() internally decide what the maximum number of datagrams they will forward is. We have some upcoming reasons to allow the caller to decide that instead, so make the maximum number of datagrams a parameter for both of them. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- udp.c | 31 ++++++++++++++++++------------- udp_vu.c | 6 ++++-- udp_vu.h | 3 ++- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/udp.c b/udp.c index 4444d762..d81f1213 100644 --- a/udp.c +++ b/udp.c @@ -742,22 +742,17 @@ void udp_listen_sock_handler(const struct ctx *c, * udp_buf_reply_sock_data() - Handle new data from flow specific socket * @c: Execution context * @s: Socket to read data from + * @n: Maximum number of datagrams to forward * @tosidx: Flow & side to forward data from @s to * * Return: true on success, false if can't forward from socket to flow's pif */ -static bool udp_buf_reply_sock_data(const struct ctx *c, - int s, flow_sidx_t tosidx) +static bool udp_buf_reply_sock_data(const struct ctx *c, int s, int n, + flow_sidx_t tosidx) { const struct flowside *toside = flowside_at_sidx(tosidx); uint8_t topif = pif_at_sidx(tosidx); - /* For not entirely clear reasons (data locality?) pasta gets better - * throughput if we receive tap datagrams one at a a time. For small - * splice datagrams throughput is slightly better if we do batch, but - * it's slightly worse for large splice datagrams. Since we don't know - * the size before we receive, always go one at a time for pasta mode. - */ - int n = (c->mode == MODE_PASTA ? 1 : UDP_MAX_FRAMES), i; + int i; if ((n = udp_sock_recv(c, s, udp_mh_recv, n)) <= 0) return true; @@ -802,6 +797,14 @@ void udp_sock_handler(const struct ctx *c, union epoll_ref ref, } if (events & EPOLLIN) { + /* For not entirely clear reasons (data locality?) pasta gets + * better throughput if we receive tap datagrams one at a a + * time. For small splice datagrams throughput is slightly + * better if we do batch, but it's slightly worse for large + * splice datagrams. Since we don't know the size before we + * receive, always go one at a time for pasta mode. + */ + size_t n = (c->mode == MODE_PASTA ? 1 : UDP_MAX_FRAMES); flow_sidx_t tosidx = flow_sidx_opposite(ref.flowside); int s = ref.fd; bool ret; @@ -809,10 +812,12 @@ void udp_sock_handler(const struct ctx *c, union epoll_ref ref, flow_trace(uflow, "Received data on reply socket"); uflow->ts = now->tv_sec; - if (c->mode == MODE_VU) - ret = udp_vu_reply_sock_data(c, s, tosidx); - else - ret = udp_buf_reply_sock_data(c, s, tosidx); + if (c->mode == MODE_VU) { + ret = udp_vu_reply_sock_data(c, s, UDP_MAX_FRAMES, + tosidx); + } else { + ret = udp_buf_reply_sock_data(c, s, n, tosidx); + } if (!ret) { flow_err(uflow, "Unable to forward UDP"); diff --git a/udp_vu.c b/udp_vu.c index 5faf1e1d..b2618b39 100644 --- a/udp_vu.c +++ b/udp_vu.c @@ -257,11 +257,13 @@ void udp_vu_listen_sock_data(const struct ctx *c, union epoll_ref ref, * udp_vu_reply_sock_data() - Handle new data from flow specific socket * @c: Execution context * @s: Socket to read data from + * @n: Maximum number of datagrams to forward * @tosidx: Flow & side to forward data from @s to * * Return: true on success, false if can't forward from socket to flow's pif */ -bool udp_vu_reply_sock_data(const struct ctx *c, int s, flow_sidx_t tosidx) +bool udp_vu_reply_sock_data(const struct ctx *c, int s, int n, + flow_sidx_t tosidx) { const struct flowside *toside = flowside_at_sidx(tosidx); bool v6 = !(inany_v4(&toside->eaddr) && inany_v4(&toside->oaddr)); @@ -272,7 +274,7 @@ bool udp_vu_reply_sock_data(const struct ctx *c, int s, flow_sidx_t tosidx) if (pif_at_sidx(tosidx) != PIF_TAP) return false; - for (i = 0; i < UDP_MAX_FRAMES; i++) { + for (i = 0; i < n; i++) { ssize_t dlen; int iov_used; diff --git a/udp_vu.h b/udp_vu.h index 6d541a4e..c897c36f 100644 --- a/udp_vu.h +++ b/udp_vu.h @@ -8,6 +8,7 @@ void udp_vu_listen_sock_data(const struct ctx *c, union epoll_ref ref, const struct timespec *now); -bool udp_vu_reply_sock_data(const struct ctx *c, int s, flow_sidx_t tosidx); +bool udp_vu_reply_sock_data(const struct ctx *c, int s, int n, + flow_sidx_t tosidx); #endif /* UDP_VU_H */ -- 2.49.0