From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Anna-Maria Behnsen <anna-maria@linutronix.de>,
Frederic Weisbecker <frederic@kernel.org>,
John Stultz <jstultz@google.com>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@kernel.org>, Stephen Boyd <sboyd@kernel.org>,
Eric Biederman <ebiederm@xmission.com>,
Oleg Nesterov <oleg@redhat.com>
Subject: [patch V3 32/51] posix-timers: Add proper state tracking
Date: Mon, 10 Jun 2024 18:42:44 +0200 (CEST) [thread overview]
Message-ID: <20240610164027.485595881@linutronix.de> (raw)
In-Reply-To: 20240610163452.591699700@linutronix.de
Right now the state tracking is done by two struct members:
- it_active:
A boolean which tracks armed/disarmed state
- it_signal_seq:
A sequence counter which is used to invalidate settings
and prevent rearming
Replace it_active with it_status and keep properly track about the states
in one place.
This allows to reuse it_signal_seq to track reprogramming, disarm and
delete operations in order to drop signals which are related to the state
previous of those operations.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
include/linux/posix-timers.h | 4 ++--
kernel/time/alarmtimer.c | 2 +-
kernel/time/posix-cpu-timers.c | 15 ++++++++-------
kernel/time/posix-timers.c | 22 +++++++++++++---------
kernel/time/posix-timers.h | 6 ++++++
5 files changed, 30 insertions(+), 19 deletions(-)
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -147,7 +147,7 @@ static inline void posix_cputimers_init_
* @kclock: Pointer to the k_clock struct handling this timer
* @it_clock: The posix timer clock id
* @it_id: The posix timer id for identifying the timer
- * @it_active: Marker that timer is active
+ * @it_status: The status of the timer
* @it_overrun: The overrun counter for pending signals
* @it_overrun_last: The overrun at the time of the last delivered signal
* @it_signal_seq: Sequence count to control signal delivery
@@ -168,7 +168,7 @@ struct k_itimer {
const struct k_clock *kclock;
clockid_t it_clock;
timer_t it_id;
- int it_active;
+ int it_status;
s64 it_overrun;
s64 it_overrun_last;
unsigned int it_signal_seq;
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -585,7 +585,7 @@ static enum alarmtimer_restart alarm_han
*/
ptr->it_overrun += __alarm_forward_now(alarm, ptr->it_interval, true);
++ptr->it_signal_seq;
- ptr->it_active = 1;
+ ptr->it_status = POSIX_TIMER_ARMED;
result = ALARMTIMER_RESTART;
}
spin_unlock_irqrestore(&ptr->it_lock, flags);
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -453,7 +453,6 @@ static void disarm_timer(struct k_itimer
struct cpu_timer *ctmr = &timer->it.cpu;
struct posix_cputimer_base *base;
- timer->it_active = 0;
if (!cpu_timer_dequeue(ctmr))
return;
@@ -494,11 +493,12 @@ static int posix_cpu_timer_del(struct k_
*/
WARN_ON_ONCE(ctmr->head || timerqueue_node_queued(&ctmr->node));
} else {
- if (timer->it.cpu.firing)
+ if (timer->it.cpu.firing) {
ret = TIMER_RETRY;
- else
+ } else {
disarm_timer(timer, p);
-
+ timer->it_status = POSIX_TIMER_DISARMED;
+ }
unlock_task_sighand(p, &flags);
}
@@ -560,7 +560,7 @@ static void arm_timer(struct k_itimer *t
struct cpu_timer *ctmr = &timer->it.cpu;
u64 newexp = cpu_timer_getexpires(ctmr);
- timer->it_active = 1;
+ timer->it_status = POSIX_TIMER_ARMED;
if (!cpu_timer_enqueue(&base->tqhead, ctmr))
return;
@@ -586,7 +586,8 @@ static void cpu_timer_fire(struct k_itim
{
struct cpu_timer *ctmr = &timer->it.cpu;
- timer->it_active = 0;
+ timer->it_status = POSIX_TIMER_DISARMED;
+
if (unlikely(timer->sigq == NULL)) {
/*
* This a special case for clock_nanosleep,
@@ -671,7 +672,7 @@ static int posix_cpu_timer_set(struct k_
ret = TIMER_RETRY;
} else {
cpu_timer_dequeue(ctmr);
- timer->it_active = 0;
+ timer->it_status = POSIX_TIMER_DISARMED;
}
/*
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -272,7 +272,7 @@ bool posixtimer_deliver_signal(struct ke
if (timr->it_interval && timr->it_signal_seq == info->si_sys_private) {
timr->kclock->timer_rearm(timr);
- timr->it_active = 1;
+ timr->it_status = POSIX_TIMER_ARMED;
timr->it_overrun_last = timr->it_overrun;
timr->it_overrun = -1LL;
++timr->it_signal_seq;
@@ -292,14 +292,17 @@ bool posixtimer_deliver_signal(struct ke
int posix_timer_queue_signal(struct k_itimer *timr)
{
+ enum posix_timer_state state = POSIX_TIMER_DISARMED;
int ret, si_private = 0;
enum pid_type type;
lockdep_assert_held(&timr->it_lock);
- timr->it_active = 0;
- if (timr->it_interval)
+ if (timr->it_interval) {
+ state = POSIX_TIMER_REQUEUE_PENDING;
si_private = ++timr->it_signal_seq;
+ }
+ timr->it_status = state;
type = !(timr->it_sigev_notify & SIGEV_THREAD_ID) ? PIDTYPE_TGID : PIDTYPE_PID;
ret = send_sigqueue(timr->sigq, timr->it_pid, type, si_private);
@@ -367,7 +370,7 @@ static enum hrtimer_restart posix_timer_
timr->it_overrun += hrtimer_forward(timer, now, timr->it_interval);
ret = HRTIMER_RESTART;
++timr->it_signal_seq;
- timr->it_active = 1;
+ timr->it_status = POSIX_TIMER_ARMED;
}
}
@@ -647,10 +650,10 @@ void common_timer_get(struct k_itimer *t
/* interval timer ? */
if (iv) {
cur_setting->it_interval = ktime_to_timespec64(iv);
- } else if (!timr->it_active) {
+ } else if (timr->it_status == POSIX_TIMER_DISARMED) {
/*
* SIGEV_NONE oneshot timers are never queued and therefore
- * timr->it_active is always false. The check below
+ * timr->it_status is always DISARMED. The check below
* vs. remaining time will handle this case.
*
* For all other timers there is nothing to update here, so
@@ -895,7 +898,7 @@ int common_timer_set(struct k_itimer *ti
if (kc->timer_try_to_cancel(timr) < 0)
return TIMER_RETRY;
- timr->it_active = 0;
+ timr->it_status = POSIX_TIMER_DISARMED;
posix_timer_set_common(timr, new_setting);
/* Keep timer disarmed when it_value is zero */
@@ -908,7 +911,8 @@ int common_timer_set(struct k_itimer *ti
sigev_none = timr->it_sigev_notify == SIGEV_NONE;
kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none);
- timr->it_active = !sigev_none;
+ if (!sigev_none)
+ timr->it_status = POSIX_TIMER_ARMED;
return 0;
}
@@ -1007,7 +1011,7 @@ int common_timer_del(struct k_itimer *ti
timer->it_interval = 0;
if (kc->timer_try_to_cancel(timer) < 0)
return TIMER_RETRY;
- timer->it_active = 0;
+ timer->it_status = POSIX_TIMER_DISARMED;
return 0;
}
--- a/kernel/time/posix-timers.h
+++ b/kernel/time/posix-timers.h
@@ -1,6 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 */
#define TIMER_RETRY 1
+enum posix_timer_state {
+ POSIX_TIMER_DISARMED,
+ POSIX_TIMER_ARMED,
+ POSIX_TIMER_REQUEUE_PENDING,
+};
+
struct k_clock {
int (*clock_getres)(const clockid_t which_clock,
struct timespec64 *tp);
next prev parent reply other threads:[~2024-06-10 16:42 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-10 16:42 [patch V3 00/51] posix-timers: Cure inconsistencies and the SIG_IGN mess Thomas Gleixner
2024-06-10 16:42 ` [patch V3 01/51] selftests/timers/posix_timers: Simplify error handling Thomas Gleixner
2024-06-10 16:42 ` [patch V3 02/51] selftests/timers/posix_timers: Add SIG_IGN test Thomas Gleixner
2024-06-10 16:42 ` [patch V3 03/51] selftests/timers/posix_timers: Validate signal rules Thomas Gleixner
2024-06-10 16:42 ` [patch V3 04/51] selftests/timers/posix-timers: Validate SIGEV_NONE Thomas Gleixner
2024-06-10 16:42 ` [patch V3 05/51] selftests/timers/posix-timers: Validate timer_gettime() Thomas Gleixner
2024-06-10 16:42 ` [patch V3 06/51] selftests/timers/posix-timers: Validate overrun after unblock Thomas Gleixner
2024-06-10 16:42 ` [patch V3 07/51] posix-cpu-timers: Split up posix_cpu_timer_get() Thomas Gleixner
2024-06-21 15:28 ` Frederic Weisbecker
2024-06-10 16:42 ` [patch V3 08/51] posix-cpu-timers: Save interval only for armed timers Thomas Gleixner
2024-06-21 15:33 ` Frederic Weisbecker
2024-06-10 16:42 ` [patch V3 09/51] posix-cpu-timers: Handle interval timers correctly in timer_get() Thomas Gleixner
2024-06-22 9:04 ` Frederic Weisbecker
2024-06-10 16:42 ` [patch V3 10/51] posix-cpu-timers: Handle SIGEV_NONE " Thomas Gleixner
2024-06-22 14:28 ` Frederic Weisbecker
2024-06-10 16:42 ` [patch V3 11/51] posix-cpu-timers: Handle SIGEV_NONE timers correctly in timer_set() Thomas Gleixner
2024-06-22 14:35 ` Frederic Weisbecker
2024-06-22 21:56 ` Thomas Gleixner
2024-06-23 11:16 ` [patch V3-2 " Thomas Gleixner
2024-06-23 19:12 ` Frederic Weisbecker
2024-06-10 16:42 ` [patch V3 12/51] posix-cpu-timers: Replace old expiry retrieval in posix_cpu_timer_set() Thomas Gleixner
2024-06-23 11:17 ` [patch V3-2 " Thomas Gleixner
2024-06-23 20:23 ` Frederic Weisbecker
2024-06-10 16:42 ` [patch V3 13/51] posix-cpu-timers: Do not arm SIGEV_NONE timers Thomas Gleixner
2024-06-23 21:04 ` Frederic Weisbecker
2024-06-10 16:42 ` [patch V3 14/51] posix-cpu-timers: Use @now instead of @val for clarity Thomas Gleixner
2024-06-10 16:42 ` [patch V3 15/51] posix-cpu-timers: Remove incorrect comment in posix_cpu_timer_set() Thomas Gleixner
2024-06-10 16:42 ` [patch V3 16/51] posix-cpu-timers: Simplify posix_cpu_timer_set() Thomas Gleixner
2024-06-23 22:41 ` Frederic Weisbecker
2024-06-10 16:42 ` [patch V3 17/51] posix-timers: Retrieve interval in common timer_settime() code Thomas Gleixner
2024-06-25 15:13 ` Frederic Weisbecker
2024-06-10 16:42 ` [patch V3 18/51] posix-timers: Clear overrun in common_timer_set() Thomas Gleixner
2024-06-10 16:42 ` [patch V3 19/51] posix-timers: Convert timer list to hlist Thomas Gleixner
2024-06-10 16:42 ` [patch V3 20/51] posix-timers: Consolidate timer setup Thomas Gleixner
2024-06-25 22:19 ` Frederic Weisbecker
2024-06-10 16:42 ` [patch V3 21/51] posix-cpu-timers: Make k_itimer::it_active consistent Thomas Gleixner
2024-06-25 22:36 ` Frederic Weisbecker
2024-06-10 16:42 ` [patch V3 22/51] posix-timers: Consolidate signal queueing Thomas Gleixner
2024-06-10 16:42 ` [patch V3 23/51] signal: Remove task argument from dequeue_signal() Thomas Gleixner
2024-06-10 16:42 ` [patch V3 24/51] signal: Replace BUG_ON()s Thomas Gleixner
2024-06-10 16:42 ` [patch V3 25/51] signal: Confine POSIX_TIMERS properly Thomas Gleixner
2024-06-10 16:42 ` [patch V3 26/51] signal: Prevent user space from setting si_sys_private Thomas Gleixner
2024-06-10 16:42 ` [patch V3 27/51] signal: Get rid of resched_timer logic Thomas Gleixner
2024-06-10 16:42 ` [patch V3 28/51] posix-timers: Cure si_sys_private race Thomas Gleixner
2024-06-10 16:42 ` [patch V3 29/51] signal: Allow POSIX timer signals to be dropped Thomas Gleixner
2024-06-10 16:42 ` [patch V3 30/51] posix-timers: Drop signal if timer has been deleted or reprogrammed Thomas Gleixner
2024-06-10 16:42 ` [patch V3 31/51] posix-timers: Rename k_itimer::it_requeue_pending Thomas Gleixner
2024-06-10 16:42 ` Thomas Gleixner [this message]
2024-06-10 16:42 ` [patch V3 33/51] posix-timers: Make signal delivery consistent Thomas Gleixner
2024-06-10 16:42 ` [patch V3 34/51] posix-timers: Make signal overrun accounting sensible Thomas Gleixner
2024-06-10 16:42 ` [patch V3 35/51] posix-cpu-timers: Use dedicated flag for CPU timer nanosleep Thomas Gleixner
2024-06-10 16:42 ` [patch V3 36/51] posix-timers: Add a refcount to struct k_itimer Thomas Gleixner
2024-06-10 16:42 ` [patch V3 37/51] signal: Split up __sigqueue_alloc() Thomas Gleixner
2024-06-10 16:42 ` [patch V3 38/51] signal: Provide posixtimer_sigqueue_init() Thomas Gleixner
2024-06-10 16:42 ` [patch V3 39/51] signal: Add sys_private_ptr to siginfo::_sifields::_timer Thomas Gleixner
2024-06-23 11:17 ` Thomas Gleixner
2024-06-10 16:42 ` [patch V3 40/51] posix-timers: Store PID type in the timer Thomas Gleixner
2024-06-10 16:42 ` [patch V3 41/51] signal: Refactor send_sigqueue() Thomas Gleixner
2024-06-10 16:42 ` [patch V3 42/51] posix-timers: Embed sigqueue in struct k_itimer Thomas Gleixner
2024-06-10 16:42 ` [patch V3 43/51] signal: Cleanup unused posix-timer leftovers Thomas Gleixner
2024-06-10 16:42 ` [patch V3 44/51] signal: Add task argument to flush_sigqueue_mask() Thomas Gleixner
2024-06-10 16:43 ` [patch V3 45/51] signal: Provide ignored_posix_timers list Thomas Gleixner
2024-06-10 16:43 ` [patch V3 46/51] posix-timers: Handle ignored list on delete and exit Thomas Gleixner
2024-06-10 16:43 ` [patch V3 47/51] signal: Handle ignored signals in do_sigaction(action != SIG_IGN) Thomas Gleixner
2024-06-10 16:43 ` [patch V3 48/51] signal: Queue ignored posixtimers on ignore list Thomas Gleixner
2024-06-10 16:43 ` [patch V3 49/51] posix-timers: Cleanup SIG_IGN workaround leftovers Thomas Gleixner
2024-06-10 16:43 ` [patch V3 50/51] alarmtimers: Remove the throttle mechanism from alarm_forward_now() Thomas Gleixner
2024-06-10 16:43 ` [patch V3 51/51] alarmtimers: Remove return value from alarm functions Thomas Gleixner
2024-06-10 19:49 ` [patch V3 00/51] posix-timers: Cure inconsistencies and the SIG_IGN mess Peter Zijlstra
2024-06-11 6:58 ` Thomas Gleixner
2024-06-23 11:24 ` Thomas Gleixner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240610164027.485595881@linutronix.de \
--to=tglx@linutronix.de \
--cc=anna-maria@linutronix.de \
--cc=ebiederm@xmission.com \
--cc=frederic@kernel.org \
--cc=jstultz@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=oleg@redhat.com \
--cc=peterz@infradead.org \
--cc=sboyd@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox