All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch 00/45] posix-timers: Cure inconsistencies and the SIG_IGN mess
@ 2023-06-06 14:37 Thomas Gleixner
  2023-06-06 14:37 ` [patch 01/45] selftests/timers/posix_timers: Make signal distribution test less fragile Thomas Gleixner
                   ` (44 more replies)
  0 siblings, 45 replies; 66+ messages in thread
From: Thomas Gleixner @ 2023-06-06 14:37 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Anna-Maria Behnsen, John Stultz,
	Peter Zijlstra, Ingo Molnar, Stephen Boyd, Eric Biederman,
	Oleg Nesterov

Hi!

My recent cleanup work made me reread a 15 years old comment about the
SIG_IGN problem:

 "FIXME: What we really want, is to stop this timer completely and restart
  it in case the SIG_IGN is removed. This is a non trivial change which
  involves sighand locking (sigh !), which we don't want to do late in the
  release cycle.  ...  A more complex fix which solves also another related
  inconsistency is already in the pipeline."

The embarrasing part was that I put that comment in back then. So I went
back and rumaged through old notes as I completely had forgotten why our
attempts to fix this back then failed.

It turned out that the comment is about right: sighand locking and life
time issues. So I sat down with the old notes and started to wrap my head
around this again.

The problem to solve:

Posix interval timers are not rearmed automatically by the kernel for
various reasons:

   1) To prevent DoS by extremly short intervals.
   2) To avoid timer overhead when a signal is pending and has not
      yet been delivered.

This is achieved by queueing the signal at timer expiry and rearming the
timer at signal delivery to user space. This puts the rearming basically
under scheduler control and the work happens in context of the task which
asked for the signal.

There is a problem with that vs. SIG_IGN. If a signal has SIG_IGN installed
as handler the related signals are discarded. So in case of posix interval
timers this means that such a timer is never rearmed even when SIG_IGN is
replaced later with a real handler (including SIG_DFL).

To work around that the kernel self rearms those timers and throttles them
when the interval is smaller than a tick to prevent a DoS.

That just keeps timers ticking, which obviously has effects on power and
just creates work for nothing.

So ideally these timers should be stopped and rearmed when SIG_IGN is
replaced, which aligns with the regular handling of posix timers.

Sounds trivial, but isn't:

  1) Lock ordering.

     The timer lock cannot be taken with sighand lock held which is
     problematic vs. the atomicity of sigaction().

  2) Life time rules

     The timer and the sigqueue are separate entities which requires a
     lookup of the timer ID in the signal rearm code. This can be handled,
     but the separate life time rules are not necessarily robust.

  3) Finding the relevant timers

     Obviosly it is possible to walk the posix timer list under sighand
     lock and handle it from there. That can be expensive especially in the
     case that there are no affected timers as the walk would just end up
     doing nothing.

The following series is a new and this time actually working attempt to
solve this. It addresses it by:

  1) Embedding the preallocated sigqueue into struct k_itimer, which makes
     the life time rules way simpler and just needs a trivial reference
     count.

  2) Having a separate list in task::signal on which ignored timers are
     queued.

     This avoids walking a potentially large timer list for nothing on a
     SIG_IGN to handler transition.

  3) Requeueing the timers signal in the relevant signal queue so the timer
     is rearmed when the signal is actually delivered

     That turned out to be the least complicated way to address the sighand
     lock vs. timer lock ordering issue.

With that timers which have their signal ignored are not longer self
rearmed and the relevant workarounds including throttling for DoS
prevention are removed.

Aside of the SIG_IGN issues it also addresses a few inconsistencies in
posix CPU timers and the general inconsistency of signal handling
vs. disarmed, reprogrammed and deleted timers.

To actually validate the fixes the posix timer self test has been expanded
with tests which cover not only the simple SIG IGN case but also more
complex scenarios which have never been handled correctly by the current
self rearming work around.

The series is based on:

    git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core

and is also available from git:

    git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git timers/posix

Thanks,

	tglx
