Message ID | 20230414193700.542116-2-bugaevc@gmail.com |
---|---|
State | New |
Headers | show |
Series | [1/5] hurd: Fix restoring reply port in sigreturn | expand |
Hello, Sergey Bugaev, le ven. 14 avril 2023 22:36:57 +0300, a ecrit: > - struct hurd_sigstate *ss = _hurd_self_sigstate (); > + struct hurd_sigstate *ss; > + > + /* We know the sigstate must be initialized, That doesn't seem to be true, we get segfaults with this patch applied in these tests: ./htl/tst-kill6.test-result:FAIL: htl/tst-kill6 ./htl/tst-pt-tls2.test-result:FAIL: htl/tst-pt-tls2 #0 0x0105a7c2 in sigstate_is_global_rcv (ss=0x0) at hurdsig.c:183 183 && (ss->actions[0].sa_handler == SIG_IGN); (gdb) bt #0 0x0105a7c2 in sigstate_is_global_rcv (ss=0x0) at hurdsig.c:183 #1 __GI__hurd_sigstate_lock (ss=0x0) at hurdsig.c:192 #2 0x0108bb17 in __sigreturn (scp=0x2104bec) at ../sysdeps/mach/hurd/i386/sigreturn.c:94 #3 0x010602f6 in trampoline () from ./libc.so.0.3 Samuel
(Git managed to eat my email -- it both sent an empty one *and* truncated my local file (what?); so retyping and resending this.) On Tue, Apr 18, 2023 at 2:23 AM Samuel Thibault <samuel.thibault@gnu.org> wrote: > That doesn't seem to be true, we get segfaults with this patch applied > in these tests: > > ./htl/tst-kill6.test-result:FAIL: htl/tst-kill6 > ./htl/tst-pt-tls2.test-result:FAIL: htl/tst-pt-tls2 > > #0 0x0105a7c2 in sigstate_is_global_rcv (ss=0x0) at hurdsig.c:183 > 183 && (ss->actions[0].sa_handler == SIG_IGN); > (gdb) bt > #0 0x0105a7c2 in sigstate_is_global_rcv (ss=0x0) at hurdsig.c:183 > #1 __GI__hurd_sigstate_lock (ss=0x0) at hurdsig.c:192 > #2 0x0108bb17 in __sigreturn (scp=0x2104bec) at ../sysdeps/mach/hurd/i386/sigreturn.c:94 > #3 0x010602f6 in trampoline () from ./libc.so.0.3 Interesting; so while the sigstate for the thread must have been initialized, it seems it has never been installed into the tcb->_hurd_sigstate slot, because the thread has never called _hurd_self_sigstate (). So we have to make the full call to _hurd_self_sigstate () the first time, to find the sigstate and install it into the slot. Please try this: Sergey ---- >8 ---- From 94fc9499390b4de9fbe10c3014d473ac42878c6a Mon Sep 17 00:00:00 2001 From: Sergey Bugaev <bugaevc@gmail.com> Date: Fri, 14 Apr 2023 16:32:45 +0300 Subject: [PATCH] hurd: Microoptimize sigreturn Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> --- sysdeps/mach/hurd/i386/sigreturn.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sysdeps/mach/hurd/i386/sigreturn.c b/sysdeps/mach/hurd/i386/sigreturn.c index a0fc8891..1686734d 100644 --- a/sysdeps/mach/hurd/i386/sigreturn.c +++ b/sysdeps/mach/hurd/i386/sigreturn.c @@ -29,7 +29,12 @@ static void __sigreturn2 (int *usp, struct sigcontext *scp) { mach_port_t reply_port; - struct hurd_sigstate *ss = _hurd_self_sigstate (); + struct hurd_sigstate *ss; + + /* We know the sigstate must be initialized by the call below, but the + compiler does not. Help it out a little bit by eliding the check that + _hurd_self_sigstate makes otherwise. */ + ss = THREAD_GETMEM (THREAD_SELF, _hurd_sigstate); _hurd_sigstate_unlock (ss); /* Destroy the MiG reply port used by the signal handler, and restore the @@ -44,7 +49,7 @@ __sigreturn2 (int *usp, struct sigcontext *scp) do. */ reply_port = THREAD_GETMEM (THREAD_SELF, reply_port); THREAD_SETMEM (THREAD_SELF, reply_port, MACH_PORT_DEAD); - if (MACH_PORT_VALID (reply_port)) + if (__glibc_likely (MACH_PORT_VALID (reply_port))) (void) __mach_port_mod_refs (__mach_task_self (), reply_port, MACH_PORT_RIGHT_RECEIVE, -1); THREAD_SETMEM (THREAD_SELF, reply_port, scp->sc_reply_port); @@ -69,6 +74,7 @@ __sigreturn2 (int *usp, struct sigcontext *scp) /* Firewall. */ A (hlt); #undef A + __builtin_unreachable (); } int @@ -77,7 +83,7 @@ __sigreturn (struct sigcontext *scp) struct hurd_sigstate *ss; struct hurd_userlink *link = (void *) &scp[1]; - if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK)) + if (__glibc_unlikely (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))) { errno = EINVAL; return -1;
Sergey Bugaev, le mar. 18 avril 2023 13:21:50 +0300, a ecrit: > (Git managed to eat my email -- it both sent an empty one *and* > truncated my local file (what?); so retyping and resending this.) > > On Tue, Apr 18, 2023 at 2:23 AM Samuel Thibault <samuel.thibault@gnu.org> wrote: > > That doesn't seem to be true, we get segfaults with this patch applied > > in these tests: > > > > ./htl/tst-kill6.test-result:FAIL: htl/tst-kill6 > > ./htl/tst-pt-tls2.test-result:FAIL: htl/tst-pt-tls2 > > > > #0 0x0105a7c2 in sigstate_is_global_rcv (ss=0x0) at hurdsig.c:183 > > 183 && (ss->actions[0].sa_handler == SIG_IGN); > > (gdb) bt > > #0 0x0105a7c2 in sigstate_is_global_rcv (ss=0x0) at hurdsig.c:183 > > #1 __GI__hurd_sigstate_lock (ss=0x0) at hurdsig.c:192 > > #2 0x0108bb17 in __sigreturn (scp=0x2104bec) at ../sysdeps/mach/hurd/i386/sigreturn.c:94 > > #3 0x010602f6 in trampoline () from ./libc.so.0.3 > > Interesting; so while the sigstate for the thread must have been > initialized, it seems it has never been installed into the > tcb->_hurd_sigstate slot, because the thread has never called > _hurd_self_sigstate (). So we have to make the full call to > _hurd_self_sigstate () the first time, to find the sigstate and > install it into the slot. > > Please try this: That one works fine, applied, thanks! > Sergey > > ---- >8 ---- > > > From 94fc9499390b4de9fbe10c3014d473ac42878c6a Mon Sep 17 00:00:00 2001 > From: Sergey Bugaev <bugaevc@gmail.com> > Date: Fri, 14 Apr 2023 16:32:45 +0300 > Subject: [PATCH] hurd: Microoptimize sigreturn > > Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> > --- > sysdeps/mach/hurd/i386/sigreturn.c | 12 +++++++++--- > 1 file changed, 9 insertions(+), 3 deletions(-) > > diff --git a/sysdeps/mach/hurd/i386/sigreturn.c b/sysdeps/mach/hurd/i386/sigreturn.c > index a0fc8891..1686734d 100644 > --- a/sysdeps/mach/hurd/i386/sigreturn.c > +++ b/sysdeps/mach/hurd/i386/sigreturn.c > @@ -29,7 +29,12 @@ static void > __sigreturn2 (int *usp, struct sigcontext *scp) > { > mach_port_t reply_port; > - struct hurd_sigstate *ss = _hurd_self_sigstate (); > + struct hurd_sigstate *ss; > + > + /* We know the sigstate must be initialized by the call below, but the > + compiler does not. Help it out a little bit by eliding the check that > + _hurd_self_sigstate makes otherwise. */ > + ss = THREAD_GETMEM (THREAD_SELF, _hurd_sigstate); > _hurd_sigstate_unlock (ss); > > /* Destroy the MiG reply port used by the signal handler, and restore the > @@ -44,7 +49,7 @@ __sigreturn2 (int *usp, struct sigcontext *scp) > do. */ > reply_port = THREAD_GETMEM (THREAD_SELF, reply_port); > THREAD_SETMEM (THREAD_SELF, reply_port, MACH_PORT_DEAD); > - if (MACH_PORT_VALID (reply_port)) > + if (__glibc_likely (MACH_PORT_VALID (reply_port))) > (void) __mach_port_mod_refs (__mach_task_self (), reply_port, > MACH_PORT_RIGHT_RECEIVE, -1); > THREAD_SETMEM (THREAD_SELF, reply_port, scp->sc_reply_port); > @@ -69,6 +74,7 @@ __sigreturn2 (int *usp, struct sigcontext *scp) > /* Firewall. */ > A (hlt); > #undef A > + __builtin_unreachable (); > } > > int > @@ -77,7 +83,7 @@ __sigreturn (struct sigcontext *scp) > struct hurd_sigstate *ss; > struct hurd_userlink *link = (void *) &scp[1]; > > - if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK)) > + if (__glibc_unlikely (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))) > { > errno = EINVAL; > return -1; > -- > 2.39.2 >
diff --git a/sysdeps/mach/hurd/i386/sigreturn.c b/sysdeps/mach/hurd/i386/sigreturn.c index a0fc8891..6ad8a998 100644 --- a/sysdeps/mach/hurd/i386/sigreturn.c +++ b/sysdeps/mach/hurd/i386/sigreturn.c @@ -29,7 +29,12 @@ static void __sigreturn2 (int *usp, struct sigcontext *scp) { mach_port_t reply_port; - struct hurd_sigstate *ss = _hurd_self_sigstate (); + struct hurd_sigstate *ss; + + /* We know the sigstate must be initialized, but the compiler does not. + Help it out a little bit by eliding the check that _hurd_self_sigstate + makes otherwise. */ + ss = THREAD_GETMEM (THREAD_SELF, _hurd_sigstate); _hurd_sigstate_unlock (ss); /* Destroy the MiG reply port used by the signal handler, and restore the @@ -44,7 +49,7 @@ __sigreturn2 (int *usp, struct sigcontext *scp) do. */ reply_port = THREAD_GETMEM (THREAD_SELF, reply_port); THREAD_SETMEM (THREAD_SELF, reply_port, MACH_PORT_DEAD); - if (MACH_PORT_VALID (reply_port)) + if (__glibc_likely (MACH_PORT_VALID (reply_port))) (void) __mach_port_mod_refs (__mach_task_self (), reply_port, MACH_PORT_RIGHT_RECEIVE, -1); THREAD_SETMEM (THREAD_SELF, reply_port, scp->sc_reply_port); @@ -69,6 +74,7 @@ __sigreturn2 (int *usp, struct sigcontext *scp) /* Firewall. */ A (hlt); #undef A + __builtin_unreachable (); } int @@ -77,13 +83,14 @@ __sigreturn (struct sigcontext *scp) struct hurd_sigstate *ss; struct hurd_userlink *link = (void *) &scp[1]; - if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK)) + if (__glibc_unlikely (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))) { errno = EINVAL; return -1; } - ss = _hurd_self_sigstate (); + /* Same as above, microoptimize _hurd_self_sigstate. */ + ss = THREAD_GETMEM (THREAD_SELF, _hurd_sigstate); _hurd_sigstate_lock (ss); /* Remove the link on the `active resources' chain added by
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> --- I'll understand if this patch will be rejected, since this is not a hot path. But I just couldn't help myself when I saw what this was being compiled to! Much cleaner now. If you don't like THREAD_GETMEM (THREAD_SELF, _hurd_sigstate), we could have _hurd_self_sigstate_fast () or something. sysdeps/mach/hurd/i386/sigreturn.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)