net: lib: zperf: improve UDP RX throughput

The original flow of socket_service thread handling the Zperf UDP RX
packets is: zsock_poll() polls all sockets for events, if ctx->recv_q
of Zperf is not empty, it will call trigger_work() -> udp_recv_data()
-> zsock_recvfrom() to read only one UDP packet from ctx->recv_q, then
go back to zsock_poll() and run the same process again, which is
inefficient.
The alternative solution is, in udp_recv_data(), it should exhaust all
the packets in the current ctx->recv_q, and then go back to
zsock_poll() to run the same process again.
In our Wi-Fi test case, for WPA3 security mode of 5GHz, the STA UDP RX
throughput can be improved from 91.48 Mbps to 99.87 Mbps, the SAP UDP
RX throughput can be improved from 85.97 Mbps to 96.00 Mbps.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
This commit is contained in:
Maochen Wang 2025-03-17 16:03:17 +08:00 committed by Benjamin Cabé
commit cb65dfbd2b

View file

@ -315,7 +315,7 @@ static void udp_receiver_cleanup(void)
static int udp_recv_data(struct net_socket_service_event *pev)
{
static uint8_t buf[UDP_RECEIVER_BUF_SIZE];
int ret = 0;
int ret = 1;
int family, sock_error;
struct sockaddr addr;
socklen_t optlen = sizeof(int);
@ -341,19 +341,25 @@ static int udp_recv_data(struct net_socket_service_event *pev)
return 0;
}
ret = zsock_recvfrom(pev->event.fd, buf, sizeof(buf), 0,
&addr, &addrlen);
if (ret < 0) {
ret = -errno;
(void)zsock_getsockopt(pev->event.fd, SOL_SOCKET,
SO_DOMAIN, &family, &optlen);
NET_ERR("recv failed on IPv%d socket (%d)",
family == AF_INET ? 4 : 6, -ret);
goto error;
while (ret > 0) {
ret = zsock_recvfrom(pev->event.fd, buf, sizeof(buf), ZSOCK_MSG_DONTWAIT,
&addr, &addrlen);
if ((ret < 0) && (errno == EAGAIN)) {
ret = 0;
break;
}
if (ret < 0) {
ret = -errno;
(void)zsock_getsockopt(pev->event.fd, SOL_SOCKET,
SO_DOMAIN, &family, &optlen);
NET_ERR("recv failed on IPv%d socket (%d)",
family == AF_INET ? 4 : 6, -ret);
goto error;
}
udp_received(pev->event.fd, &addr, buf, ret);
}
udp_received(pev->event.fd, &addr, buf, ret);
return ret;
error: