As reported by Anton, there is a large penalty to signal handling performance on radix systems using KUAP. The signal handling code performs many user access operations, each of which needs to switch the KUAP permissions bit to open and then close user access. This involves a costly 'mtspr' operation [0].
There is existing work done on x86 and by Christopher Leroy for PPC32 to instead open up user access in "blocks" using user_*_access_{begin,end}. We can do the same in PPC64 to bring performance back up on KUAP-enabled radix systems. This series applies on top of Christophe Leroy's work for PPC32 [1] (I'm sure patchwork won't be too happy about that). The first two patches add some needed 'unsafe' versions of copy-from functions. While these do not make use of asm-goto they still allow for avoiding the repeated uaccess switches. The third patch adds 'notrace' to any functions expected to be called in a uaccess block context. Normally functions called in such a context should be inlined, but this is not feasible everywhere. Marking them 'notrace' should provide _some_ protection against leaving the user access window open. The next three patches rewrite some of the signal64 helper functions to be 'unsafe'. Finally, the last two patches update the main signal handling functions to make use of the new 'unsafe' helpers and eliminate some additional uaccess switching. I used the will-it-scale signal1 benchmark to measure and compare performance [2]. The below results are from a P9 Blackbird system. Note that currently hash does not support KUAP and is therefore used as the "baseline" comparison. Bigger numbers are better: signal1_threads -t1 -s10 | | hash | radix | | --------------- | ------ | ------ | | linuxppc/next | 289014 | 158408 | | unsafe-signal64 | 298506 | 253053 | [0]: https://github.com/linuxppc/issues/issues/277 [1]: https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=196278 [2]: https://github.com/antonblanchard/will-it-scale/blob/master/tests/signal1.c Christopher M. Riedl (5): powerpc/uaccess: Add unsafe_copy_from_user powerpc/signal: Add unsafe_copy_{vsx,fpr}_from_user() powerpc: Mark functions called inside uaccess blocks w/ 'notrace' powerpc/signal64: Replace setup_sigcontext() w/ unsafe_setup_sigcontext() powerpc/signal64: Replace restore_sigcontext() w/ unsafe_restore_sigcontext() Daniel Axtens (3): powerpc/signal64: Replace setup_trampoline() w/ unsafe_setup_trampoline() powerpc/signal64: Rewrite handle_rt_signal64() to minimise uaccess switches powerpc/signal64: Rewrite rt_sigreturn() to minimise uaccess switches arch/powerpc/include/asm/uaccess.h | 28 ++-- arch/powerpc/kernel/process.c | 20 +-- arch/powerpc/kernel/signal.h | 33 +++++ arch/powerpc/kernel/signal_64.c | 216 +++++++++++++++++------------ arch/powerpc/mm/mem.c | 4 +- 5 files changed, 194 insertions(+), 107 deletions(-) -- 2.28.0