posix-timers: Move sequence logic into struct k_itimer

The posix timer signal handling uses siginfo::si_sys_private for handling
the sequence counter check. That indirection is not longer required and the
sequence count value at signal queueing time can be stored in struct
k_itimer itself.

This removes the requirement of treating siginfo::si_sys_private special as
it's now always zero as the kernel does not touch it anymore.

Suggested-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
Link: https://lore.kernel.org/all/20241105064213.852619866@linutronix.de
This commit is contained in:
Thomas Gleixner 2024-11-05 09:14:48 +01:00
parent c2a4796a15
commit 647da5f709
4 changed files with 7 additions and 10 deletions

View File

@ -162,6 +162,7 @@ static inline void posix_cputimers_init_work(void) { }
* @it_overrun: The overrun counter for pending signals * @it_overrun: The overrun counter for pending signals
* @it_overrun_last: The overrun at the time of the last delivered signal * @it_overrun_last: The overrun at the time of the last delivered signal
* @it_signal_seq: Sequence count to control signal delivery * @it_signal_seq: Sequence count to control signal delivery
* @it_sigqueue_seq: The sequence count at the point where the signal was queued
* @it_sigev_notify: The notify word of sigevent struct for signal delivery * @it_sigev_notify: The notify word of sigevent struct for signal delivery
* @it_interval: The interval for periodic timers * @it_interval: The interval for periodic timers
* @it_signal: Pointer to the creators signal struct * @it_signal: Pointer to the creators signal struct
@ -184,6 +185,7 @@ struct k_itimer {
s64 it_overrun; s64 it_overrun;
s64 it_overrun_last; s64 it_overrun_last;
unsigned int it_signal_seq; unsigned int it_signal_seq;
unsigned int it_sigqueue_seq;
int it_sigev_notify; int it_sigev_notify;
enum pid_type it_pid_type; enum pid_type it_pid_type;
ktime_t it_interval; ktime_t it_interval;

View File

@ -46,7 +46,7 @@ union __sifields {
__kernel_timer_t _tid; /* timer id */ __kernel_timer_t _tid; /* timer id */
int _overrun; /* overrun count */ int _overrun; /* overrun count */
sigval_t _sigval; /* same as below */ sigval_t _sigval; /* same as below */
int _sys_private; /* not to be passed to user */ int _sys_private; /* Not used by the kernel. Historic leftover. Always 0. */
} _timer; } _timer;
/* POSIX.1b signals */ /* POSIX.1b signals */

View File

@ -1976,12 +1976,10 @@ int posixtimer_send_sigqueue(struct k_itimer *tmr)
return -1; return -1;
/* /*
* Update @q::info::si_sys_private for posix timer signals with * Update @tmr::sigqueue_seq for posix timer signals with sighand
* sighand locked to prevent a race against dequeue_signal() which * locked to prevent a race against dequeue_signal().
* decides based on si_sys_private whether to invoke
* posixtimer_rearm() or not.
*/ */
q->info.si_sys_private = tmr->it_signal_seq; tmr->it_sigqueue_seq = tmr->it_signal_seq;
ret = 1; /* the signal is ignored */ ret = 1; /* the signal is ignored */
if (!prepare_signal(sig, t, false)) { if (!prepare_signal(sig, t, false)) {

View File

@ -259,7 +259,7 @@ static bool __posixtimer_deliver_signal(struct kernel_siginfo *info, struct k_it
* since the signal was queued. In either case, don't rearm and * since the signal was queued. In either case, don't rearm and
* drop the signal. * drop the signal.
*/ */
if (timr->it_signal_seq != info->si_sys_private || WARN_ON_ONCE(!timr->it_signal)) if (timr->it_signal_seq != timr->it_sigqueue_seq || WARN_ON_ONCE(!timr->it_signal))
return false; return false;
if (!timr->it_interval || WARN_ON_ONCE(timr->it_status != POSIX_TIMER_REQUEUE_PENDING)) if (!timr->it_interval || WARN_ON_ONCE(timr->it_status != POSIX_TIMER_REQUEUE_PENDING))
@ -297,9 +297,6 @@ bool posixtimer_deliver_signal(struct kernel_siginfo *info, struct sigqueue *tim
posixtimer_putref(timr); posixtimer_putref(timr);
spin_lock(&current->sighand->siglock); spin_lock(&current->sighand->siglock);
/* Don't expose the si_sys_private value to userspace */
info->si_sys_private = 0;
return ret; return ret;
} }