From 074740a32c6a36c5ba7d4be66dd4ee63e9f744f3 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 24 Jan 2018 15:53:23 -0800 Subject: [PATCH] common/rc: report kmemleak errors If kmemleak is enabled, scan and report memory leaks after every test. Note that the kmemleak check support is EXPERIMENTAL! Due to the way kmemleak works, the leak might be from an earlier test, or something totally unrelated. [eguan: add EXPERIMENTAL disclaimer in commit log too] Signed-off-by: Darrick J. Wong Reviewed-by: Eryu Guan Signed-off-by: Eryu Guan --- check | 2 ++ common/rc | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/check b/check index 2bdad399..58a2f5cc 100755 --- a/check +++ b/check @@ -499,6 +499,7 @@ _expunge_test() return 0 } +_init_kmemleak _prepare_test_list if $OPTIONS_HAVE_SECTIONS; then @@ -791,6 +792,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 diff --git a/common/rc b/common/rc index 77a4eb43..2e3a83ae 100644 --- a/common/rc +++ b/common/rc @@ -3438,6 +3438,66 @@ _check_dmesg() fi } +# capture the kmemleak report +_capture_kmemleak() +{ + local _kern_knob="${DEBUGFS_MNT}/kmemleak" + local _leak_file="$1" + + # 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}" + cat "${_kern_knob}" > /dev/null + echo "scan" > "${_kern_knob}" + cat "${_kern_knob}" > "${_leak_file}.tmp" + if [ -s "${_leak_file}.tmp" ]; then + cat > "${_leak_file}" << ENDL +EXPERIMENTAL kmemleak reported some memory leaks! Due to the way kmemleak +works, the leak might be from an earlier test, or something totally unrelated. +ENDL + cat "${_leak_file}.tmp" >> "${_leak_file}" + rm -rf "${_leak_file}.tmp" + fi + echo "clear" > "${_kern_knob}" +} + +# set up kmemleak +_init_kmemleak() +{ + local _kern_knob="${DEBUGFS_MNT}/kmemleak" + + if [ ! -w "${_kern_knob}" ]; then + return 0 + fi + + # Disable the automatic scan so that we can control it completely, + # then dump all the leaks recorded so far. + echo "scan=off" > "${_kern_knob}" + _capture_kmemleak /dev/null +} + +# check kmemleak log +_check_kmemleak() +{ + local _kern_knob="${DEBUGFS_MNT}/kmemleak" + local _leak_file="${seqres}.kmemleak" + + if [ ! -w "${_kern_knob}" ]; then + return 0 + fi + + # Capture and report any leaks + _capture_kmemleak "${_leak_file}" + if [ -s "${_leak_file}" ]; then + _dump_err "_check_kmemleak: something found in kmemleak (see ${_leak_file})" + return 1 + else + rm -f "${_leak_file}" + return 0 + fi +} + # don't check dmesg log after test _disable_dmesg_check() { -- 2.47.3