Merge tag 'timers_urgent_for_v6.13_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer fixes from Borislav Petkov:

 - Fix a case where posix timers with a thread-group-wide target would
   miss signals if some of the group's threads are exiting

 - Fix a hang caused by ndelay() calling the wrong delay function
   __udelay()

 - Fix a wrong offset calculation in adjtimex(2) when using ADJ_MICRO
   (microsecond resolution) and a negative offset

* tag 'timers_urgent_for_v6.13_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  posix-timers: Target group sigqueue to current task only if not exiting
  delay: Fix ndelay() spuriously treated as udelay()
  ntp: Remove invalid cast in time offset math
This commit is contained in:
Linus Torvalds
2024-12-01 12:41:21 -08:00
3 changed files with 7 additions and 6 deletions

View File

@@ -75,11 +75,11 @@ static __always_inline void ndelay(unsigned long nsec)
{
if (__builtin_constant_p(nsec)) {
if (nsec >= DELAY_CONST_MAX)
__bad_udelay();
__bad_ndelay();
else
__const_udelay(nsec * NDELAY_CONST_MULT);
} else {
__udelay(nsec);
__ndelay(nsec);
}
}
#define ndelay(x) ndelay(x)

View File

@@ -1959,14 +1959,15 @@ static void posixtimer_queue_sigqueue(struct sigqueue *q, struct task_struct *t,
*
* Where type is not PIDTYPE_PID, signals must be delivered to the
* process. In this case, prefer to deliver to current if it is in
* the same thread group as the target process, which avoids
* unnecessarily waking up a potentially idle task.
* the same thread group as the target process and its sighand is
* stable, which avoids unnecessarily waking up a potentially idle task.
*/
static inline struct task_struct *posixtimer_get_target(struct k_itimer *tmr)
{
struct task_struct *t = pid_task(tmr->it_pid, tmr->it_pid_type);
if (t && tmr->it_pid_type != PIDTYPE_PID && same_thread_group(t, current))
if (t && tmr->it_pid_type != PIDTYPE_PID &&
same_thread_group(t, current) && !current->exit_state)
t = current;
return t;
}

View File

@@ -798,7 +798,7 @@ int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts,
txc->offset = shift_right(ntpdata->time_offset * NTP_INTERVAL_FREQ, NTP_SCALE_SHIFT);
if (!(ntpdata->time_status & STA_NANO))
txc->offset = (u32)txc->offset / NSEC_PER_USEC;
txc->offset = div_s64(txc->offset, NSEC_PER_USEC);
}
result = ntpdata->time_state;