---
 arch/x86/kernel/signal_32.c                   |    2 
 arch/x86/kernel/signal_64.c                   |    2 
 drivers/power/supply/charger-manager.c        |    3 
 fs/proc/base.c                                |   10 
 fs/signalfd.c                                 |    4 
 fs/timerfd.c                                  |    4 
 include/linux/alarmtimer.h                    |   10 
 include/linux/posix-timers.h                  |   69 ++
 include/linux/sched/signal.h                  |   11 
 include/uapi/asm-generic/siginfo.h            |    2 
 init/init_task.c                              |    5 
 kernel/fork.c                                 |    3 
 kernel/signal.c                               |  486 ++++++++++++--------
 kernel/time/alarmtimer.c                      |   82 ---
 kernel/time/itimer.c                          |   22 
 kernel/time/posix-cpu-timers.c                |  227 +++------
 kernel/time/posix-timers.c                    |  285 ++++++------
 kernel/time/posix-timers.h                    |    9 
 net/netfilter/xt_IDLETIMER.c                  |    4
 19 files changed, 642 insertions(+), 598 deletions(-)
 
 tools/testing/selftests/timers/posix_timers.c |  606 +++++++++++++++++++++-----
 1 file changed, 491 insertions(+), 115 deletions(-)

^ permalink raw reply	[flat|nested] 66+ messages in thread

