public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: Stefano Brivio <sbrivio@redhat.com>
Cc: passt-dev@passt.top
Subject: Re: [PATCH v2 5/5] test: Add memory/passt test cases
Date: Tue, 1 Nov 2022 11:58:26 +1100	[thread overview]
Message-ID: <Y2BvMovjBiFLA1e1@yekko> (raw)
In-Reply-To: <20221031112059.170269-6-sbrivio@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 13491 bytes --]

On Mon, Oct 31, 2022 at 12:20:59PM +0100, Stefano Brivio wrote:
> 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.

Huh.. weird.

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

So, we don't do it at the moment, but it should be pretty easy to make
the ssh-over-vsock stuff use a persistent control socket
(ControlPersist / ControlMaster).  That would mean we'd just establish
one connection then all the subsequent guest bound commands would go
over that one initial connection.

It wouldn't take zero socket memory of course, but it should be small
and more importantly stable.  So, if we take a diff of usage as you
already do, the results should still be good.

This patch is not working for me, for reasons I'm still debugging.
Some more minor comments in the interim.

> 
> 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

AFAICT you're always using a context pane for passt, so you don't need
this conditional.

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

You shouldn't need this for the passt pane, since it is context based,
the teardown_context_watch will do it.

> +	teardown_context_watch ${PANE_PASST} passt
> +	teardown_context_watch ${PANE_GUEST} qemu

Likewise you don't want this for the guest pane since it is *not*
context based.  

> +}
> 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

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2022-11-01  0:59 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 ` [PATCH v2 5/5] test: Add memory/passt test cases Stefano Brivio
2022-11-01  0:58   ` David Gibson [this message]
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=Y2BvMovjBiFLA1e1@yekko \
    --to=david@gibson.dropbear.id.au \
    --cc=passt-dev@passt.top \
    --cc=sbrivio@redhat.com \
    /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).