[LTP] [PATCH v2] kernel/device-drivers/zram/zram01.sh : don't fill from /dev/zero

Ian Wienand iwienand@redhat.com
Tue Aug 8 05:56:42 CEST 2023


I have a system (virtualized aarch64, 4.18.0 kernel) that is
consistently failing the zram01.sh test as it tries to divide the
memory stats by zero.  This has been reported before at [1] without
resolution.

After some investigation [2] my conclusion is that this zero value
represents the pages allocated for compressed storage in the zram
device, and due to same-page deduplication the extant method of
filling with all-zeros can indeed lead us to not having any compressed
data to measure.

This is visible in the occasional divide-by-zero error, but in the
bigger picture means this test is not exercising the compression path
as desired.

The approach here is to mix the write values to make something
compressible but avoid the same-page deduplication.  However, to cover
both paths, as described inline, we write out a few pages worth and
double-check the stats reflect deduplicated pages.

This also adds the sync, as discussed in prior version [3] to increase
the reliability of testing.

[1] https://lists.linux.it/pipermail/ltp/2019-July/013028.html
[2] https://lists.linux.it/pipermail/ltp/2023-August/034585.html
[3] https://lists.linux.it/pipermail/ltp/2023-August/034560.html

Signed-off-by: Ian Wienand <iwienand@redhat.com>
---
 .../kernel/device-drivers/zram/zram01.sh      | 56 ++++++++++++++++---
 1 file changed, 49 insertions(+), 7 deletions(-)

diff --git a/testcases/kernel/device-drivers/zram/zram01.sh b/testcases/kernel/device-drivers/zram/zram01.sh
index 58d233f91..619d47f93 100755
--- a/testcases/kernel/device-drivers/zram/zram01.sh
+++ b/testcases/kernel/device-drivers/zram/zram01.sh
@@ -4,7 +4,7 @@
 # Author: Alexey Kodanev <alexey.kodanev@oracle.com>
 #
 # Test creates several zram devices with different filesystems on them.
-# It fills each device with zeros and checks that compression works.
+# It fills each device and checks that compression works.
 
 TST_CNT=7
 TST_TESTFUNC="do_test"
@@ -107,14 +107,39 @@ zram_mount()
 
 zram_fill_fs()
 {
-	local mem_used_total
-	local b i r v
+	local mm_stat mem_used_total same_pages
+	local b f i r v
+
+	# zram has "same page" detection that will flag pages filled
+	# with the same value.  These pages are not compressed; there
+	# is just a record left in the allocation table "page full of
+	# <x>".  mem_used_total is the number of pages held by the
+	# allocator to store store compressed data.  If we write a
+	# consistent value in the dd loop below (e.g. just /dev/zero)
+	# the only data to compress is the filesystem metadata.  It is
+	# possible the fs is not quiescent, thus this metadata is in
+	# memory (i.e. not compressed).  Consequently we could have no
+	# compressed data stored and the ratio (data/pages held for
+	# compressed data) would be a divide by zero.
+	#
+	# To make sure we are actually testing both the same-page and
+	# compression paths, we first pad with zeros but then fill
+	# with a compressible series of alternatiting 0x00 and 0xFF.
+	# This should assure we stress the compression path and can
+	# calculate the compression level reliabily.
+	dd if=/dev/zero count=1 bs=512 count=1 2>err.txt | tr "\000" "\377" > compressible
+	dd if=/dev/zero count=1 bs=512 count=1 >> compressible 2>err.txt
 
 	for i in $(seq $dev_start $dev_end); do
-		tst_res TINFO "filling zram$i (it can take long time)"
+		f='/dev/zero'
+		tst_res TINFO "zero filling zram$i"
 		b=0
 		while true; do
-			dd conv=notrunc if=/dev/zero of=zram${i}/file \
+			if [ $b == 1024 ]; then
+				f='compressible'
+				tst_res TINFO "filling zram$i with compressible data (this may take a while)"
+			fi
+			dd conv=notrunc if=$f of=zram${i}/file \
 				oflag=append count=1 bs=1024 status=none \
 				>/dev/null 2>err.txt || break
 			b=$(($b + 1))
@@ -133,7 +158,18 @@ zram_fill_fs()
 			continue
 		fi
 
-		mem_used_total=`awk '{print $3}' "/sys/block/zram$i/mm_stat"`
+		# The compression needs time to catch up so we get
+		# useful stats
+		sync
+
+		mm_stat=$(cat "/sys/block/zram$i/mm_stat")
+		tst_res TINFO "stats for zram$i : $mm_stat"
+
+		mem_used_total=`echo $mm_stat | awk '{print $3}'`
+		if [ $mem_used_total -eq 0 ]; then
+			test_res FAIL "/sys/block/zram$i/mm_stat reports 0 size : $(cat /sys/block/zram$i/mm_stat)"
+			return
+		fi
 		v=$((100 * 1024 * $b / $mem_used_total))
 		r=`echo "scale=2; $v / 100 " | bc`
 
@@ -141,9 +177,15 @@ zram_fill_fs()
 			tst_res TFAIL "compression ratio: $r:1"
 			break
 		fi
-
 		tst_res TPASS "compression ratio: $r:1"
+
+		same_pages=`echo $mm_stat | awk '{print $6}'`
+		if [ "$same_pages" -lt 10 ]; then
+		    tst_res TFAIL "insufficient same_pages: $same_pages < 10"
+		fi
+		tst_res TPASS "same_pages: $same_pages"
 	done
+	rm compressible
 }
 
 do_test()
-- 
2.41.0



More information about the ltp mailing list