mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-17 03:39:07 +08:00
signal: Replace resched_timer logic
In preparation for handling ignored posix timer signals correctly and embedding the sigqueue struct into struct k_itimer, hand down a pointer to the sigqueue struct into posix_timer_deliver_signal() instead of just having a boolean flag. No functional change. 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.652658158@linutronix.de
This commit is contained in:
@@ -110,7 +110,7 @@ static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct,
|
||||
void posixtimer_rearm_itimer(struct task_struct *p);
|
||||
bool posixtimer_init_sigqueue(struct sigqueue *q);
|
||||
int posixtimer_send_sigqueue(struct k_itimer *tmr);
|
||||
bool posixtimer_deliver_signal(struct kernel_siginfo *info);
|
||||
bool posixtimer_deliver_signal(struct kernel_siginfo *info, struct sigqueue *timer_sigq);
|
||||
void posixtimer_free_timer(struct k_itimer *timer);
|
||||
|
||||
/* Init task static initializer */
|
||||
@@ -135,7 +135,8 @@ static inline void posix_cputimers_init(struct posix_cputimers *pct) { }
|
||||
static inline void posix_cputimers_group_init(struct posix_cputimers *pct,
|
||||
u64 cpu_limit) { }
|
||||
static inline void posixtimer_rearm_itimer(struct task_struct *p) { }
|
||||
static inline bool posixtimer_deliver_signal(struct kernel_siginfo *info) { return false; }
|
||||
static inline bool posixtimer_deliver_signal(struct kernel_siginfo *info,
|
||||
struct sigqueue *timer_sigq) { return false; }
|
||||
static inline void posixtimer_free_timer(struct k_itimer *timer) { }
|
||||
#endif
|
||||
|
||||
|
||||
@@ -545,7 +545,7 @@ bool unhandled_signal(struct task_struct *tsk, int sig)
|
||||
}
|
||||
|
||||
static void collect_signal(int sig, struct sigpending *list, kernel_siginfo_t *info,
|
||||
bool *resched_timer)
|
||||
struct sigqueue **timer_sigq)
|
||||
{
|
||||
struct sigqueue *q, *first = NULL;
|
||||
|
||||
@@ -568,10 +568,17 @@ still_pending:
|
||||
list_del_init(&first->list);
|
||||
copy_siginfo(info, &first->info);
|
||||
|
||||
*resched_timer = (first->flags & SIGQUEUE_PREALLOC) &&
|
||||
(info->si_code == SI_TIMER);
|
||||
|
||||
__sigqueue_free(first);
|
||||
/*
|
||||
* posix-timer signals are preallocated and freed when the
|
||||
* timer goes away. Either directly or by clearing
|
||||
* SIGQUEUE_PREALLOC so that the next delivery will free
|
||||
* them. Spare the extra round through __sigqueue_free()
|
||||
* which is ignoring preallocated signals.
|
||||
*/
|
||||
if (unlikely((first->flags & SIGQUEUE_PREALLOC) && (info->si_code == SI_TIMER)))
|
||||
*timer_sigq = first;
|
||||
else
|
||||
__sigqueue_free(first);
|
||||
} else {
|
||||
/*
|
||||
* Ok, it wasn't in the queue. This must be
|
||||
@@ -588,12 +595,12 @@ still_pending:
|
||||
}
|
||||
|
||||
static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
|
||||
kernel_siginfo_t *info, bool *resched_timer)
|
||||
kernel_siginfo_t *info, struct sigqueue **timer_sigq)
|
||||
{
|
||||
int sig = next_signal(pending, mask);
|
||||
|
||||
if (sig)
|
||||
collect_signal(sig, pending, info, resched_timer);
|
||||
collect_signal(sig, pending, info, timer_sigq);
|
||||
return sig;
|
||||
}
|
||||
|
||||
@@ -605,18 +612,19 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
|
||||
int dequeue_signal(sigset_t *mask, kernel_siginfo_t *info, enum pid_type *type)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
bool resched_timer = false;
|
||||
struct sigqueue *timer_sigq;
|
||||
int signr;
|
||||
|
||||
lockdep_assert_held(&tsk->sighand->siglock);
|
||||
|
||||
again:
|
||||
*type = PIDTYPE_PID;
|
||||
signr = __dequeue_signal(&tsk->pending, mask, info, &resched_timer);
|
||||
timer_sigq = NULL;
|
||||
signr = __dequeue_signal(&tsk->pending, mask, info, &timer_sigq);
|
||||
if (!signr) {
|
||||
*type = PIDTYPE_TGID;
|
||||
signr = __dequeue_signal(&tsk->signal->shared_pending,
|
||||
mask, info, &resched_timer);
|
||||
mask, info, &timer_sigq);
|
||||
|
||||
if (unlikely(signr == SIGALRM))
|
||||
posixtimer_rearm_itimer(tsk);
|
||||
@@ -642,8 +650,8 @@ again:
|
||||
current->jobctl |= JOBCTL_STOP_DEQUEUED;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_POSIX_TIMERS) && unlikely(resched_timer)) {
|
||||
if (!posixtimer_deliver_signal(info))
|
||||
if (IS_ENABLED(CONFIG_POSIX_TIMERS) && unlikely(timer_sigq)) {
|
||||
if (!posixtimer_deliver_signal(info, timer_sigq))
|
||||
goto again;
|
||||
}
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ static void common_hrtimer_rearm(struct k_itimer *timr)
|
||||
* This function is called from the signal delivery code. It decides
|
||||
* whether the signal should be dropped and rearms interval timers.
|
||||
*/
|
||||
bool posixtimer_deliver_signal(struct kernel_siginfo *info)
|
||||
bool posixtimer_deliver_signal(struct kernel_siginfo *info, struct sigqueue *timer_sigq)
|
||||
{
|
||||
struct k_itimer *timr;
|
||||
unsigned long flags;
|
||||
|
||||
Reference in New Issue
Block a user