Skip to contentSkip to conversation

common/rc: report kmemleak errors

PATCH In review Darrick J. Wong 2 participants 3 messages Nov 29, 2017 – Dec 5, 2017

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 common/rc: report kmemleak errors

From: Darrick J. Wong <[email protected]>

If kmemleak is enabled, scan and report memory leaks after every test.

---
 check     |    2 ++
 common/rc |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)
check +2 -0
index b2d251a..469188e 100755
@@ -497,6 +497,7 @@ _check_filesystems()
 	fi
 }
 
+_init_kmemleak
 _prepare_test_list
 
 if $OPTIONS_HAVE_SECTIONS; then
@@ -793,6 +794,7 @@ for section in $HOST_OPTIONS_SECTIONS; do
 		    n_try=`expr $n_try + 1`
 		    _check_filesystems
 		    _check_dmesg || err=true
+		    _check_kmemleak || err=true
 		fi
 
 	    fi
common/rc +51 -0

57 lines not on this page · raw message

#1 lore raw
Quoted 35 lines · Darrick J. Wong

From: Darrick J. Wong <[email protected]>

If kmemleak is enabled, scan and report memory leaks after every test.

---
 check     |    2 ++
 common/rc |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)
check +2 -0
index b2d251a..469188e 100755
@@ -497,6 +497,7 @@ _check_filesystems()
 	fi
 }
 
+_init_kmemleak
 _prepare_test_list
 
 if $OPTIONS_HAVE_SECTIONS; then
@@ -793,6 +794,7 @@ for section in $HOST_OPTIONS_SECTIONS; do
 		    n_try=`expr $n_try + 1`
 		    _check_filesystems
 		    _check_dmesg || err=true
+		    _check_kmemleak || err=true
 		fi
 
 	    fi
common/rc +0 -0
index cb83918..6dc77d5 100644

common/rc _check_dmesg() · line 3345

Quoted 7 lines
common/rc +4 -0
@@ -3339,6 +3339,57 @@ _check_dmesg()
 	fi
 }
 
+# set up kmemleak
+_init_kmemleak()
+{
+	local _kern_knob="/sys/kernel/debug/kmemleak"

Use $DEBUGFS_MNT? e.g. $DEBUGFS_MNT/kmemleak

Quoted 4 lines
common/rc +4 -0
+
+	if [ ! -w "${_kern_knob}" ]; then
+		return 0
+	fi

common/rc _check_dmesg() · line 3359

Quoted 10 lines
common/rc +10 -0
+
+	# Scan for all the memory leaks that have happened to date and
+	# clear them so that we can pinpoint leaks to tests accurately.
+	# Scan twice because the first write finishes before the scan
+	# does....
+	echo "scan" > "${_kern_knob}"
+	cat "${_kern_knob}" > /dev/null
+	echo "scan" > "${_kern_knob}"
+	cat "${_kern_knob}" > /dev/null
+	echo "clear" > "${_kern_knob}"

So this leaves the automatic background scan on, seems this is not a problem. But how about disabling automatic scan (echo "scan=off" > $DEBUGFS_MNT/kmemleak) and only depend on the manual scan in _check_kmemleak?

Quoted 11 lines
common/rc +11 -0
+}
+
+# check kmemleak log
+_check_kmemleak()
+{
+	local _kern_knob="/sys/kernel/debug/kmemleak"
+	local _leak_file="${RESULT_DIR}/check_kmemleak"
+
+	if [ ! -w "${_kern_knob}" ]; then
+		return 0
+	fi

common/rc _check_dmesg() · line 3380

Quoted 10 lines
common/rc +10 -0
+
+	# Tell the kernel to scan for memory leaks.  Apparently the write
+	# returns before the scan is complete, so do it twice in the hopes
+	# that twice is enough to capture all the leaks.
+	echo "scan" > "${_kern_knob}"
+	sed -e 's/age [0-9\.]*s/age XXXX/g' < "${_kern_knob}" > "${_leak_file}.new"
+	echo "scan" > "${_kern_knob}"
+	sed -e 's/age [0-9\.]*s/age XXXX/g' < "${_kern_knob}" > "${_leak_file}.new"
+
+	diff -u -N "${_leak_file}" "${_leak_file}.new" > $seqres.kmemleak

Hmm, I think this reports false failure, e.g. let's say generic/001 leaks memory and generic/002 doesn't

./check generic/001 # this fails kmemleak check and populates check_kmemleak file
./check generic/002 # diff against the stale check_kmemleak file and fails the check too

How about just check if there's anything reported from $DEBUGFS_MNT/kmemleak and clearing the kmemleak buffer after each test? e.g.

echo "scan" > $DEBUGFS_MNT/kmemleak
cat $DEBUGFS_MNT/kmemleak > $seqres.kmemleak
echo "clear" > $DEBUGFS_MNT/kmemleak
if [ -s $seqres.kmemleak ]; then
_dump_err "_check_kmemleak: something found in kmemleak (see $seqres.kmemleak)" return 1
else
rm -f $seqres.kmemleak
return 0
fi

Thanks,
Eryu

Quoted 15 lines
common/rc +12 -0
+	res=$?
+	mv "${_leak_file}.new" "${_leak_file}"
+
+	if [ $res -ne 0 ]; then
+		_dump_err "_check_kmemleak: something found in kmemleak (see $seqres.kmemleak)"
+		return 1
+	else
+		rm -f $seqres.kmemleak
+		return 0
+	fi
+}
+
 # don't check dmesg log after test
 _disable_dmesg_check()
 {
#2 lore raw
Quoted 39 lines · Eryu Guan
Quoted 38 lines · Darrick J. Wong

From: Darrick J. Wong <[email protected]>

If kmemleak is enabled, scan and report memory leaks after every test.

---
 check     |    2 ++
 common/rc |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)
