* [PATCH stable 6.18 0/2] Kunit backports for older systems
@ 2026-07-30 19:03 Florian Fainelli
2026-07-30 19:03 ` [PATCH stable 6.18 1/2] kunit: tool: Terminate kernel under test on SIGINT Florian Fainelli
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Florian Fainelli @ 2026-07-30 19:03 UTC (permalink / raw)
To: stable
Cc: Florian Fainelli, Richard Weinberger, Anton Ivanov, Johannes Berg,
Brendan Higgins, David Gow, Rae Moar, Kees Cook, Jens Axboe,
Al Viro, Tiwei Bie, open list:USER-MODE LINUX (UML), open list,
open list:KERNEL UNIT TESTING FRAMEWORK (KUnit),
open list:KERNEL UNIT TESTING FRAMEWORK (KUnit),
bcm-kernel-feedback-list
This patch series addresses an issue we encountered on older Ubuntu
20.04.6 LTS servers whereby running Kunit would not return to a prompt
and it would not be possible to Ctrl-C the running session either.
David Gow (1):
kunit: tool: Terminate kernel under test on SIGINT
Shuvam Pandey (1):
kunit: tool: skip stty when stdin is not a tty
tools/testing/kunit/kunit_kernel.py | 38 ++++++++++++++++-------
tools/testing/kunit/kunit_tool_test.py | 42 ++++++++++++++++++++++++++
2 files changed, 69 insertions(+), 11 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH stable 6.18 1/2] kunit: tool: Terminate kernel under test on SIGINT
2026-07-30 19:03 [PATCH stable 6.18 0/2] Kunit backports for older systems Florian Fainelli
@ 2026-07-30 19:03 ` Florian Fainelli
2026-07-30 19:03 ` [PATCH stable 6.18 2/2] kunit: tool: skip stty when stdin is not a tty Florian Fainelli
2026-08-01 1:40 ` [PATCH stable 6.18 0/2] Kunit backports for older systems Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: Florian Fainelli @ 2026-07-30 19:03 UTC (permalink / raw)
To: stable
Cc: David Gow, Andy Shevchenko, Shuah Khan, Florian Fainelli, Cursor,
Richard Weinberger, Anton Ivanov, Johannes Berg, Brendan Higgins,
Rae Moar, Kees Cook, Jens Axboe, Al Viro, Tiwei Bie,
open list:USER-MODE LINUX (UML), open list,
open list:KERNEL UNIT TESTING FRAMEWORK (KUnit),
open list:KERNEL UNIT TESTING FRAMEWORK (KUnit),
bcm-kernel-feedback-list
From: David Gow <david@davidgow.net>
commit 8f260b02eeeffbf2263c2b82b6e3e32fd73cde2b upstream
kunit.py will attempt to catch SIGINT / ^C in order to ensure the TTY isn't
messed up, but never actually attempts to terminate the running kernel (be
it UML or QEMU). This can lead to a bit of frustration if the kernel has
crashed or hung.
Terminate the kernel process in the signal handler, if it's running. This
requires plumbing through the process handle in a few more places (and
having some checks to see if the kernel is still running in places where it
may have already been killed).
Reported-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Closes: https://lore.kernel.org/all/aaFmiAmg9S18EANA@smile.fi.intel.com/
Signed-off-by: David Gow <david@davidgow.net>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Tested-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
[florian: resolved conflict in signal_handler(): upstream references
_restore_terminal_if_tty() which is introduced by the following commit;
retained subprocess.call(['stty', 'sane']) until that helper is available]
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Change-Id: I4fc947a1e9268b8611151f7845edb4c832f05890
---
tools/testing/kunit/kunit_kernel.py | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py
index 2998e1bc088b..4f0bec8fb4e1 100644
--- a/tools/testing/kunit/kunit_kernel.py
+++ b/tools/testing/kunit/kunit_kernel.py
@@ -16,7 +16,7 @@ import shutil
import signal
import sys
import threading
-from typing import Iterator, List, Optional, Tuple
+from typing import Iterator, List, Optional, Tuple, Any
from types import FrameType
import kunit_config
@@ -265,6 +265,7 @@ class LinuxSourceTree:
if kconfig_add:
kconfig = kunit_config.parse_from_string('\n'.join(kconfig_add))
self._kconfig.merge_in_entries(kconfig)
+ self._process : Optional[subprocess.Popen[Any]] = None
def arch(self) -> str:
return self._arch
@@ -358,36 +359,45 @@ class LinuxSourceTree:
args.append('kunit.filter_action=' + filter_action)
args.append('kunit.enable=1')
- process = self._ops.start(args, build_dir)
- assert process.stdout is not None # tell mypy it's set
+ self._process = self._ops.start(args, build_dir)
+ assert self._process is not None # tell mypy it's set
+ assert self._process.stdout is not None # tell mypy it's set
# Enforce the timeout in a background thread.
def _wait_proc() -> None:
try:
- process.wait(timeout=timeout)
+ if self._process:
+ self._process.wait(timeout=timeout)
except Exception as e:
print(e)
- process.terminate()
- process.wait()
+ if self._process:
+ self._process.terminate()
+ self._process.wait()
waiter = threading.Thread(target=_wait_proc)
waiter.start()
output = open(get_outfile_path(build_dir), 'w')
try:
# Tee the output to the file and to our caller in real time.
- for line in process.stdout:
+ for line in self._process.stdout:
output.write(line)
yield line
# This runs even if our caller doesn't consume every line.
finally:
# Flush any leftover output to the file
- output.write(process.stdout.read())
+ if self._process:
+ if self._process.stdout:
+ output.write(self._process.stdout.read())
+ self._process.stdout.close()
+ self._process = None
output.close()
- process.stdout.close()
waiter.join()
subprocess.call(['stty', 'sane'])
def signal_handler(self, unused_sig: int, unused_frame: Optional[FrameType]) -> None:
logging.error('Build interruption occurred. Cleaning console.')
+ if self._process:
+ self._process.terminate()
+ self._process.wait()
subprocess.call(['stty', 'sane'])
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH stable 6.18 2/2] kunit: tool: skip stty when stdin is not a tty
2026-07-30 19:03 [PATCH stable 6.18 0/2] Kunit backports for older systems Florian Fainelli
2026-07-30 19:03 ` [PATCH stable 6.18 1/2] kunit: tool: Terminate kernel under test on SIGINT Florian Fainelli
@ 2026-07-30 19:03 ` Florian Fainelli
2026-08-01 1:40 ` [PATCH stable 6.18 0/2] Kunit backports for older systems Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: Florian Fainelli @ 2026-07-30 19:03 UTC (permalink / raw)
To: stable
Cc: Shuvam Pandey, David Gow, Shuah Khan, Florian Fainelli, Cursor,
Richard Weinberger, Anton Ivanov, Johannes Berg, Brendan Higgins,
Rae Moar, Kees Cook, Jens Axboe, Al Viro, Tiwei Bie,
open list:USER-MODE LINUX (UML), open list,
open list:KERNEL UNIT TESTING FRAMEWORK (KUnit),
open list:KERNEL UNIT TESTING FRAMEWORK (KUnit),
bcm-kernel-feedback-list
From: Shuvam Pandey <shuvampandey1@gmail.com>
commit e42c349f4cdfa43cb39a68c8f764f8cafc23a9a9 upstream
run_kernel() cleanup and signal_handler() invoke stty unconditionally.
When stdin is not a tty (for example in CI or unit tests), this writes
noise to stderr.
Call stty only when stdin is a tty.
Add regression tests for these paths:
- run_kernel() with non-tty stdin
- signal_handler() with non-tty stdin
- signal_handler() with tty stdin
Signed-off-by: Shuvam Pandey <shuvampandey1@gmail.com>
Reviewed-by: David Gow <david@davidgow.net>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
[florian: add missing 'import sys' required by sys.stdin.isatty(); the
module was already present in the mainline tree before this commit but
was absent from the 6.12 base of kunit_kernel.py]
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Change-Id: I6c5292f5db0f5ce95399ee3dc87c00116709391e
---
tools/testing/kunit/kunit_kernel.py | 10 ++++--
tools/testing/kunit/kunit_tool_test.py | 42 ++++++++++++++++++++++++++
2 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py
index 4f0bec8fb4e1..2869fcb199ff 100644
--- a/tools/testing/kunit/kunit_kernel.py
+++ b/tools/testing/kunit/kunit_kernel.py
@@ -346,6 +346,12 @@ class LinuxSourceTree:
return False
return self.validate_config(build_dir)
+ def _restore_terminal_if_tty(self) -> None:
+ # stty requires a controlling terminal; skip headless runs.
+ if sys.stdin is None or not sys.stdin.isatty():
+ return
+ subprocess.call(['stty', 'sane'])
+
def run_kernel(self, args: Optional[List[str]]=None, build_dir: str='', filter_glob: str='', filter: str='', filter_action: Optional[str]=None, timeout: Optional[int]=None) -> Iterator[str]:
# Copy to avoid mutating the caller-supplied list. exec_tests() reuses
# the same args across repeated run_kernel() calls (e.g. --run_isolated),
@@ -393,11 +399,11 @@ class LinuxSourceTree:
output.close()
waiter.join()
- subprocess.call(['stty', 'sane'])
+ self._restore_terminal_if_tty()
def signal_handler(self, unused_sig: int, unused_frame: Optional[FrameType]) -> None:
logging.error('Build interruption occurred. Cleaning console.')
if self._process:
self._process.terminate()
self._process.wait()
- subprocess.call(['stty', 'sane'])
+ self._restore_terminal_if_tty()
diff --git a/tools/testing/kunit/kunit_tool_test.py b/tools/testing/kunit/kunit_tool_test.py
index ed45bac1548d..0eb61de9abd4 100755
--- a/tools/testing/kunit/kunit_tool_test.py
+++ b/tools/testing/kunit/kunit_tool_test.py
@@ -515,6 +515,48 @@ class LinuxSourceTreeTest(unittest.TestCase):
self.assertIn('kunit.filter_glob=suite.test1', start_calls[0])
self.assertIn('kunit.filter_glob=suite.test2', start_calls[1])
+ def test_run_kernel_skips_terminal_reset_without_tty(self):
+ def fake_start(unused_args, unused_build_dir):
+ return subprocess.Popen(['printf', 'KTAP version 1\n'],
+ text=True, stdout=subprocess.PIPE)
+
+ non_tty_stdin = mock.Mock()
+ non_tty_stdin.isatty.return_value = False
+
+ with tempfile.TemporaryDirectory('') as build_dir:
+ tree = kunit_kernel.LinuxSourceTree(build_dir, kunitconfig_paths=[os.devnull])
+ with mock.patch.object(tree._ops, 'start', side_effect=fake_start), \
+ mock.patch.object(kunit_kernel.sys, 'stdin', non_tty_stdin), \
+ mock.patch.object(kunit_kernel.subprocess, 'call') as mock_call:
+ for _ in tree.run_kernel(build_dir=build_dir):
+ pass
+
+ mock_call.assert_not_called()
+
+ def test_signal_handler_skips_terminal_reset_without_tty(self):
+ non_tty_stdin = mock.Mock()
+ non_tty_stdin.isatty.return_value = False
+ tree = kunit_kernel.LinuxSourceTree('', kunitconfig_paths=[os.devnull])
+
+ with mock.patch.object(kunit_kernel.sys, 'stdin', non_tty_stdin), \
+ mock.patch.object(kunit_kernel.subprocess, 'call') as mock_call, \
+ mock.patch.object(kunit_kernel.logging, 'error') as mock_error:
+ tree.signal_handler(signal.SIGINT, None)
+ mock_error.assert_called_once()
+ mock_call.assert_not_called()
+
+ def test_signal_handler_resets_terminal_with_tty(self):
+ tty_stdin = mock.Mock()
+ tty_stdin.isatty.return_value = True
+ tree = kunit_kernel.LinuxSourceTree('', kunitconfig_paths=[os.devnull])
+
+ with mock.patch.object(kunit_kernel.sys, 'stdin', tty_stdin), \
+ mock.patch.object(kunit_kernel.subprocess, 'call') as mock_call, \
+ mock.patch.object(kunit_kernel.logging, 'error') as mock_error:
+ tree.signal_handler(signal.SIGINT, None)
+ mock_error.assert_called_once()
+ mock_call.assert_called_once_with(['stty', 'sane'])
+
def test_build_reconfig_no_config(self):
with tempfile.TemporaryDirectory('') as build_dir:
with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH stable 6.18 0/2] Kunit backports for older systems
2026-07-30 19:03 [PATCH stable 6.18 0/2] Kunit backports for older systems Florian Fainelli
2026-07-30 19:03 ` [PATCH stable 6.18 1/2] kunit: tool: Terminate kernel under test on SIGINT Florian Fainelli
2026-07-30 19:03 ` [PATCH stable 6.18 2/2] kunit: tool: skip stty when stdin is not a tty Florian Fainelli
@ 2026-08-01 1:40 ` Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-08-01 1:40 UTC (permalink / raw)
To: stable
Cc: Sasha Levin, Florian Fainelli, Richard Weinberger, Anton Ivanov,
Johannes Berg, Brendan Higgins, David Gow, Rae Moar, Kees Cook,
Jens Axboe, Al Viro, Tiwei Bie, linux-um, linux-kernel,
linux-kselftest, kunit-dev, bcm-kernel-feedback-list
On Thu, Jul 30, 2026 at 12:03:27PM -0700, Florian Fainelli wrote:
> David Gow (1):
> kunit: tool: Terminate kernel under test on SIGINT
>
> Shuvam Pandey (1):
> kunit: tool: skip stty when stdin is not a tty
Both of these are already queued for 6.18 as plain cherry-picks, so
there's nothing to do here - no need to respin. Thanks!
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-01 1:40 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30 19:03 [PATCH stable 6.18 0/2] Kunit backports for older systems Florian Fainelli
2026-07-30 19:03 ` [PATCH stable 6.18 1/2] kunit: tool: Terminate kernel under test on SIGINT Florian Fainelli
2026-07-30 19:03 ` [PATCH stable 6.18 2/2] kunit: tool: skip stty when stdin is not a tty Florian Fainelli
2026-08-01 1:40 ` [PATCH stable 6.18 0/2] Kunit backports for older systems Sasha Levin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.