yang.yang29@ wrote: > From: zhang yunkai (CGEL ZTE) <zhang.yunkai@xxxxxxxxxx> > > The UDP GSO bench only tests the performance of userspace payload splitting > and UDP GSO. But we are also concerned about the performance comparing > with IP fragmentation and UDP GSO. In other words comparing IP fragmentation > and segmentation. > > So we add testcase of IP fragmentation of UDP packets, then user would easy > to get to know the performance promotion of UDP GSO compared with IP > fragmentation. We add a new option "-f", which is to send big data using > IP fragmentation instead of using UDP GSO or userspace payload splitting. > > In the QEMU environment we could see obvious promotion of UDP GSO. > The first test is to get the performance of userspace payload splitting. > bash# udpgso_bench_tx -l 4 -4 -D "$DST" > udp tx: 10 MB/s 7812 calls/s 186 msg/s > udp tx: 10 MB/s 7392 calls/s 176 msg/s > udp tx: 11 MB/s 7938 calls/s 189 msg/s > udp tx: 11 MB/s 7854 calls/s 187 msg/s > > The second test is to get the performance of IP fragmentation. > bash# udpgso_bench_tx -l 4 -4 -D "$DST" -f > udp tx: 33 MB/s 572 calls/s 572 msg/s > udp tx: 33 MB/s 563 calls/s 563 msg/s > udp tx: 31 MB/s 540 calls/s 540 msg/s > udp tx: 33 MB/s 571 calls/s 571 msg/s > > The third test is to get the performance of UDP GSO. > bash# udpgso_bench_tx -l 4 -4 -D "$DST" -S 0 > udp tx: 46 MB/s 795 calls/s 795 msg/s > udp tx: 49 MB/s 845 calls/s 845 msg/s > udp tx: 49 MB/s 847 calls/s 847 msg/s > udp tx: 45 MB/s 774 calls/s 774 msg/s > > Signed-off-by: zhang yunkai (CGEL ZTE) <zhang.yunkai@xxxxxxxxxx> > Reviewed-by: xu xin (CGEL ZTE) <xu.xin16@xxxxxxxxxx> > Reviewed-by: Yang Yang (CGEL ZTE) <yang.yang29@xxxxxxxxxx> > Cc: Xuexin Jiang (CGEL ZTE) <jiang.xuexin@xxxxxxxxxx> > --- > tools/testing/selftests/net/udpgso_bench_tx.c | 33 ++++++++++++++++++++++----- > 1 file changed, 27 insertions(+), 6 deletions(-) > > diff --git a/tools/testing/selftests/net/udpgso_bench_tx.c b/tools/testing/selftests/net/udpgso_bench_tx.c > index 477392715a9a..025e706b594b 100644 > --- a/tools/testing/selftests/net/udpgso_bench_tx.c > +++ b/tools/testing/selftests/net/udpgso_bench_tx.c > @@ -64,6 +64,7 @@ static int cfg_runtime_ms = -1; > static bool cfg_poll; > static int cfg_poll_loop_timeout_ms = 2000; > static bool cfg_segment; > +static bool cfg_fragment; > static bool cfg_sendmmsg; > static bool cfg_tcp; > static uint32_t cfg_tx_ts = SOF_TIMESTAMPING_TX_SOFTWARE; > @@ -375,6 +376,21 @@ static int send_udp_sendmmsg(int fd, char *data) > return ret; > } > > +static int send_udp_fragment(int fd, char *data) > +{ > + int ret; > + > + ret = sendto(fd, data, cfg_payload_len, cfg_zerocopy ? MSG_ZEROCOPY : 0, > + cfg_connected ? NULL : (void *)&cfg_dst_addr, > + cfg_connected ? 0 : cfg_alen); This should probably disable PMTU discovery with IP_PMTUDISC_OMIT to allow transmission with fragmentation of a packet that exceeds MTU. And to avoid send returning with error after ICMP destination unreachable messages if MTU is exceeded in the path. > + if (ret == -1) > + error(1, errno, "write"); > + if (ret != cfg_payload_len) > + error(1, errno, "write: %uB != %uB\n", ret, cfg_payload_len); > + > + return 1; > +} > + > static void send_udp_segment_cmsg(struct cmsghdr *cm) > { > uint16_t *valp; > @@ -429,7 +445,7 @@ static int send_udp_segment(int fd, char *data) > > static void usage(const char *filepath) > { > - error(1, 0, "Usage: %s [-46acmHPtTuvz] [-C cpu] [-D dst ip] [-l secs] " > + error(1, 0, "Usage: %s [-46acfmHPtTuvz] [-C cpu] [-D dst ip] [-l secs] " > "[-L secs] [-M messagenr] [-p port] [-s sendsize] [-S gsosize]", > filepath); > } > @@ -440,7 +456,7 @@ static void parse_opts(int argc, char **argv) > int max_len, hdrlen; > int c; > > - while ((c = getopt(argc, argv, "46acC:D:Hl:L:mM:p:s:PS:tTuvz")) != -1) { > + while ((c = getopt(argc, argv, "46acC:D:fHl:L:mM:p:s:PS:tTuvz")) != -1) { > switch (c) { > case '4': > if (cfg_family != PF_UNSPEC) > @@ -469,6 +485,9 @@ static void parse_opts(int argc, char **argv) > case 'l': > cfg_runtime_ms = strtoul(optarg, NULL, 10) * 1000; > break; > + case 'f': > + cfg_fragment = true; > + break; > case 'L': > cfg_poll_loop_timeout_ms = strtoul(optarg, NULL, 10) * 1000; > break; > @@ -527,10 +546,10 @@ static void parse_opts(int argc, char **argv) > error(1, 0, "must pass one of -4 or -6"); > if (cfg_tcp && !cfg_connected) > error(1, 0, "connectionless tcp makes no sense"); > - if (cfg_segment && cfg_sendmmsg) > - error(1, 0, "cannot combine segment offload and sendmmsg"); > - if (cfg_tx_tstamp && !(cfg_segment || cfg_sendmmsg)) > - error(1, 0, "Options -T and -H require either -S or -m option"); > + if ((cfg_segment + cfg_sendmmsg + cfg_fragment) > 1) > + error(1, 0, "cannot combine segment offload , fragment and sendmmsg"); nit: extra whitespace before comma. > + if (cfg_tx_tstamp && !(cfg_segment || cfg_sendmmsg || cfg_fragment)) > + error(1, 0, "Options -T and -H require either -S or -m or -f option"); > > if (cfg_family == PF_INET) > hdrlen = sizeof(struct iphdr) + sizeof(struct udphdr); > @@ -695,6 +714,8 @@ int main(int argc, char **argv) > num_sends += send_udp_segment(fd, buf[i]); > else if (cfg_sendmmsg) > num_sends += send_udp_sendmmsg(fd, buf[i]); > + else if (cfg_fragment) > + num_sends += send_udp_fragment(fd, buf[i]); > else > num_sends += send_udp(fd, buf[i]); > num_msgs++; > -- > 2.15.2