Log errors are the most widely used mechanism for reporting issues in the kernel. When an error is logged using the device helpers, eg dev_err(), it gets metadata attached that identifies the subsystem and device where the message is coming from. This series makes use of that metadata in a new test to report which devices logged errors.
The first two patches move a test and a helper script to keep things organized before this new test is added in the third patch.
It is expected that there might be many false-positive error messages throughout the drivers code which will be reported by this test. By having this test in the first place and working through the results we can address those occurrences by adjusting the loglevel of the messages that turn out to not be real errors that require the user's attention. It will also motivate additional error messages to be introduced in the code to detect real errors where they turn out to be missing, since it will be possible to detect said issues automatically.
As an example, below you can see the test result for mt8192-asurada-spherion. The single standing issue has been investigated and will be addressed in an EC firmware update [1]:
TAP version 13 1..1 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `model_name' property: -6 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `energy_full_design' property: -6 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 power_supply sbs-8-000b: driver failed to report `time_to_empty_now' property: -5 not ok 1 +power_supply:sbs-8-000b Totals: pass:0 fail:1 xfail:0 xpass:0 skip:0 error:0
[1] https://lore.kernel.org/all/cf4d8131-4b63-4c7a-9f27-5a0847c656c4@notapiano
Signed-off-by: Nícolas F. R. A. Prado nfraprado@collabora.com --- Nícolas F. R. A. Prado (3): kselftest: devices: Move discoverable devices test to subdirectory kselftest: Move ksft helper module to common directory kselftest: devices: Add test to detect device error logs
tools/testing/selftests/Makefile | 4 +- tools/testing/selftests/devices/Makefile | 4 - .../testing/selftests/devices/error_logs/Makefile | 3 + .../devices/error_logs/test_device_error_logs.py | 85 ++++++++++++++++++++++ tools/testing/selftests/devices/probe/Makefile | 4 + .../{ => probe}/boards/Dell Inc.,XPS 13 9300.yaml | 0 .../{ => probe}/boards/google,spherion.yaml | 0 .../{ => probe}/test_discoverable_devices.py | 7 +- .../selftests/{devices => kselftest}/ksft.py | 0 9 files changed, 101 insertions(+), 6 deletions(-) --- base-commit: 7b4f2bc91c15fdcf948bb2d9741a9d7d54303f8d change-id: 20240421-dev-err-log-selftest-28f5b8fc7cd0
Best regards,
Move the discoverable devices test to a subdirectory to allow other related tests to be added to the devices directory.
Signed-off-by: Nícolas F. R. A. Prado nfraprado@collabora.com --- tools/testing/selftests/Makefile | 2 +- tools/testing/selftests/devices/{ => probe}/Makefile | 2 +- .../selftests/devices/{ => probe}/boards/Dell Inc.,XPS 13 9300.yaml | 0 tools/testing/selftests/devices/{ => probe}/boards/google,spherion.yaml | 0 tools/testing/selftests/devices/{ => probe}/ksft.py | 0 .../testing/selftests/devices/{ => probe}/test_discoverable_devices.py | 0 6 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index c785b6256a45..55815470e94c 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -13,7 +13,7 @@ TARGETS += core TARGETS += cpufreq TARGETS += cpu-hotplug TARGETS += damon -TARGETS += devices +TARGETS += devices/probe TARGETS += dmabuf-heaps TARGETS += drivers/dma-buf TARGETS += drivers/s390x/uvdevice diff --git a/tools/testing/selftests/devices/Makefile b/tools/testing/selftests/devices/probe/Makefile similarity index 77% rename from tools/testing/selftests/devices/Makefile rename to tools/testing/selftests/devices/probe/Makefile index ca29249b30c3..7a6eaa031cfe 100644 --- a/tools/testing/selftests/devices/Makefile +++ b/tools/testing/selftests/devices/probe/Makefile @@ -1,4 +1,4 @@ TEST_PROGS := test_discoverable_devices.py TEST_FILES := boards ksft.py
-include ../lib.mk +include ../../lib.mk diff --git a/tools/testing/selftests/devices/boards/Dell Inc.,XPS 13 9300.yaml b/tools/testing/selftests/devices/probe/boards/Dell Inc.,XPS 13 9300.yaml similarity index 100% rename from tools/testing/selftests/devices/boards/Dell Inc.,XPS 13 9300.yaml rename to tools/testing/selftests/devices/probe/boards/Dell Inc.,XPS 13 9300.yaml diff --git a/tools/testing/selftests/devices/boards/google,spherion.yaml b/tools/testing/selftests/devices/probe/boards/google,spherion.yaml similarity index 100% rename from tools/testing/selftests/devices/boards/google,spherion.yaml rename to tools/testing/selftests/devices/probe/boards/google,spherion.yaml diff --git a/tools/testing/selftests/devices/ksft.py b/tools/testing/selftests/devices/probe/ksft.py similarity index 100% rename from tools/testing/selftests/devices/ksft.py rename to tools/testing/selftests/devices/probe/ksft.py diff --git a/tools/testing/selftests/devices/test_discoverable_devices.py b/tools/testing/selftests/devices/probe/test_discoverable_devices.py similarity index 100% rename from tools/testing/selftests/devices/test_discoverable_devices.py rename to tools/testing/selftests/devices/probe/test_discoverable_devices.py
Move the ksft python module, which provides generic helpers for kselftests, to a common directory so it can be more easily shared between different tests.
Signed-off-by: Nícolas F. R. A. Prado nfraprado@collabora.com --- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/devices/probe/Makefile | 2 +- tools/testing/selftests/devices/probe/test_discoverable_devices.py | 7 ++++++- tools/testing/selftests/{devices/probe => kselftest}/ksft.py | 0 4 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 55815470e94c..a07ef1f473b3 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -250,6 +250,7 @@ ifdef INSTALL_PATH install -m 744 kselftest/runner.sh $(INSTALL_PATH)/kselftest/ install -m 744 kselftest/prefix.pl $(INSTALL_PATH)/kselftest/ install -m 744 kselftest/ktap_helpers.sh $(INSTALL_PATH)/kselftest/ + install -m 744 kselftest/ksft.py $(INSTALL_PATH)/kselftest/ install -m 744 run_kselftest.sh $(INSTALL_PATH)/ rm -f $(TEST_LIST) @ret=1; \ diff --git a/tools/testing/selftests/devices/probe/Makefile b/tools/testing/selftests/devices/probe/Makefile index 7a6eaa031cfe..f630108c3fdf 100644 --- a/tools/testing/selftests/devices/probe/Makefile +++ b/tools/testing/selftests/devices/probe/Makefile @@ -1,4 +1,4 @@ TEST_PROGS := test_discoverable_devices.py -TEST_FILES := boards ksft.py +TEST_FILES := boards
include ../../lib.mk diff --git a/tools/testing/selftests/devices/probe/test_discoverable_devices.py b/tools/testing/selftests/devices/probe/test_discoverable_devices.py index fbae8deb593d..0a2f4902dbbf 100755 --- a/tools/testing/selftests/devices/probe/test_discoverable_devices.py +++ b/tools/testing/selftests/devices/probe/test_discoverable_devices.py @@ -15,12 +15,17 @@ #
import glob -import ksft import os import re import sys import yaml
+# Allow ksft module to be imported from different directory +this_dir = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(this_dir, "../../kselftest/")) + +import ksft + pci_controllers = [] usb_controllers = []
diff --git a/tools/testing/selftests/devices/probe/ksft.py b/tools/testing/selftests/kselftest/ksft.py similarity index 100% rename from tools/testing/selftests/devices/probe/ksft.py rename to tools/testing/selftests/kselftest/ksft.py
Log errors are the most widely used mechanism for reporting issues in the kernel. When an error is logged using the device helpers, eg dev_err(), it gets metadata attached that identifies the subsystem and device where the message is coming from. Introduce a new test that makes use of that metadata to report which devices logged errors (or more critical messages).
Signed-off-by: Nícolas F. R. A. Prado nfraprado@collabora.com --- tools/testing/selftests/Makefile | 1 + .../testing/selftests/devices/error_logs/Makefile | 3 + .../devices/error_logs/test_device_error_logs.py | 85 ++++++++++++++++++++++ 3 files changed, 89 insertions(+)
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index a07ef1f473b3..e74da5e6e499 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -13,6 +13,7 @@ TARGETS += core TARGETS += cpufreq TARGETS += cpu-hotplug TARGETS += damon +TARGETS += devices/error_logs TARGETS += devices/probe TARGETS += dmabuf-heaps TARGETS += drivers/dma-buf diff --git a/tools/testing/selftests/devices/error_logs/Makefile b/tools/testing/selftests/devices/error_logs/Makefile new file mode 100644 index 000000000000..d546c3fb0a7f --- /dev/null +++ b/tools/testing/selftests/devices/error_logs/Makefile @@ -0,0 +1,3 @@ +TEST_PROGS := test_device_error_logs.py + +include ../../lib.mk diff --git a/tools/testing/selftests/devices/error_logs/test_device_error_logs.py b/tools/testing/selftests/devices/error_logs/test_device_error_logs.py new file mode 100755 index 000000000000..3dd56c8ec92c --- /dev/null +++ b/tools/testing/selftests/devices/error_logs/test_device_error_logs.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2024 Collabora Ltd +# +# This test checks for the presence of error (or more critical) log messages +# coming from devices in the kernel log. +# +# One failed test case is reported for each device that has outputted error +# logs. Devices with no errors do not produce a passing test case to avoid +# polluting the results, therefore a successful run will list 0 tests run. +# + +import glob +import os +import re +import sys + +# Allow ksft module to be imported from different directory +this_dir = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(this_dir, "../../kselftest/")) + +import ksft + +kmsg = "/dev/kmsg" + +RE_log = re.compile( + r"(?P<prefix>[0-9]+),(?P<sequence>[0-9]+),(?P<timestamp>[0-9]+),(?P<flag>[^;]*)(,[^;]*)*;(?P<message>.*)" +) +RE_tag = re.compile(r" (?P<key>[^=]+)=(?P<value>.*)") + +PREFIX_ERROR = 3 + +logs = [] +error_log_per_device = {} + + +def parse_kmsg(): + current_log = {} + + with open(kmsg) as f: + os.set_blocking(f.fileno(), False) + + for line in f: + tag_line = RE_tag.match(line) + log_line = RE_log.match(line) + + if log_line: + if current_log: + logs.append(current_log) # Save last log + + current_log = { + "prefix": int(log_line.group("prefix")), + "sequence": int(log_line.group("sequence")), + "timestamp": int(log_line.group("timestamp")), + "flag": log_line.group("flag"), + "message": log_line.group("message"), + } + elif tag_line: + current_log[tag_line.group("key")] = tag_line.group("value") + + +def generate_per_device_error_log(): + for log in logs: + if log.get("DEVICE") and log["prefix"] <= PREFIX_ERROR: + if not error_log_per_device.get(log["DEVICE"]): + error_log_per_device[log["DEVICE"]] = [] + error_log_per_device[log["DEVICE"]].append(log) + + +parse_kmsg() + +generate_per_device_error_log() +num_tests = len(error_log_per_device) + +ksft.print_header() +ksft.set_plan(num_tests) + +for device in error_log_per_device: + for log in error_log_per_device[device]: + ksft.print_msg(log["message"]) + ksft.test_result_fail(device) +if num_tests == 0: + ksft.print_msg("No device error logs found") +ksft.finished()
linux-kselftest-mirror@lists.linaro.org