public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: Stefano Brivio <sbrivio@redhat.com>
To: passt-dev@passt.top
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH v2 5/5] test: Add memory/passt test cases
Date: Mon, 31 Oct 2022 12:20:59 +0100	[thread overview]
Message-ID: <20221031112059.170269-6-sbrivio@redhat.com> (raw)
In-Reply-To: <20221031112059.170269-1-sbrivio@redhat.com>

These show a summary of memory usage in kernel and userspace with
different port forwarding configurations, details of userspace usage
using 'nm' (passt only uses statically allocated memory), and details
of kernel memory from slab reporting facilities.

This adds a new test image, mbuto.mem.img, with harcoded IPv4 and
IPv6 addresses and routes, and just the tools we need to start and
stop passt, to report from /proc/slabinfo, /proc/meminfo, and to
print and parse symbol sizes using nm(1).

passt can't pivot_root() for sandboxing purposes on ramfs, so we need
to create another filesystem and chroot into it, first.

We don't want to use pane context functions, as we're checking memory
usage for sockets: resort to screen-scraping.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
 test/Makefile        |   5 +-
 test/lib/layout_ugly |  39 +++++++++
 test/lib/setup_ugly  |  37 +++++++++
 test/memory/passt    | 187 +++++++++++++++++++++++++++++++++++++++++++
 test/passt.mem.mbuto |  42 ++++++++++
 test/run             |   4 +
 6 files changed, 313 insertions(+), 1 deletion(-)
 create mode 100644 test/memory/passt
 create mode 100755 test/passt.mem.mbuto

diff --git a/test/Makefile b/test/Makefile
index 91498ff..9f2bc42 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -55,7 +55,7 @@ UBUNTU_IMGS = $(UBUNTU_OLD_IMGS) $(UBUNTU_NEW_IMGS)
 DOWNLOAD_ASSETS = mbuto \
 	$(DEBIAN_IMGS) $(FEDORA_IMGS) $(OPENSUSE_IMGS) $(UBUNTU_IMGS)
 TESTDATA_ASSETS = small.bin big.bin medium.bin
-LOCAL_ASSETS = mbuto.img QEMU_EFI.fd \
+LOCAL_ASSETS = mbuto.img mbuto.mem.img QEMU_EFI.fd \
 	$(DEBIAN_IMGS:%=prepared-%) $(FEDORA_IMGS:%=prepared-%) \
 	$(UBUNTU_NEW_IMGS:%=prepared-%) \
 	nsholder guest-key guest-key.pub \
@@ -76,6 +76,9 @@ guest-key guest-key.pub:
 mbuto.img: passt.mbuto mbuto guest-key.pub $(TESTDATA_ASSETS)
 	./mbuto/mbuto -p ./$< -c lz4 -f $@
 
+mbuto.mem.img: passt.mem.mbuto mbuto ../passt.avx2
+	./mbuto/mbuto -p ./$< -c lz4 -f $@
+
 nsholder: nsholder.c
 	$(CC) $(CFLAGS) -o $@ $^
 
diff --git a/test/lib/layout_ugly b/test/lib/layout_ugly
index 9397b7d..d62d337 100644
--- a/test/lib/layout_ugly
+++ b/test/lib/layout_ugly
@@ -81,3 +81,42 @@ layout_pasta_simple() {
 
 	sleep 1
 }
+
+# layout_memory() - Screen-scraped panes for memory usage tests, big guest pane
+layout_memory() {
+	sleep 3
+
+	tmux kill-pane -a -t 0
+	cmd_write 0 clear
+
+	tmux split-window -h -l '35%' -t passt_test
+	tmux split-window -v -l '15%' -t passt_test
+
+	PANE_PASST=2
+	PANE_GUEST=0
+	PANE_INFO=1
+
+	get_info_cols
+
+	tmux send-keys -l -t ${PANE_INFO} 'while cat '"$STATEBASE/log_pipe"'; do :; done'
+	tmux send-keys -t ${PANE_INFO} -N 100 C-m
+	tmux select-pane -t ${PANE_INFO} -T "test log"
+
+	if context_exists guest; then
+		pane_watch_contexts ${PANE_GUEST} guest guest
+	else
+		tmux pipe-pane -O -t ${PANE_GUEST} "cat >> ${LOGDIR}/pane_guest.log"
+		tmux select-pane -t ${PANE_GUEST} -T "guest"
+	fi
+
+	if context_exists passt; then
+		pane_watch_contexts ${PANE_PASST} passt passt
+	else
+		tmux pipe-pane -O -t ${PANE_PASST} "cat >> ${LOGDIR}/pane_passt.log"
+		tmux select-pane -t ${PANE_PASST} -T "passt"
+	fi
+
+	info_layout "memory usage"
+
+	sleep 1
+}
diff --git a/test/lib/setup_ugly b/test/lib/setup_ugly
index 764177e..f2e07ba 100755
--- a/test/lib/setup_ugly
+++ b/test/lib/setup_ugly
@@ -13,6 +13,8 @@
 # Copyright (c) 2022 Red Hat GmbH
 # Author: Stefano Brivio <sbrivio@redhat.com>
 
