summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/posix-timers.h5
-rw-r--r--kernel/signal.c7
-rw-r--r--kernel/time/posix-timers.c3
3 files changed, 9 insertions, 6 deletions
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 670bf03a56ef..4ab49e5c42af 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -100,8 +100,9 @@ static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct,
{
pct->bases[CPUCLOCK_SCHED].nextevt = runtime;
}
+
void posixtimer_rearm_itimer(struct task_struct *p);
-void posixtimer_rearm(struct kernel_siginfo *info);
+bool posixtimer_deliver_signal(struct kernel_siginfo *info);
/* Init task static initializer */
#define INIT_CPU_TIMERBASE(b) { \
@@ -125,7 +126,7 @@ 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 void posixtimer_rearm(struct kernel_siginfo *info) { }
+static inline bool posixtimer_deliver_signal(struct kernel_siginfo *info) { return false; }
#endif
#ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
diff --git a/kernel/signal.c b/kernel/signal.c
index 1563c83ff224..df34aa47181e 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -594,6 +594,7 @@ int dequeue_signal(sigset_t *mask, kernel_siginfo_t *info, enum pid_type *type)
lockdep_assert_held(&tsk->sighand->siglock);
+again:
*type = PIDTYPE_PID;
signr = __dequeue_signal(&tsk->pending, mask, info, &resched_timer);
if (!signr) {
@@ -625,9 +626,9 @@ int dequeue_signal(sigset_t *mask, kernel_siginfo_t *info, enum pid_type *type)
current->jobctl |= JOBCTL_STOP_DEQUEUED;
}
- if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
- if (unlikely(resched_timer))
- posixtimer_rearm(info);
+ if (IS_ENABLED(CONFIG_POSIX_TIMERS) && unlikely(resched_timer)) {
+ if (!posixtimer_deliver_signal(info))
+ goto again;
}
return signr;
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 05af074285fa..dd0b1dff54d9 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -254,7 +254,7 @@ static void common_hrtimer_rearm(struct k_itimer *timr)
* info::si_sys_private is not zero, which indicates that the timer has to
* be rearmed. Restart the timer and update info::si_overrun.
*/
-void posixtimer_rearm(struct kernel_siginfo *info)
+bool posixtimer_deliver_signal(struct kernel_siginfo *info)
{
struct k_itimer *timr;
unsigned long flags;
@@ -286,6 +286,7 @@ out:
/* Don't expose the si_sys_private value to userspace */
info->si_sys_private = 0;
+ return true;
}
int posix_timer_queue_signal(struct k_itimer *timr)