Skip to content

Commit af2b7e5

Browse files
Zijian Zhangkuba-moo
authored andcommitted
selftests: fix OOM in msg_zerocopy selftest
In selftests/net/msg_zerocopy.c, it has a while loop keeps calling sendmsg on a socket with MSG_ZEROCOPY flag, and it will recv the notifications until the socket is not writable. Typically, it will start the receiving process after around 30+ sendmsgs. However, as the introduction of commit dfa2f04 ("tcp: get rid of sysctl_tcp_adv_win_scale"), the sender is always writable and does not get any chance to run recv notifications. The selftest always exits with OUT_OF_MEMORY because the memory used by opt_skb exceeds the net.core.optmem_max. Meanwhile, it could be set to a different value to trigger OOM on older kernels too. Thus, we introduce "cfg_notification_limit" to force sender to receive notifications after some number of sendmsgs. Fixes: 07b65c5 ("test: add msg_zerocopy test") Signed-off-by: Zijian Zhang <[email protected]> Signed-off-by: Xiaochun Lu <[email protected]> Reviewed-by: Willem de Bruijn <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent f66738d commit af2b7e5

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

tools/testing/selftests/net/msg_zerocopy.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static bool cfg_rx;
8585
static int cfg_runtime_ms = 4200;
8686
static int cfg_verbose;
8787
static int cfg_waittime_ms = 500;
88+
static int cfg_notification_limit = 32;
8889
static bool cfg_zerocopy;
8990

9091
static socklen_t cfg_alen;
@@ -95,6 +96,7 @@ static char payload[IP_MAXPACKET];
9596
static long packets, bytes, completions, expected_completions;
9697
static int zerocopied = -1;
9798
static uint32_t next_completion;
99+
static uint32_t sends_since_notify;
98100

99101
static unsigned long gettimeofday_ms(void)
100102
{
@@ -208,6 +210,7 @@ static bool do_sendmsg(int fd, struct msghdr *msg, bool do_zerocopy, int domain)
208210
error(1, errno, "send");
209211
if (cfg_verbose && ret != len)
210212
fprintf(stderr, "send: ret=%u != %u\n", ret, len);
213+
sends_since_notify++;
211214

212215
if (len) {
213216
packets++;
@@ -460,6 +463,7 @@ static bool do_recv_completion(int fd, int domain)
460463
static void do_recv_completions(int fd, int domain)
461464
{
462465
while (do_recv_completion(fd, domain)) {}
466+
sends_since_notify = 0;
463467
}
464468

465469
/* Wait for all remaining completions on the errqueue */
@@ -549,6 +553,9 @@ static void do_tx(int domain, int type, int protocol)
549553
else
550554
do_sendmsg(fd, &msg, cfg_zerocopy, domain);
551555

556+
if (cfg_zerocopy && sends_since_notify >= cfg_notification_limit)
557+
do_recv_completions(fd, domain);
558+
552559
while (!do_poll(fd, POLLOUT)) {
553560
if (cfg_zerocopy)
554561
do_recv_completions(fd, domain);
@@ -708,7 +715,7 @@ static void parse_opts(int argc, char **argv)
708715

709716
cfg_payload_len = max_payload_len;
710717

711-
while ((c = getopt(argc, argv, "46c:C:D:i:mp:rs:S:t:vz")) != -1) {
718+
while ((c = getopt(argc, argv, "46c:C:D:i:l:mp:rs:S:t:vz")) != -1) {
712719
switch (c) {
713720
case '4':
714721
if (cfg_family != PF_UNSPEC)
@@ -736,6 +743,9 @@ static void parse_opts(int argc, char **argv)
736743
if (cfg_ifindex == 0)
737744
error(1, errno, "invalid iface: %s", optarg);
738745
break;
746+
case 'l':
747+
cfg_notification_limit = strtoul(optarg, NULL, 0);
748+
break;
739749
case 'm':
740750
cfg_cork_mixed = true;
741751
break;

0 commit comments

Comments
 (0)