[linux-next] selftests: net: udpgso_bench_tx: Add test for IP fragmentation of UDP packets

Message ID 202302241438536013777@zte.com.cn
State New
Headers
Series [linux-next] selftests: net: udpgso_bench_tx: Add test for IP fragmentation of UDP packets |

Commit Message

Yang Yang Feb. 24, 2023, 6:38 a.m. UTC
  From: zhang yunkai (CGEL ZTE) <zhang.yunkai@zte.com.cn>

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@zte.com.cn>
Reviewed-by: xu xin (CGEL ZTE) <xu.xin16@zte.com.cn>
Reviewed-by: Yang Yang (CGEL ZTE) <yang.yang29@zte.com.cn>
Cc: Xuexin Jiang (CGEL ZTE) <jiang.xuexin@zte.com.cn>
---
 tools/testing/selftests/net/udpgso_bench_tx.c | 33 ++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 6 deletions(-)
  

Comments

Willem de Bruijn Feb. 24, 2023, 2:47 p.m. UTC | #1
yang.yang29@ wrote:
> From: zhang yunkai (CGEL ZTE) <zhang.yunkai@zte.com.cn>
> 
> 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@zte.com.cn>
> Reviewed-by: xu xin (CGEL ZTE) <xu.xin16@zte.com.cn>
> Reviewed-by: Yang Yang (CGEL ZTE) <yang.yang29@zte.com.cn>
> Cc: Xuexin Jiang (CGEL ZTE) <jiang.xuexin@zte.com.cn>
> ---
>  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
  

Patch

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);
+	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");
+	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++;