| From foo@baz Sun Jun 17 12:07:34 CEST 2018 |
| From: Dave Hansen <dave.hansen@linux.intel.com> |
| Date: Wed, 9 May 2018 10:13:44 -0700 |
| Subject: x86/pkeys/selftests: Avoid printf-in-signal deadlocks |
| |
| From: Dave Hansen <dave.hansen@linux.intel.com> |
| |
| [ Upstream commit caf9eb6b4c82fc6cbd03697052ff22d97b0c377b ] |
| |
| printf() and friends are unusable in signal handlers. They deadlock. |
| The pkey selftest does not do any normal printing in signal handlers, |
| only extra debugging. So, just print the format string so we get |
| *some* output when debugging. |
| |
| Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> |
| Cc: Andrew Morton <akpm@linux-foundation.org> |
| Cc: Dave Hansen <dave.hansen@intel.com> |
| Cc: Linus Torvalds <torvalds@linux-foundation.org> |
| Cc: Michael Ellermen <mpe@ellerman.id.au> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Ram Pai <linuxram@us.ibm.com> |
| Cc: Shuah Khan <shuah@kernel.org> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Cc: linux-mm@kvack.org |
| Link: http://lkml.kernel.org/r/20180509171344.C53FD2F3@viggo.jf.intel.com |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| tools/testing/selftests/x86/pkey-helpers.h | 20 ++++++++------------ |
| 1 file changed, 8 insertions(+), 12 deletions(-) |
| |
| --- a/tools/testing/selftests/x86/pkey-helpers.h |
| +++ b/tools/testing/selftests/x86/pkey-helpers.h |
| @@ -26,30 +26,26 @@ static inline void sigsafe_printf(const |
| { |
| va_list ap; |
| |
| - va_start(ap, format); |
| if (!dprint_in_signal) { |
| + va_start(ap, format); |
| vprintf(format, ap); |
| + va_end(ap); |
| } else { |
| int ret; |
| - int len = vsnprintf(dprint_in_signal_buffer, |
| - DPRINT_IN_SIGNAL_BUF_SIZE, |
| - format, ap); |
| /* |
| - * len is amount that would have been printed, |
| - * but actual write is truncated at BUF_SIZE. |
| + * No printf() functions are signal-safe. |
| + * They deadlock easily. Write the format |
| + * string to get some output, even if |
| + * incomplete. |
| */ |
| - if (len > DPRINT_IN_SIGNAL_BUF_SIZE) |
| - len = DPRINT_IN_SIGNAL_BUF_SIZE; |
| - ret = write(1, dprint_in_signal_buffer, len); |
| + ret = write(1, format, strlen(format)); |
| if (ret < 0) |
| - abort(); |
| + exit(1); |
| } |
| - va_end(ap); |
| } |
| #define dprintf_level(level, args...) do { \ |
| if (level <= DEBUG_LEVEL) \ |
| sigsafe_printf(args); \ |
| - fflush(NULL); \ |
| } while (0) |
| #define dprintf0(args...) dprintf_level(0, args) |
| #define dprintf1(args...) dprintf_level(1, args) |