lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20250823155452.198536-1-preetpal.singh@s.amity.edu>
Date: Sat, 23 Aug 2025 21:24:52 +0530
From: Preetpalbugs <preetpal77952@...il.com>
To: skhan@...uxfoundation.org
Cc: linux-kselftest@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Preetpalbugs <preetpal.singh@...mity.edu>
Subject: [PATCH] selftests: timers: Fix wording and grammar in messages

Signed-off-by: Preetpalbugs <preetpal.singh@...mity.edu>
---
 posix_timers.c | 290 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 290 insertions(+)
 create mode 100644 posix_timers.c

diff --git a/posix_timers.c b/posix_timers.c
new file mode 100644
index 0000000..486b71b
--- /dev/null
+++ b/posix_timers.c
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat, Inc., Frederic Weisbecker <fweisbec@...hat.com>
+ *
+ * Selftests for a few posix timers interface.
+ *
+ * Kernel loop code stolen from Steven Rostedt <srostedt@...hat.com>
+ */
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <time.h>
+#include <pthread.h>
+
+#include "../kselftest.h"
+
+#define DELAY 2
+#define USECS_PER_SEC 1000000
+
+static volatile int done;
+
+/* Busy loop in userspace to elapse ITIMER_VIRTUAL */
+static void user_loop(void)
+{
+	while (!done);
+}
+
+/*
+ * Try to spend as much time as possible in kernelspace
+ * to elapse ITIMER_PROF.
+ */
+static void kernel_loop(void)
+{
+	void *addr = sbrk(0);
+	int err = 0;
+
+	while (!done && !err) {
+		err = brk(addr + 4096);
+		err |= brk(addr);
+	}
+}
+
+/*
+ * Sleep until ITIMER_REAL expiration.
+ */
+static void idle_loop(void)
+{
+	pause();
+}
+
+static void sig_handler(int nr)
+{
+	done = 1;
+}
+
+/*
+ * Check the expected timer expiration matches the GTOD elapsed delta since
+ * we armed the timer. Keep a 0.5 sec error margin due to various jitter.
+ */
+static int check_diff(struct timeval start, struct timeval end)
+{
+	long long diff;
+
+	diff = end.tv_usec - start.tv_usec;
+	diff += (end.tv_sec - start.tv_sec) * USECS_PER_SEC;
+
+	if (llabs(diff - DELAY * USECS_PER_SEC) > USECS_PER_SEC / 2) {
+		printf("Diff too high: %lld..", diff);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int check_itimer(int which)
+{
+	const char *name;
+	int err;
+	struct timeval start, end;
+	struct itimerval val = {
+		.it_value.tv_sec = DELAY,
+	};
+
+	if (which == ITIMER_VIRTUAL)
+		name = "ITIMER_VIRTUAL";
+	else if (which == ITIMER_PROF)
+		name = "ITIMER_PROF";
+	else if (which == ITIMER_REAL)
+		name = "ITIMER_REAL";
+	else
+		return -1;
+
+	done = 0;
+
+	if (which == ITIMER_VIRTUAL)
+		signal(SIGVTALRM, sig_handler);
+	else if (which == ITIMER_PROF)
+		signal(SIGPROF, sig_handler);
+	else if (which == ITIMER_REAL)
+		signal(SIGALRM, sig_handler);
+
+	err = gettimeofday(&start, NULL);
+	if (err < 0) {
+		ksft_perror("Can't call gettimeofday()");
+		return -1;
+	}
+
+	err = setitimer(which, &val, NULL);
+	if (err < 0) {
+		ksft_perror("Can't set timer");
+		return -1;
+	}
+
+	if (which == ITIMER_VIRTUAL)
+		user_loop();
+	else if (which == ITIMER_PROF)
+		kernel_loop();
+	else if (which == ITIMER_REAL)
+		idle_loop();
+
+	err = gettimeofday(&end, NULL);
+	if (err < 0) {
+		ksft_perror("Can't call gettimeofday()");
+		return -1;
+	}
+
+	ksft_test_result(check_diff(start, end) == 0, "%s\n", name);
+
+	return 0;
+}
+
+static int check_timer_create(int which)
+{
+	const char *type;
+	int err;
+	timer_t id;
+	struct timeval start, end;
+	struct itimerspec val = {
+		.it_value.tv_sec = DELAY,
+	};
+
+	if (which == CLOCK_THREAD_CPUTIME_ID) {
+		type = "thread";
+	} else if (which == CLOCK_PROCESS_CPUTIME_ID) {
+		type = "process";
+	} else {
+		ksft_print_msg("Unknown timer_create() type %d\n", which);
+		return -1;
+	}
+
+	done = 0;
+	err = timer_create(which, NULL, &id);
+	if (err < 0) {
+		ksft_perror("Can't create timer");
+		return -1;
+	}
+	signal(SIGALRM, sig_handler);
+
+	err = gettimeofday(&start, NULL);
+	if (err < 0) {
+		ksft_perror("Can't call gettimeofday()");
+		return -1;
+	}
+
+	err = timer_settime(id, 0, &val, NULL);
+	if (err < 0) {
+		ksft_perror("Can't set timer");
+		return -1;
+	}
+
+	user_loop();
+
+	err = gettimeofday(&end, NULL);
+	if (err < 0) {
+		ksft_perror("Can't call gettimeofday()");
+		return -1;
+	}
+
+	ksft_test_result(check_diff(start, end) == 0,
+			 "timer_create() per %s\n", type);
+
+	return 0;
+}
+
+static pthread_t ctd_thread;
+static volatile int ctd_count, ctd_failed;
+
+static void ctd_sighandler(int sig)
+{
+	if (pthread_self() != ctd_thread)
+		ctd_failed = 1;
+	ctd_count--;
+}
+
+static void *ctd_thread_func(void *arg)
+{
+	struct itimerspec val = {
+		.it_value.tv_sec = 0,
+		.it_value.tv_nsec = 1000 * 1000,
+		.it_interval.tv_sec = 0,
+		.it_interval.tv_nsec = 1000 * 1000,
+	};
+	timer_t id;
+
+	/* 1/10 seconds to ensure the leader sleeps */
+	usleep(10000);
+
+	ctd_count = 100;
+	if (timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id))
+		return "Can't create timer\n";
+	if (timer_settime(id, 0, &val, NULL))
+		return "Can't set timer\n";
+
+	while (ctd_count > 0 && !ctd_failed)
+		;
+
+	if (timer_delete(id))
+		return "Can't delete timer\n";
+
+	return NULL;
+}
+
+/*
+ * Test that only the running thread receives the timer signal.
+ */
+static int check_timer_distribution(void)
+{
+	const char *errmsg;
+
+	signal(SIGALRM, ctd_sighandler);
+
+	errmsg = "Can't create thread\n";
+	if (pthread_create(&ctd_thread, NULL, ctd_thread_func, NULL))
+		goto err;
+
+	errmsg = "Cannot join thread\n";
+	if (pthread_join(ctd_thread, (void **)&errmsg) || errmsg)
+		goto err;
+
+	if (!ctd_failed)
+		ksft_test_result_pass("check signal distribution\n");
+	else if (ksft_min_kernel_version(6, 3))
+		ksft_test_result_fail("check signal distribution\n");
+	else
+		ksft_test_result_skip("check signal distribution (old kernel)\n");
+	return 0;
+err:
+	ksft_print_msg("%s", errmsg);
+	return -1;
+}
+
+int main(int argc, char **argv)
+{
+	ksft_print_header();
+	ksft_set_plan(6);
+
+	ksft_print_msg("Testing POSIX timers. False negative may happen on CPU execution \n");
+	ksft_print_msg("This may happen on CPU-based timers if other threads run on the CPU...\n");
+
+	if (check_itimer(ITIMER_VIRTUAL) < 0)
+		ksft_exit_fail();
+
+	if (check_itimer(ITIMER_PROF) < 0)
+		ksft_exit_fail();
+
+	if (check_itimer(ITIMER_REAL) < 0)
+		ksft_exit_fail();
+
+	if (check_timer_create(CLOCK_THREAD_CPUTIME_ID) < 0)
+		ksft_exit_fail();
+
+	/*
+	 * It's unfortunately hard to reliably test a timer expiration
+	 * on parallel multithread cputime. We could arm it to expire
+	 * on DELAY * nr_threads, with nr_threads busy looping, then wait
+	 * the normal DELAY since the time is elapsing nr_threads faster.
+	 * But for that we need to ensure we have real physical free CPUs
+	 * to ensure true parallelism. So test only one thread until we
+	 * find a better solution.
+	 */
+	if (check_timer_create(CLOCK_PROCESS_CPUTIME_ID) < 0)
+		ksft_exit_fail();
+
+	if (check_timer_distribution() < 0)
+		ksft_exit_fail();
+
+	ksft_finished();
+}
-- 
2.50.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