* [PATCH] x86: do_signal: simplify the TS_RESTORE_SIGMASK logic
@ 2011-07-10 18:22 Oleg Nesterov
2011-07-10 21:08 ` Al Viro
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Oleg Nesterov @ 2011-07-10 18:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: David Howells, David Woodhouse, Ingo Molnar, linux-kernel
1. do_signal() looks at TS_RESTORE_SIGMASK and calculates the
mask which should be stored in the signal frame, then it
passes "oldset" to the callees, down to setup_rt_frame().
This is ugly, setup_rt_frame() can do this itself and nobody
else needs this sigset_t. Move this code into setup_rt_frame.
2. do_signal() also clears TS_RESTORE_SIGMASK if handle_signal()
succeeds.
We can move this to setup_rt_frame() as well, this avoids the
unnecessary checks and makes the logic more clear.
3. use set_current_blocked() instead of sigprocmask(SIG_SETMASK),
sigprocmask() should be avoided.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
arch/x86/kernel/signal.c | 29 ++++++++++-------------------
1 file changed, 10 insertions(+), 19 deletions(-)
--- ptrace/arch/x86/kernel/signal.c~2_restore_sigmask 2011-07-10 18:06:30.000000000 +0200
+++ ptrace/arch/x86/kernel/signal.c 2011-07-10 19:45:21.000000000 +0200
@@ -653,11 +653,15 @@ int ia32_setup_frame(int sig, struct k_s
static int
setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+ struct pt_regs *regs)
{
int usig = signr_convert(sig);
+ sigset_t *set = ¤t->blocked;
int ret;
+ if (current_thread_info()->status & TS_RESTORE_SIGMASK)
+ set = ¤t->saved_sigmask;
+
/* Set up the stack frame */
if (is_ia32) {
if (ka->sa.sa_flags & SA_SIGINFO)
@@ -672,12 +676,13 @@ setup_rt_frame(int sig, struct k_sigacti
return -EFAULT;
}
+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
return ret;
}
static int
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
- sigset_t *oldset, struct pt_regs *regs)
+ struct pt_regs *regs)
{
sigset_t blocked;
int ret;
@@ -712,7 +717,7 @@ handle_signal(unsigned long sig, siginfo
likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
regs->flags &= ~X86_EFLAGS_TF;
- ret = setup_rt_frame(sig, ka, info, oldset, regs);
+ ret = setup_rt_frame(sig, ka, info, regs);
if (ret)
return ret;
@@ -758,7 +763,6 @@ static void do_signal(struct pt_regs *re
struct k_sigaction ka;
siginfo_t info;
int signr;
- sigset_t *oldset;
/*
* We want the common case to go fast, which is why we may in certain
@@ -770,23 +774,10 @@ static void do_signal(struct pt_regs *re
if (!user_mode(regs))
return;
- if (current_thread_info()->status & TS_RESTORE_SIGMASK)
- oldset = ¤t->saved_sigmask;
- else
- oldset = ¤t->blocked;
-
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
/* Whee! Actually deliver the signal. */
- if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
- /*
- * A signal was successfully delivered; the saved
- * sigmask will have been stored in the signal frame,
- * and will be restored by sigreturn, so we can simply
- * clear the TS_RESTORE_SIGMASK flag.
- */
- current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
- }
+ handle_signal(signr, &info, &ka, regs);
return;
}
@@ -814,7 +805,7 @@ static void do_signal(struct pt_regs *re
*/
if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
- sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
+ set_current_blocked(¤t->saved_sigmask);
}
}
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] x86: do_signal: simplify the TS_RESTORE_SIGMASK logic
2011-07-10 18:22 [PATCH] x86: do_signal: simplify the TS_RESTORE_SIGMASK logic Oleg Nesterov
@ 2011-07-10 21:08 ` Al Viro
2011-07-11 11:39 ` Oleg Nesterov
2011-07-13 9:25 ` Matt Fleming
2011-07-15 5:47 ` [tip:x86/signal] x86, do_signal: Simplify " tip-bot for Oleg Nesterov
2 siblings, 1 reply; 6+ messages in thread
From: Al Viro @ 2011-07-10 21:08 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Andrew Morton, David Howells, David Woodhouse, Ingo Molnar,
linux-kernel
On Sun, Jul 10, 2011 at 08:22:03PM +0200, Oleg Nesterov wrote:
> 2. do_signal() also clears TS_RESTORE_SIGMASK if handle_signal()
> succeeds.
>
> We can move this to setup_rt_frame() as well, this avoids the
> unnecessary checks and makes the logic more clear.
> + current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
> return ret;
This is broken. If setup_rt_frame() fails, you don't want to do that.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] x86: do_signal: simplify the TS_RESTORE_SIGMASK logic
2011-07-10 21:08 ` Al Viro
@ 2011-07-11 11:39 ` Oleg Nesterov
0 siblings, 0 replies; 6+ messages in thread
From: Oleg Nesterov @ 2011-07-11 11:39 UTC (permalink / raw)
To: Al Viro
Cc: Andrew Morton, David Howells, David Woodhouse, Ingo Molnar,
linux-kernel
On 07/10, Al Viro wrote:
>
> On Sun, Jul 10, 2011 at 08:22:03PM +0200, Oleg Nesterov wrote:
>
> > 2. do_signal() also clears TS_RESTORE_SIGMASK if handle_signal()
> > succeeds.
> >
> > We can move this to setup_rt_frame() as well, this avoids the
> > unnecessary checks and makes the logic more clear.
>
>
> > + current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
> > return ret;
>
> This is broken.
You know, I was also going to change this "return ret", "return 0"
looks more clear to me. But then I should have renamed "ret", and
I decided to leave it alone.
> If setup_rt_frame() fails, you don't want to do that.
Sure. Please look at the code, it does
if (ret) {
force_sigsegv(sig, current);
return -EFAULT;
}
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
return ret;
We clear TS_RESTORE_SIGMASK only if we return 0.
Oleg.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] x86: do_signal: simplify the TS_RESTORE_SIGMASK logic
2011-07-10 18:22 [PATCH] x86: do_signal: simplify the TS_RESTORE_SIGMASK logic Oleg Nesterov
2011-07-10 21:08 ` Al Viro
@ 2011-07-13 9:25 ` Matt Fleming
2011-07-13 15:23 ` Oleg Nesterov
2011-07-15 5:47 ` [tip:x86/signal] x86, do_signal: Simplify " tip-bot for Oleg Nesterov
2 siblings, 1 reply; 6+ messages in thread
From: Matt Fleming @ 2011-07-13 9:25 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Andrew Morton, David Howells, David Woodhouse, Ingo Molnar,
linux-kernel
On Sun, 10 Jul 2011 20:22:03 +0200
Oleg Nesterov <oleg@redhat.com> wrote:
> 1. do_signal() looks at TS_RESTORE_SIGMASK and calculates the
> mask which should be stored in the signal frame, then it
> passes "oldset" to the callees, down to setup_rt_frame().
>
> This is ugly, setup_rt_frame() can do this itself and nobody
> else needs this sigset_t. Move this code into setup_rt_frame.
>
> 2. do_signal() also clears TS_RESTORE_SIGMASK if handle_signal()
> succeeds.
>
> We can move this to setup_rt_frame() as well, this avoids the
> unnecessary checks and makes the logic more clear.
>
> 3. use set_current_blocked() instead of sigprocmask(SIG_SETMASK),
> sigprocmask() should be avoided.
Could you please mention commit e6fa16ab "signal: sigprocmask() should
do retarget_shared_pending()", since it's not immediately obvious in
this changelog why sigprocmask() should be avoided.
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
FWIW,
Reviewed-by: Matt Fleming <matt.fleming@linux.intel.com>
--
Matt Fleming, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] x86: do_signal: simplify the TS_RESTORE_SIGMASK logic
2011-07-13 9:25 ` Matt Fleming
@ 2011-07-13 15:23 ` Oleg Nesterov
0 siblings, 0 replies; 6+ messages in thread
From: Oleg Nesterov @ 2011-07-13 15:23 UTC (permalink / raw)
To: Matt Fleming
Cc: Andrew Morton, David Howells, David Woodhouse, Ingo Molnar,
linux-kernel
On 07/13, Matt Fleming wrote:
>
> On Sun, 10 Jul 2011 20:22:03 +0200
> Oleg Nesterov <oleg@redhat.com> wrote:
>
> > 1. do_signal() looks at TS_RESTORE_SIGMASK and calculates the
> > mask which should be stored in the signal frame, then it
> > passes "oldset" to the callees, down to setup_rt_frame().
> >
> > This is ugly, setup_rt_frame() can do this itself and nobody
> > else needs this sigset_t. Move this code into setup_rt_frame.
> >
> > 2. do_signal() also clears TS_RESTORE_SIGMASK if handle_signal()
> > succeeds.
> >
> > We can move this to setup_rt_frame() as well, this avoids the
> > unnecessary checks and makes the logic more clear.
> >
> > 3. use set_current_blocked() instead of sigprocmask(SIG_SETMASK),
> > sigprocmask() should be avoided.
>
> Could you please mention commit e6fa16ab "signal: sigprocmask() should
> do retarget_shared_pending()", since it's not immediately obvious in
> this changelog why sigprocmask() should be avoided.
Well, sigprocmask(SIG_SETMASK) is fine from the correctness pov,
it calls set_current_blocked().
sigprocmask() should be avoided because it is strange interface.
It has numeruos callers, but in fact almost all of them could use
set_current_blocked() (ignoring sys_rt_sigprocmask).
Linus suggested to simply kill sigprocmask(). I am not sure, but
at least it shouldn't be abused and its last argument is confusing.
> Reviewed-by: Matt Fleming <matt.fleming@linux.intel.com>
Thanks for looking!
Oleg.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [tip:x86/signal] x86, do_signal: Simplify the TS_RESTORE_SIGMASK logic
2011-07-10 18:22 [PATCH] x86: do_signal: simplify the TS_RESTORE_SIGMASK logic Oleg Nesterov
2011-07-10 21:08 ` Al Viro
2011-07-13 9:25 ` Matt Fleming
@ 2011-07-15 5:47 ` tip-bot for Oleg Nesterov
2 siblings, 0 replies; 6+ messages in thread
From: tip-bot for Oleg Nesterov @ 2011-07-15 5:47 UTC (permalink / raw)
To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, oleg, tglx, hpa
Commit-ID: 9b429620740945363b746414e8b9a84b8119914c
Gitweb: http://git.kernel.org/tip/9b429620740945363b746414e8b9a84b8119914c
Author: Oleg Nesterov <oleg@redhat.com>
AuthorDate: Sun, 10 Jul 2011 20:22:03 +0200
Committer: H. Peter Anvin <hpa@linux.intel.com>
CommitDate: Thu, 14 Jul 2011 21:22:11 -0700
x86, do_signal: Simplify the TS_RESTORE_SIGMASK logic
1. do_signal() looks at TS_RESTORE_SIGMASK and calculates the
mask which should be stored in the signal frame, then it
passes "oldset" to the callees, down to setup_rt_frame().
This is ugly, setup_rt_frame() can do this itself and nobody
else needs this sigset_t. Move this code into setup_rt_frame.
2. do_signal() also clears TS_RESTORE_SIGMASK if handle_signal()
succeeds.
We can move this to setup_rt_frame() as well, this avoids the
unnecessary checks and makes the logic more clear.
3. use set_current_blocked() instead of sigprocmask(SIG_SETMASK),
sigprocmask() should be avoided.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Link: http://lkml.kernel.org/r/20110710182203.GA27979@redhat.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
---
arch/x86/kernel/signal.c | 29 ++++++++++-------------------
1 files changed, 10 insertions(+), 19 deletions(-)
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index bf9345d..8c55f97 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -651,11 +651,15 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
static int
setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+ struct pt_regs *regs)
{
int usig = signr_convert(sig);
+ sigset_t *set = ¤t->blocked;
int ret;
+ if (current_thread_info()->status & TS_RESTORE_SIGMASK)
+ set = ¤t->saved_sigmask;
+
/* Set up the stack frame */
if (is_ia32) {
if (ka->sa.sa_flags & SA_SIGINFO)
@@ -670,12 +674,13 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return -EFAULT;
}
+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
return ret;
}
static int
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
- sigset_t *oldset, struct pt_regs *regs)
+ struct pt_regs *regs)
{
sigset_t blocked;
int ret;
@@ -710,7 +715,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
regs->flags &= ~X86_EFLAGS_TF;
- ret = setup_rt_frame(sig, ka, info, oldset, regs);
+ ret = setup_rt_frame(sig, ka, info, regs);
if (ret)
return ret;
@@ -765,7 +770,6 @@ static void do_signal(struct pt_regs *regs)
struct k_sigaction ka;
siginfo_t info;
int signr;
- sigset_t *oldset;
/*
* We want the common case to go fast, which is why we may in certain
@@ -777,23 +781,10 @@ static void do_signal(struct pt_regs *regs)
if (!user_mode(regs))
return;
- if (current_thread_info()->status & TS_RESTORE_SIGMASK)
- oldset = ¤t->saved_sigmask;
- else
- oldset = ¤t->blocked;
-
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
/* Whee! Actually deliver the signal. */
- if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
- /*
- * A signal was successfully delivered; the saved
- * sigmask will have been stored in the signal frame,
- * and will be restored by sigreturn, so we can simply
- * clear the TS_RESTORE_SIGMASK flag.
- */
- current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
- }
+ handle_signal(signr, &info, &ka, regs);
return;
}
@@ -821,7 +812,7 @@ static void do_signal(struct pt_regs *regs)
*/
if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
- sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
+ set_current_blocked(¤t->saved_sigmask);
}
}
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-07-15 5:47 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-10 18:22 [PATCH] x86: do_signal: simplify the TS_RESTORE_SIGMASK logic Oleg Nesterov
2011-07-10 21:08 ` Al Viro
2011-07-11 11:39 ` Oleg Nesterov
2011-07-13 9:25 ` Matt Fleming
2011-07-13 15:23 ` Oleg Nesterov
2011-07-15 5:47 ` [tip:x86/signal] x86, do_signal: Simplify " tip-bot for Oleg Nesterov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox