From 3aaf3c067e9a36f6cef75138a54fe64b9da74324 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 22 Apr 2026 08:26:41 +0200 Subject: [PATCH] cpumf/pai.c: Install SIGINT/SIGTERM handler for graceful termination MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sending signal SIGINT/SIGTERM to a running pai process causes immediate termination of that running process. This usually interrupts a select() system call waiting for more input to read from the installed events and its mapped memory buffers. As there is no signal handler installed, a SIGINT or SIGTERM signal simply terminates the process, sometimes leaving incomplete recorded output file paicryto.XXX (where XXX is the CPU number). Install a signal handler to intercept signal SIGINT or SIGTERM and run one more data collection loop to read out pending data and close all recording output files properly. Signed-off-by: Thomas Richter Reviewed-by: Sumanth Korikkar Signed-off-by: Jan Höppner --- cpumf/pai.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cpumf/pai.c b/cpumf/pai.c index 932f06e5..b8da83e7 100644 --- a/cpumf/pai.c +++ b/cpumf/pai.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,8 @@ #define S390_EVT_PAI_CRYPTO 0x1000 #define S390_EVT_PAI_NNPA 0x1800 +/* SIGINT or SIGTERM signal received */ +static volatile unsigned int sigterm; /* Default values for select() timeout: 1 second */ static unsigned long read_interval = 1000; /* Size of mapped perf event ring buffer in 4KB pages. @@ -350,6 +353,10 @@ static int collect(unsigned long cnt) if (FD_ISSET(i, &r_fds)) readmap(i); } + } else if (errno == EINTR && sigterm) { + /* Interrupt by signal SIGINT/SIGTERM, one more iteration */ + cnt = 2; + rc = 0; } } while (rc != -1 && --cnt > 0); return rc; @@ -983,6 +990,12 @@ static void setprio(const char *prio) err(EXIT_FAILURE, "Could not set realtime priority"); } +static void sig_handler(int no) +{ + if (no == SIGINT || no == SIGTERM) + sigterm = 1; +} + int main(int argc, char **argv) { bool crypto_record = false, report = false; @@ -1070,6 +1083,10 @@ int main(int argc, char **argv) errx(EXIT_FAILURE, "Invalid argument for runtime"); } + if (signal(SIGTERM, sig_handler) == SIG_ERR || + signal(SIGINT, sig_handler) == SIG_ERR) + errx(EXIT_FAILURE, "Failed to set signal handler"); + ev_install(group); ev_enable();