check +2 -0
index b2d251a..469188e 100755
@@ -497,6 +497,7 @@ _check_filesystems()
 	fi
 }
 
+_init_kmemleak
 _prepare_test_list
 
 if $OPTIONS_HAVE_SECTIONS; then
@@ -793,6 +794,7 @@ for section in $HOST_OPTIONS_SECTIONS; do
 		    n_try=`expr $n_try + 1`
 		    _check_filesystems
 		    _check_dmesg || err=true
+		    _check_kmemleak || err=true
 		fi
 
 	    fi
common/rc +0 -0
index cb83918..6dc77d5 100644
@@ -3339,6 +3339,57 @@ _check_dmesg()
 	fi
 }
 
Quoted 6 lines

common/rc _check_dmesg() · line 3345

Quoted 4 lines
common/rc +4 -0
+# set up kmemleak
+_init_kmemleak()
+{
+	local _kern_knob="/sys/kernel/debug/kmemleak"

Use $DEBUGFS_MNT? e.g. $DEBUGFS_MNT/kmemleak

Ok.

Quoted 11 lines
Quoted 11 lines
common/rc +11 -0
+
+	if [ ! -w "${_kern_knob}" ]; then
+		return 0
+	fi
+
+	# Scan for all the memory leaks that have happened to date and
+	# clear them so that we can pinpoint leaks to tests accurately.
+	# Scan twice because the first write finishes before the scan
+	# does....
+	echo "scan" > "${_kern_knob}"
+	cat "${_kern_knob}" > /dev/null
Quoted 8 lines

common/rc _check_dmesg() · line 3359

Quoted 3 lines
common/rc +3 -0
+	echo "scan" > "${_kern_knob}"
+	cat "${_kern_knob}" > /dev/null
+	echo "clear" > "${_kern_knob}"

So this leaves the automatic background scan on, seems this is not a problem. But how about disabling automatic scan (echo "scan=off" > $DEBUGFS_MNT/kmemleak) and only depend on the manual scan in _check_kmemleak?

Sure? Seeing as we trigger it manually after each test there's little reason to leave the autoscan enabled.

Quoted 31 lines
Quoted 11 lines
common/rc +11 -0
+}
+
+# check kmemleak log
+_check_kmemleak()
+{
+	local _kern_knob="/sys/kernel/debug/kmemleak"
+	local _leak_file="${RESULT_DIR}/check_kmemleak"
+
+	if [ ! -w "${_kern_knob}" ]; then
+		return 0
+	fi

common/rc _check_dmesg() · line 3380

Quoted 10 lines
common/rc +10 -0
+
+	# Tell the kernel to scan for memory leaks.  Apparently the write
+	# returns before the scan is complete, so do it twice in the hopes
+	# that twice is enough to capture all the leaks.
+	echo "scan" > "${_kern_knob}"
+	sed -e 's/age [0-9\.]*s/age XXXX/g' < "${_kern_knob}" > "${_leak_file}.new"
+	echo "scan" > "${_kern_knob}"
+	sed -e 's/age [0-9\.]*s/age XXXX/g' < "${_kern_knob}" > "${_leak_file}.new"
+
+	diff -u -N "${_leak_file}" "${_leak_file}.new" > $seqres.kmemleak

Hmm, I think this reports false failure, e.g. let's say generic/001 leaks memory and generic/002 doesn't

./check generic/001 # this fails kmemleak check and populates check_kmemleak file
./check generic/002 # diff against the stale check_kmemleak file and fails the check too

How about just check if there's anything reported from $DEBUGFS_MNT/kmemleak and clearing the kmemleak buffer after each test? e.g.

Quoted 10 lines

echo "scan" > $DEBUGFS_MNT/kmemleak
cat $DEBUGFS_MNT/kmemleak > $seqres.kmemleak
echo "clear" > $DEBUGFS_MNT/kmemleak
if [ -s $seqres.kmemleak ]; then
_dump_err "_check_kmemleak: something found in kmemleak (see $seqres.kmemleak)" return 1
else
rm -f $seqres.kmemleak
return 0
fi

That does seem simpler, though even with the manual scan we still have to read kmemleak twice to ensure that we capture all the leak information. (The memory leak scanner seems to have some kind of race condition with the sysfs write method...)

--D

Quoted 22 lines

Thanks,
Eryu

Quoted 5 lines
common/rc +5 -0
+	res=$?
+	mv "${_leak_file}.new" "${_leak_file}"
+
+	if [ $res -ne 0 ]; then
+		_dump_err "_check_kmemleak: something found in kmemleak (see $seqres.kmemleak)"

common/rc _check_dmesg() · line 3395

Quoted 10 lines
common/rc +7 -0
+		return 1
+	else
+		rm -f $seqres.kmemleak
+		return 0
+	fi
+}
+
 # don't check dmesg log after test
 _disable_dmesg_check()
 {

--
To unsubscribe from this list: send the line "unsubscribe fstests" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html