[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230606142031.071059989@linutronix.de>
Date: Tue, 6 Jun 2023 16:37:19 +0200 (CEST)
From: Thomas Gleixner <tglx@...utronix.de>
To: LKML <linux-kernel@...r.kernel.org>
Cc: Frederic Weisbecker <frederic@...nel.org>,
Anna-Maria Behnsen <anna-maria@...utronix.de>,
John Stultz <jstultz@...gle.com>,
Peter Zijlstra <peterz@...radead.org>,
Ingo Molnar <mingo@...nel.org>,
Stephen Boyd <sboyd@...nel.org>,
Eric Biederman <ebiederm@...ssion.com>,
Oleg Nesterov <oleg@...hat.com>
Subject: [patch 01/45] selftests/timers/posix_timers: Make signal distribution
test less fragile
The signal distribution test has a tendency to hang for a long time as the
signal delivery is not really evenly distributed.
Increasing the timer interval to 10ms makes this less likely. Add a timeout
to catch the case where it hangs and terminate the test gracefully.
While at it get rid of the pointless atomic operation on a the thread local
variable in the signal handler.
Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
---
tools/testing/selftests/timers/posix_timers.c | 42 ++++++++++++++++----------
1 file changed, 27 insertions(+), 15 deletions(-)
--- a/tools/testing/selftests/timers/posix_timers.c
+++ b/tools/testing/selftests/timers/posix_timers.c
@@ -188,18 +188,19 @@ static int check_timer_create(int which)
return 0;
}
-int remain;
-__thread int got_signal;
+static int remain;
+static __thread int got_signal;
static void *distribution_thread(void *arg)
{
- while (__atomic_load_n(&remain, __ATOMIC_RELAXED));
+ while (__atomic_load_n(&remain, __ATOMIC_RELAXED) && !done);
+
return NULL;
}
static void distribution_handler(int nr)
{
- if (!__atomic_exchange_n(&got_signal, 1, __ATOMIC_RELAXED))
+ if (++got_signal == 1)
__atomic_fetch_sub(&remain, 1, __ATOMIC_RELAXED);
}
@@ -209,20 +210,22 @@ static void distribution_handler(int nr)
*/
static int check_timer_distribution(void)
{
- int err, i;
- timer_t id;
const int nthreads = 10;
pthread_t threads[nthreads];
struct itimerspec val = {
.it_value.tv_sec = 0,
- .it_value.tv_nsec = 1000 * 1000,
+ .it_value.tv_nsec = 20 * 1000 * 1000,
.it_interval.tv_sec = 0,
- .it_interval.tv_nsec = 1000 * 1000,
+ .it_interval.tv_nsec = 20 * 1000 * 1000,
};
+ time_t start, now;
+ int err, i;
+ timer_t id;
printf("Check timer_create() per process signal distribution... ");
fflush(stdout);
+ done = 0;
remain = nthreads + 1; /* worker threads + this thread */
signal(SIGALRM, distribution_handler);
err = timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id);
@@ -244,7 +247,18 @@ static int check_timer_distribution(void
}
/* Wait for all threads to receive the signal. */
- while (__atomic_load_n(&remain, __ATOMIC_RELAXED));
+ now = start = time(NULL);
+ while (__atomic_load_n(&remain, __ATOMIC_RELAXED)) {
+ now = time(NULL);
+ if (now - start > 5)
+ break;
+ }
+ done = 1;
+
+ if (timer_delete(id)) {
+ perror("Can't delete timer\n");
+ return -1;
+ }
for (i = 0; i < nthreads; i++) {
if (pthread_join(threads[i], NULL)) {
@@ -253,12 +267,10 @@ static int check_timer_distribution(void
}
}
- if (timer_delete(id)) {
- perror("Can't delete timer\n");
- return -1;
- }
-
- printf("[OK]\n");
+ if (now - start <= 5)
+ printf("[OK]\n");
+ else
+ printf("%d [FAIL]\n", got_signal);
return 0;
}
Powered by blists - more mailing lists