end of thread, other threads:[~2023-07-04 10:24 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-06 14:37 [patch 00/45] posix-timers: Cure inconsistencies and the SIG_IGN mess Thomas Gleixner
2023-06-06 14:37 ` [patch 01/45] selftests/timers/posix_timers: Make signal distribution test less fragile Thomas Gleixner
2023-06-06 14:37 ` [patch 02/45] selftests/timers/posix_timers: Use TAP reporting format Thomas Gleixner
2023-06-06 14:37 ` [patch 03/45] selftests/timers/posix_timers: Add SIG_IGN test Thomas Gleixner
2023-06-06 14:37 ` [patch 04/45] selftests/timers/posix_timers: Validate signal rules Thomas Gleixner
2023-06-06 14:37 ` [patch 05/45] selftests/timers/posix-timers: Validate SIGEV_NONE Thomas Gleixner
2023-06-06 14:37 ` [patch 06/45] selftests/timers/posix-timers: Validate timer_gettime() Thomas Gleixner
2023-06-06 14:37 ` [patch 07/45] selftests/timers/posix-timers: Validate overrun after unblock Thomas Gleixner
2023-06-06 14:37 ` [patch 08/45] posix-timers: Convert timer list to hlist Thomas Gleixner
2023-06-22 21:18   ` Frederic Weisbecker
2023-06-06 14:37 ` [patch 09/45] posix-cpu-timers: Fix posix_cpu_timer_get() behaviour Thomas Gleixner
2023-06-26 22:46   ` Frederic Weisbecker
2023-06-29 18:14     ` Thomas Gleixner
2023-06-06 14:37 ` [patch 10/45] posix-cpu-timers: Use @now instead of @val for clarity Thomas Gleixner
2023-06-27  9:53   ` Frederic Weisbecker
2023-06-06 14:37 ` [patch 11/45] posix-cpu-timers: Remove incorrect comment in posix_cpu_timer_set() Thomas Gleixner
2023-06-27 10:30   ` Frederic Weisbecker
2023-06-06 14:37 ` [patch 12/45] posix-cpu-timers: Simplify posix_cpu_timer_set() Thomas Gleixner
2023-06-27 10:51   ` Frederic Weisbecker
2023-06-29 18:43     ` Thomas Gleixner
2023-06-06 14:37 ` [patch 13/45] posix-cpu-timers: Replace old expiry retrieval in posix_cpu_timer_set() Thomas Gleixner
2023-06-27 11:32   ` Frederic Weisbecker
2023-06-06 14:37 ` [patch 14/45] posix-timers: Consolidate interval retrieval Thomas Gleixner
2023-06-28 13:08   ` Frederic Weisbecker
2023-06-29 18:47     ` Thomas Gleixner
2023-06-30 11:25       ` Frederic Weisbecker
2023-06-30 13:07         ` Thomas Gleixner
2023-06-30 14:04           ` Frederic Weisbecker
2023-07-01 18:01             ` Thomas Gleixner
2023-06-06 14:37 ` [patch 15/45] posix-timers: Clear overrun in common_timer_set() Thomas Gleixner
2023-06-30 21:40   ` Frederic Weisbecker
2023-06-06 14:37 ` [patch 16/45] posix-timers: Consolidate timer setup Thomas Gleixner
2023-07-03 21:12   ` Frederic Weisbecker
2023-06-06 14:37 ` [patch 17/45] posix-cpu-timers: Make k_itimer::it_active consistent Thomas Gleixner
2023-07-03 22:30   ` Frederic Weisbecker
2023-06-06 14:37 ` [patch 18/45] posix-timers: Consolidate signal queueing Thomas Gleixner
2023-07-03 22:51   ` Frederic Weisbecker
2023-06-06 14:37 ` [patch 19/45] signal: Remove task argument from dequeue_signal() Thomas Gleixner
2023-07-04 10:02   ` Frederic Weisbecker
2023-06-06 14:37 ` [patch 20/45] signal: Replace BUG_ON()s Thomas Gleixner
2023-07-04 10:24   ` Frederic Weisbecker
2023-06-06 14:37 ` [patch 21/45] signal: Confine POSIX_TIMERS properly Thomas Gleixner
2023-06-06 14:37 ` [patch 22/45] signal: Get rid of resched_timer logic Thomas Gleixner
2023-06-06 14:37 ` [patch 23/45] posix-timers: Cure si_sys_private race Thomas Gleixner
2023-06-06 14:37 ` [patch 24/45] signal: Allow POSIX timer signals to be dropped Thomas Gleixner
2023-06-06 14:37 ` [patch 25/45] posix-timers: Drop signal if timer has been deleted or reprogrammed Thomas Gleixner
2023-06-06 14:38 ` [patch 26/45] posix-timers: Rename k_itimer::it_requeue_pending Thomas Gleixner
2023-06-06 14:38 ` [patch 27/45] posix-timers: Add proper state tracking Thomas Gleixner
2023-06-06 14:38 ` [patch 28/45] posix-timers: Make signal delivery consistent Thomas Gleixner
2023-06-06 14:38 ` [patch 29/45] posix-timers: Make signal overrun accounting sensible Thomas Gleixner
2023-06-06 14:38 ` [patch 30/45] posix-cpu-timers: Use dedicated flag for CPU timer nanosleep Thomas Gleixner
2023-06-06 14:38 ` [patch 31/45] posix-timers: Add a refcount to struct k_itimer Thomas Gleixner
2023-06-06 14:38 ` [patch 32/45] signal: Split up __sigqueue_alloc() Thomas Gleixner
2023-06-06 14:38 ` [patch 33/45] signal: Provide posixtimer_sigqueue_init() Thomas Gleixner
2023-06-06 14:38 ` [patch 34/45] signal: Add sys_private_ptr to siginfo::_sifields::_timer Thomas Gleixner
2023-06-06 14:38 ` [patch 35/45] signal: Refactor send_sigqueue() Thomas Gleixner
2023-06-06 14:38 ` [patch 36/45] posix-timers: Embed sigqueue in struct k_itimer Thomas Gleixner
2023-06-06 14:38 ` [patch 37/45] signal: Cleanup unused posix-timer leftovers Thomas Gleixner
2023-06-06 14:38 ` [patch 38/45] signal: Add task argument to flush_sigqueue_mask() Thomas Gleixner
2023-06-06 14:38 ` [patch 39/45] signal: Provide ignored_posix_timers list Thomas Gleixner
2023-06-06 14:38 ` [patch 40/45] posix-timers: Handle ignored list on delete and exit Thomas Gleixner
2023-06-06 14:38 ` [patch 41/45] signal: Handle ignored signals in do_sigaction(action != SIG_IGN) Thomas Gleixner
2023-06-06 14:38 ` [patch 42/45] signal: Queue ignored posixtimers on ignore list Thomas Gleixner
2023-06-06 14:38 ` [patch 43/45] posix-timers: Cleanup SIG_IGN workaround leftovers Thomas Gleixner
2023-06-06 14:38 ` [patch 44/45] alarmtimers: Remove the throttle mechanism from alarm_forward_now() Thomas Gleixner
2023-06-06 14:38 ` [patch 45/45] alarmtimers: Remove return value from alarm functions Thomas Gleixner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.