Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull timer fix from Eric Biederman:
"This fixes an issue of confusing injected signals with the signals
from posix timers that has existed since posix timers have been in the
kernel.

This patch is slightly simpler than my earlier version of this patch
as I discovered in testing that I had misspelled "#ifdef
CONFIG_POSIX_TIMERS". So I deleted that unnecessary test and made
setting of resched_timer uncondtional.

I have tested this and verified that without this patch there is a
nasty hang that is easy to trigger, and with this patch everything
works properly"

Thomas Gleixner dixit:
"It fixes the problem at hand and covers the ptrace case as well, which
I missed.

Reviewed-and-tested-by: Thomas Gleixner <tglx@linutronix.de>"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace:
signal: Only reschedule timers on signals timers have sent

+14 -6
+14 -6
kernel/signal.c
··· 510 510 return !tsk->ptrace; 511 511 } 512 512 513 - static void collect_signal(int sig, struct sigpending *list, siginfo_t *info) 513 + static void collect_signal(int sig, struct sigpending *list, siginfo_t *info, 514 + bool *resched_timer) 514 515 { 515 516 struct sigqueue *q, *first = NULL; 516 517 ··· 533 532 still_pending: 534 533 list_del_init(&first->list); 535 534 copy_siginfo(info, &first->info); 535 + 536 + *resched_timer = 537 + (first->flags & SIGQUEUE_PREALLOC) && 538 + (info->si_code == SI_TIMER) && 539 + (info->si_sys_private); 540 + 536 541 __sigqueue_free(first); 537 542 } else { 538 543 /* ··· 555 548 } 556 549 557 550 static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, 558 - siginfo_t *info) 551 + siginfo_t *info, bool *resched_timer) 559 552 { 560 553 int sig = next_signal(pending, mask); 561 554 562 555 if (sig) 563 - collect_signal(sig, pending, info); 556 + collect_signal(sig, pending, info, resched_timer); 564 557 return sig; 565 558 } 566 559 ··· 572 565 */ 573 566 int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) 574 567 { 568 + bool resched_timer = false; 575 569 int signr; 576 570 577 571 /* We only dequeue private signals from ourselves, we don't let 578 572 * signalfd steal them 579 573 */ 580 - signr = __dequeue_signal(&tsk->pending, mask, info); 574 + signr = __dequeue_signal(&tsk->pending, mask, info, &resched_timer); 581 575 if (!signr) { 582 576 signr = __dequeue_signal(&tsk->signal->shared_pending, 583 - mask, info); 577 + mask, info, &resched_timer); 584 578 #ifdef CONFIG_POSIX_TIMERS 585 579 /* 586 580 * itimer signal ? ··· 629 621 current->jobctl |= JOBCTL_STOP_DEQUEUED; 630 622 } 631 623 #ifdef CONFIG_POSIX_TIMERS 632 - if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) { 624 + if (resched_timer) { 633 625 /* 634 626 * Release the siglock to ensure proper locking order 635 627 * of timer locks outside of siglocks. Note, we leave