From: Ulrich Drepper Date: Tue, 25 Aug 2009 17:42:30 +0000 (-0700) Subject: Handle AVX saving on x86-64 in interrupted smbol lookups. X-Git-Tag: fedora/glibc-2.10.90-16~1^2~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=84088310ce06bfc5759b37f0cd043dce80f578b6;p=thirdparty%2Fglibc.git Handle AVX saving on x86-64 in interrupted smbol lookups. If a signal arrived during a symbol lookup and the signal handler also required a symbol lookup, the end of the lookup in the signal handler reset the flag whether restoring AVX/SSE registers is needed. Resetting means in this case that the tail part of the outer lookup code will try to restore the registers and this can fail miserably. We now restore to the previous value which makes nesting calls possible. --- diff --git a/ChangeLog b/ChangeLog index b2d98e4ee79..560f5db55cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-08-25 Ulrich Drepper + + * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Remove + leftover YMM_SIZE definition. + 2009-08-24 Ulrich Drepper * math/math_private.h (ieee_double_shape_type): Add uint64_t word to diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 3887969cb88..a9a0168357c 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,10 @@ +2009-08-25 Ulrich Drepper + + * sysdeps/x86_64/tls.h (RTLD_ENABLE_FOREIGN_CALL): Store old value + of the field in local variables. + (RTLD_FINALIZE_FOREIGN_CALL): Restore rtld_must_xmm_save from local + variable and don't unconditionally clear it. + 2009-08-24 Ulrich Drepper * pthread_create.c (start_thread): Hint to the kernel that memory for diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h index 4212038ab50..e39eb5f69d4 100644 --- a/nptl/sysdeps/x86_64/tls.h +++ b/nptl/sysdeps/x86_64/tls.h @@ -188,7 +188,7 @@ typedef struct The contained asm must *not* be marked volatile since otherwise assignments like - pthread_descr self = thread_self(); + pthread_descr self = thread_self(); do not get optimized away. */ # define THREAD_SELF \ ({ struct pthread *__self; \ @@ -404,7 +404,12 @@ extern void _dl_x86_64_restore_sse (void); # define RTLD_CHECK_FOREIGN_CALL \ (THREAD_GETMEM (THREAD_SELF, header.rtld_must_xmm_save) != 0) +/* NB: Don't use the xchg operation because that would imply a lock + prefix which is expensive and unnecessary. The cache line is also + not contested at all. */ # define RTLD_ENABLE_FOREIGN_CALL \ + int old_rtld_must_xmm_save = THREAD_GETMEM (THREAD_SELF, \ + header.rtld_must_xmm_save); \ THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, 1) # define RTLD_PREPARE_FOREIGN_CALL \ @@ -419,7 +424,8 @@ extern void _dl_x86_64_restore_sse (void); do { \ if (THREAD_GETMEM (THREAD_SELF, header.rtld_must_xmm_save) == 0) \ _dl_x86_64_restore_sse (); \ - THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, 0); \ + THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, \ + old_rtld_must_xmm_save); \ } while (0) # endif diff --git a/sysdeps/x86_64/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S index f9c60ad5cfb..5564a11af29 100644 --- a/sysdeps/x86_64/dl-trampoline.S +++ b/sysdeps/x86_64/dl-trampoline.S @@ -197,7 +197,6 @@ _dl_x86_64_save_sse: ret L(no_avx5): # endif -# define YMM_SIZE 16 movdqa %xmm0, %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE movdqa %xmm1, %fs:RTLD_SAVESPACE_SSE+1*XMM_SIZE movdqa %xmm2, %fs:RTLD_SAVESPACE_SSE+2*XMM_SIZE