signal: Skip the altstack update when not needed
authorChang S. Bae <chang.seok.bae@intel.com>
Fri, 10 Dec 2021 22:55:03 +0000 (14:55 -0800)
committerDave Hansen <dave.hansen@linux.intel.com>
Tue, 14 Dec 2021 21:08:36 +0000 (13:08 -0800)
commit6c3118c32129b4197999a8928ba776bcabd0f5c4
tree839fa17c2527f3ce0ad401a9bb57ff0022e598af
parentcabdc3a8475b918e55744f43719b26a82dc8fa6b
signal: Skip the altstack update when not needed

== Background ==

Support for large, "dynamic" fpstates was recently merged.  This
included code to ensure that sigaltstacks are sufficiently sized for
these large states.  A new lock was added to remove races between
enabling large features and setting up sigaltstacks.

== Problem ==

The new lock (sigaltstack_lock()) is acquired in the sigreturn path
before restoring the old sigaltstack.  Unfortunately, contention on the
new lock causes a measurable signal handling performance regression [1].
However, the common case is that no *changes* are made to the
sigaltstack state at sigreturn.

== Solution ==

do_sigaltstack() acquires sigaltstack_lock() and is used for both
sys_sigaltstack() and restoring the sigaltstack in sys_sigreturn().
Check for changes to the sigaltstack before taking the lock.  If no
changes were made, return before acquiring the lock.

This removes lock contention from the common-case sigreturn path.

[1] https://lore.kernel.org/lkml/20211207012128.GA16074@xsang-OptiPlex-9020/

Fixes: 3aac3ebea08f ("x86/signal: Implement sigaltstack size validation")
Reported-by: kernel test robot <oliver.sang@intel.com>
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20211210225503.12734-1-chang.seok.bae@intel.com
kernel/signal.c