+INITRAMFS_MEM="${BASEPATH}/mbuto.mem.img"
+
 # setup_distro() - Set up pane layout for distro tests
 setup_distro() {
 	layout_host
@@ -25,6 +27,30 @@ setup_pasta_options() {
 	layout_pasta_simple
 }
 
+# setup_memory() - Start qemu in guest pane, and passt in passt context
+setup_memory() {
+	context_setup_host passt
+
+	layout_memory
+
+	context_run passt "./passt -P ${STATESETUP}/passt.pid"
+
+	# pidfile isn't created until passt is listening
+	wait_for [ -f "${STATESETUP}/passt.pid" ]
+
+	pane_or_context_run guest './qrap 5 qemu-system-$(uname -m)'	   \
+		' -machine accel=kvm'                                      \
+		' -m '${VMEM}' -cpu host -smp '${VCPUS}                    \
+		' -kernel ' "/boot/vmlinuz-$(uname -r)"			   \
+		' -initrd '${INITRAMFS_MEM}' -nographic -serial stdio'	   \
+		' -nodefaults'						   \
+		' -append "console=ttyS0 mitigations=off apparmor=0 '	   \
+		'virtio-net.napi_tx=1"'					   \
+		" -device virtio-net-pci,netdev=hostnet0,x-txburst=16384"  \
+		" -netdev socket,fd=5,id=hostnet0"			   \
+		" -pidfile ${STATESETUP}/qemu.pid"
+}
+
 # teardown_distro() - Nothing to do, yet
 teardown_distro() {
 	:
@@ -36,3 +62,14 @@ teardown_pasta_options() {
 	teardown_context_watch ${PANE_PASST} passt
 }
 
+# teardown_passt() - Kill qemu with ^C, remove passt PID file
+teardown_memory() {
+	kill $(cat "${STATESETUP}/qemu.pid")
+
+	rm "${STATESETUP}/passt.pid"
+
+	tmux send-keys -t ${PANE_PASST} "C-c"
+
+	teardown_context_watch ${PANE_PASST} passt
+	teardown_context_watch ${PANE_GUEST} qemu
+}
diff --git a/test/memory/passt b/test/memory/passt
new file mode 100644
index 0000000..fa89821
--- /dev/null
+++ b/test/memory/passt
@@ -0,0 +1,187 @@
+# SPDX-License-Identifier: AGPL-3.0-or-later
+#
+# PASST - Plug A Simple Socket Transport
+#  for qemu/UNIX domain socket mode
+#
+# PASTA - Pack A Subtle Tap Abstraction
+#  for network namespace/tap device mode
+#
+# test/memory/passt - Show memory usage of passt in kernel and userspace
+#
+# Copyright (c) 2022 Red Hat GmbH
+# Author: Stefano Brivio <sbrivio@redhat.com>
+
+gtools	sed cat diff nm sort kill tee head tail chroot unshare mount mkdir cp 
+
+def	meminfo_row
+gout	DIFF meminfo_diff /tmp/meminfo.before /tmp/meminfo.after __WHAT__
+tl	__NAME__
+td	__DIFF__ 3 0 0
+endef
+
+def	meminfo_reverse_row
+gout	DIFF meminfo_diff /tmp/meminfo.after /tmp/meminfo.before __WHAT__
+tl	__NAME__
+td	__DIFF__ 3 0 0
+endef
+
+def	nm_row
+gout	SIZE nm_size /tmp/nm.size __WHAT__
+tl	__WHAT__
+td	__SIZE__ 6 0 0
+endef
+
+def	slab_row
+gout	COUNT slab_diff_count /tmp/slabinfo.before /tmp/slabinfo.after __WHAT__
+gout	SIZE slab_size /tmp/slabinfo.before __WHAT__
+gout	DIFF slab_diff_size /tmp/slabinfo.before /tmp/slabinfo.after __WHAT__
+tl	__WHAT__
+td	__COUNT__ 0 0 0
+td	__SIZE__ 0 0 0
+td	__DIFF__ 6 0 0
+endef
+
+def	start_stop_diff
+guest	sed /proc/slabinfo -ne 's/^\([^ ]* *[^ ]* *[^ ]* *[^ ]*\).*/\\\1/p' > /tmp/slabinfo.before
+guest	cat /proc/meminfo > /tmp/meminfo.before
+guest	/usr/bin/passt.avx2 -l /tmp/log -s /tmp/sock -P /tmp/pid __OPTS__ --netns-only
+sleep	2
+guest	cat /proc/meminfo > /tmp/meminfo.after
+guest	sed /proc/slabinfo -ne 's/^\([^ ]* *[^ ]* *[^ ]* *[^ ]*\).*/\\\1/p' > /tmp/slabinfo.after
+guest	kill \$(cat /tmp/pid)
+guest	diff -y --suppress-common-lines /tmp/meminfo.before /tmp/meminfo.after || :
+guest	nm -td -Sr --size-sort -P /usr/bin/passt.avx2 | head -30 | tee /tmp/nm.size
+guest	sed /proc/slabinfo -ne 's/\(.*<objsize>\).*$/\1/p' | tail -1; (diff -y --suppress-common-lines /tmp/slabinfo.before /tmp/slabinfo.after | sort -grk8)
+endef
+
+def	summary
+info	Memory usage summary
+info	
+th	type MiB
+set	WHAT MemFree
+set	NAME used
+meminfo_reverse_row
+set	WHAT AnonPages
+set	NAME userspace
+meminfo_row
+set	WHAT Slab
+set	NAME kernel
+meminfo_row
+te
+endef
+
+
+guest	mkdir /test
+guest	mount -t tmpfs none /test
+guest	mkdir /test/proc /test/dev /test/tmp
+guest	mount -o bind /proc /test/proc
+guest	mount -o bind /dev /test/dev
+guest	cp -Lr /bin /lib /lib64 /usr /sbin /test/
+
+guest	ulimit -Hn 300000
+guest	unshare -rUm -R /test
+guest	chroot .
+
+guest	meminfo_size() { grep "^$2:" $1 | tr -s ' ' | cut -f2 -d ' '; }
+guest	meminfo_diff() { echo $(( $(meminfo_size $2 $3) - $(meminfo_size $1 $3) )); }
+
+guest	nm_size() { grep -m1 "^$2 " $1 | cut -f4 -d ' '; }
+
+guest	slab_count() { grep "^$2 " $1 | tr -s ' ' | cut -f3 -d ' '; }
+guest	slab_size() { grep "^$2 " $1 | tr -s ' ' | cut -f4 -d ' '; }
+guest	slab_diff_count() { echo $(( $(slab_count $2 $3) - $(slab_count $1 $3) )); }
+guest	slab_diff_size() { echo $(( $(slab_count $2 $3) * $(slab_size $2 $3) - $(slab_count $1 $3) * $(slab_size $1 $3) )); }
+
+
+test	Memory usage: all TCP and UDP ports forwarded, IPv4 and IPv6
+set	OPTS -t all -u all
+start_stop_diff
+summary
+
+info	Userspace memory detail
+info	
+th	symbol MiB
+set	WHAT tcp_buf_discard
+nm_row
+set	WHAT tcp6_l2_buf
+nm_row
+set	WHAT tcp4_l2_buf
+nm_row
+set	WHAT tc
+nm_row
+set	WHAT pkt_buf
+nm_row
+set	WHAT udp_splice_map
+nm_row
+set	WHAT udp6_l2_buf
+nm_row
+set	WHAT udp4_l2_buf
+nm_row
+set	WHAT udp_tap_map
+nm_row
+set	WHAT icmp_id_map
+nm_row
+set	WHAT udp_splice_buf
+nm_row
+set	WHAT tc_hash
+nm_row
+set	WHAT pool_tap6_storage
+nm_row
+set	WHAT pool_tap4_storage
+nm_row
+set	WHAT tap6_l4
+nm_row
+set	WHAT tap4_l4
+nm_row
+te
+
+info	Kernel memory detail
+info	
+th	objects count size MiB
+set	WHAT pid
+slab_row
+set	WHAT dentry
+slab_row
+set	WHAT Acpi-Parse
+slab_row
+set	WHAT kmalloc-64
+slab_row
+set	WHAT kmalloc-32
+slab_row
+set	WHAT lsm_file_cache
+slab_row
+set	WHAT filp
+slab_row
+set	WHAT anon_vma_chain
+slab_row
+set	WHAT ep_head
+slab_row
+set	WHAT sock_inode_cache
+slab_row
+set	WHAT signal_cache
+slab_row
+set	WHAT TCPv6
+slab_row
+set	WHAT TCP
+slab_row
+set	WHAT UDPv6
+slab_row
+te
+
+
+test	Memory usage: all TCP ports forwarded, IPv4
+set	OPTS -t all -4
+start_stop_diff
+summary
+
+
+test	Memory usage: all TCP and UDP ports forwarded, IPv4
+set	OPTS -t all -u all -4
+start_stop_diff
+summary
+
+
+test	Memory usage: no ports forwarded
+set	OPTS -t none -u none
+start_stop_diff
+summary
diff --git a/test/passt.mem.mbuto b/test/passt.mem.mbuto
new file mode 100755
index 0000000..1550c15
--- /dev/null
+++ b/test/passt.mem.mbuto
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+#
+# PASST - Plug A Simple Socket Transport
+#  for qemu/UNIX domain socket mode
+#
+# test/passt.mem.mbuto - mbuto (https://mbuto.sh) profile for memory usage tests
+#
+# Copyright (c) 2022 Red Hat GmbH
+# Author: Stefano Brivio <sbrivio@redhat.com>
+
+PROGS="${PROGS:-ash,dash,bash chmod ip mount insmod mkdir ln cat chmod modprobe
+       grep mknod sed chown sleep bc ls ps mount unshare chroot cp kill diff
+       head tail sort tr tee cut nm which}"
+
+KMODS="${KMODS:- virtio_net virtio_pci vmw_vsock_virtio_transport}"
+
+NODES="${NODES:-console kmsg null ptmx random urandom zero}"
+
+LINKS="${LINKS:-
+	 ash,dash,bash		/init
+	 ash,dash,bash		/bin/sh}"
+
+DIRS="${DIRS} /tmp /sbin"
+
+COPIES="${COPIES} ../passt.avx2,/usr/bin/passt.avx2"
+
+FIXUP="${FIXUP}"'
+chmod 777 /tmp
+ip link set eth0 up
+ip address add 192.0.2.2/24 dev eth0
+ip address add 2001:db8::2/64 dev eth0
+ip route add default via 192.0.2.1
+ip -6 route add default via 2001:db8::1 dev eth0
+sleep 2
+sh +m
+'
+
+OUTPUT="KERNEL=__KERNEL__
+INITRD=__INITRD__
+"
diff --git a/test/run b/test/run
index c3486b9..e07513f 100755
--- a/test/run
+++ b/test/run
@@ -79,6 +79,10 @@ run() {
 	test pasta_options/log_to_file
 	teardown pasta_options
 
+	setup memory
+	test memory/passt
+	teardown memory
+
 	setup passt
 	test passt/ndp
 	test passt/dhcp
-- 
@@ -79,6 +79,10 @@ run() {
 	test pasta_options/log_to_file
 	teardown pasta_options
 
+	setup memory
+	test memory/passt
+	teardown memory
+
 	setup passt
 	test passt/ndp
 	test passt/dhcp
-- 
2.35.1


  parent reply	other threads:[~2022-10-31 11:20 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-31 11:20 [PATCH v2 0/5] Test cases to display memory usage in kernel and userspace Stefano Brivio
2022-10-31 11:20 ` [PATCH v2 1/5] test/lib: Move screen-scraping setup and layout functions to _ugly files Stefano Brivio
2022-11-01  0:39   ` David Gibson
2022-10-31 11:20 ` [PATCH v2 2/5] tap: Support for detection of existing sockets on ramfs Stefano Brivio
2022-11-01  0:41   ` David Gibson
2022-10-31 11:20 ` [PATCH v2 3/5] test/lib/perf_report: Use own flag to track initialisation Stefano Brivio
2022-11-01  0:41   ` David Gibson
2022-10-31 11:20 ` [PATCH v2 4/5] test/lib: Add "td" directive, handled by table_value() Stefano Brivio
2022-11-01  0:42   ` David Gibson
2022-10-31 11:20 ` Stefano Brivio [this message]
2022-11-01  0:58   ` [PATCH v2 5/5] test: Add memory/passt test cases David Gibson
2022-11-01  7:59     ` Stefano Brivio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221031112059.170269-6-sbrivio@redhat.com \
    --to=sbrivio@redhat.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=passt-dev@passt.top \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).