History

selftests: fixes for UDP GRO

The current implementation for UDP GRO tests is racy: the receiver may flush the RX queue while the sending is still transmitting and incorrectly report RX errors, with a wrong number of packet received. Add explicit timeouts to the receiver for both connection activation (first packet received for UDP) and reception completion, so that in the above critical scenario the receiver will wait for the transfer completion.

Paolo Abeni committed 7 years ago

Commit ada641f1 parent d235c482 files · +33 −17Browse files

Unified · Split

2 files
  1. tools/testing/selftests/net/udpgro.sh +4 −4
  2. tools/testing/selftests/net/udpgso_bench_rx.c +29 −13
tools/testing/selftests/net/udpgro.sh+4−4
@@ -37,7 +37,7 @@ run_one() { · 36 unmodified lines
3737
3838 cfg_veth
3939
40− ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} && \
40+ ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${rx_args} && \
4141 echo "ok" || \
4242 echo "failed" &
4343
@@ -81,7 +81,7 @@ run_one_nat() { · 37 unmodified lines
8181 # will land on the 'plain' one
8282 ip netns exec "${PEER_NS}" ./udpgso_bench_rx -G ${family} -b ${addr1} -n 0 &
8383 pid=$!
84− ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${family} -b ${addr2%/*} ${rx_args} && \
84+ ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${family} -b ${addr2%/*} ${rx_args} && \
8585 echo "ok" || \
8686 echo "failed"&
8787
@@ -99,8 +99,8 @@ run_one_2sock() { · 11 unmodified lines
9999
100100 cfg_veth
101101
102− ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} -p 12345 &
103− ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} && \
102+ ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${rx_args} -p 12345 &
103+ ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 2000 -R 10 ${rx_args} && \
104104 echo "ok" || \
105105 echo "failed" &
106106
tools/testing/selftests/net/udpgso_bench_rx.c+29−13
@@ -45,6 +45,8 @@ static int cfg_alen = sizeof(struct sockaddr_in6); · 44 unmodified lines
4545 static int cfg_expected_pkt_nr;
4646 static int cfg_expected_pkt_len;
4747 static int cfg_expected_gso_size;
48+static int cfg_connect_timeout_ms;
49+static int cfg_rcv_timeout_ms;
4850 static struct sockaddr_storage cfg_bind_addr;
4951
5052 static bool interrupted;
@@ -87,7 +89,7 @@ static unsigned long gettimeofday_ms(void) · 36 unmodified lines
8789 return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
8890 }
8991
90−static void do_poll(int fd)
92+static void do_poll(int fd, int timeout_ms)
9193 {
9294 struct pollfd pfd;
9395 int ret;
@@ -102,8 +104,16 @@ static void do_poll(int fd) · 8 unmodified lines
102104 break;
103105 if (ret == -1)
104106 error(1, errno, "poll");
105− if (ret == 0)
106− continue;
107+ if (ret == 0) {
108+ if (!timeout_ms)
109+ continue;
110+
111+ timeout_ms -= 10;
112+ if (timeout_ms <= 0) {
113+ interrupted = true;
114+ break;
115+ }
116+ }
107117 if (pfd.revents != POLLIN)
108118 error(1, errno, "poll: 0x%x expected 0x%x\n",
109119 pfd.revents, POLLIN);
@@ -134,7 +144,7 @@ static int do_socket(bool do_tcp) · 24 unmodified lines
134144 if (listen(accept_fd, 1))
135145 error(1, errno, "listen");
136146
137− do_poll(accept_fd);
147+ do_poll(accept_fd, cfg_connect_timeout_ms);
138148 if (interrupted)
139149 exit(0);
140150
@@ -273,7 +283,9 @@ static void do_flush_udp(int fd) · 132 unmodified lines
273283
274284 static void usage(const char *filepath)
275285 {
276− error(1, 0, "Usage: %s [-Grtv] [-b addr] [-p port] [-l pktlen] [-n packetnr] [-S gsosize]", filepath);
286+ error(1, 0, "Usage: %s [-C connect_timeout] [-Grtv] [-b addr] [-p port]"
287+ " [-l pktlen] [-n packetnr] [-R rcv_timeout] [-S gsosize]",
288+ filepath);
277289 }
278290
279291 static void parse_opts(int argc, char **argv)
@@ -282,7 +294,7 @@ static void parse_opts(int argc, char **argv) · 2 unmodified lines
282294
283295 /* bind to any by default */
284296 setup_sockaddr(PF_INET6, "::", &cfg_bind_addr);
285− while ((c = getopt(argc, argv, "4b:Gl:n:p:rS:tv")) != -1) {
297+ while ((c = getopt(argc, argv, "4b:C:Gl:n:p:rR:S:tv")) != -1) {
286298 switch (c) {
287299 case '4':
288300 cfg_family = PF_INET;
@@ -292,6 +304,9 @@ static void parse_opts(int argc, char **argv) · 3 unmodified lines
292304 case 'b':
293305 setup_sockaddr(cfg_family, optarg, &cfg_bind_addr);
294306 break;
307+ case 'C':
308+ cfg_connect_timeout_ms = strtoul(optarg, NULL, 0);
309+ break;
295310 case 'G':
296311 cfg_gro_segment = true;
297312 break;
@@ -307,6 +322,9 @@ static void parse_opts(int argc, char **argv) · 9 unmodified lines
307322 case 'r':
308323 cfg_read_all = true;
309324 break;
325+ case 'R':
326+ cfg_rcv_timeout_ms = strtoul(optarg, NULL, 0);
327+ break;
310328 case 'S':
311329 cfg_expected_gso_size = strtol(optarg, NULL, 0);
312330 break;
@@ -329,8 +347,9 @@ static void parse_opts(int argc, char **argv) · 16 unmodified lines
329347
330348 static void do_recv(void)
331349 {
350+ int timeout_ms = cfg_tcp ? cfg_rcv_timeout_ms : cfg_connect_timeout_ms;
332351 unsigned long tnow, treport;
333− int fd, loop = 0;
352+ int fd;
334353
335354 fd = do_socket(cfg_tcp);
336355
@@ -342,12 +361,7 @@ static void do_recv(void) · 5 unmodified lines
342361
343362 treport = gettimeofday_ms() + 1000;
344363 do {
345− /* force termination after the second poll(); this cope both
346− * with sender slower than receiver and missing packet errors
347− */
348− if (cfg_expected_pkt_nr && loop++)
349− interrupted = true;
350− do_poll(fd);
364+ do_poll(fd, timeout_ms);
351365
352366 if (cfg_tcp)
353367 do_flush_tcp(fd);
@@ -365,6 +379,8 @@ static void do_recv(void) · 11 unmodified lines
365379 treport = tnow + 1000;
366380 }
367381
382+ timeout_ms = cfg_rcv_timeout_ms;
383+
368384 } while (!interrupted);
369385
370386 if (cfg_expected_pkt_nr && (packets != cfg_expected_pkt_nr))