linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Sasha Levin <sasha.levin@oracle.com>,
	linux-kernel@vger.kernel.org, mingo@kernel.org
Subject: Re: [PATCH] signals: work around random wakeups in sigsuspend()
Date: Wed, 27 Jan 2016 17:41:54 +0100	[thread overview]
Message-ID: <20160127164154.GB14320@redhat.com> (raw)
In-Reply-To: <20160127084443.GL6357@twins.programming.kicks-ass.net>

On 01/27, Peter Zijlstra wrote:
>
> On Tue, Jan 26, 2016 at 10:10:09PM +0100, Oleg Nesterov wrote:
>
> > And, ironically, there is another more serious "reverse" problem ;) sigsuspend()
> > orany other user of -ERESTARTNOHAND can "miss" the signal, in a sense that the
> > kernel can wrongly restart this syscall after return from signal handler. This
> > is not trivial to fix..
>
> So I'm not entirely sure I get what you mean there.

Yes, sorry. When I re-read my email it really looks like "I know the secret but I
won't tell you" ;)

The problem is simple, the fix is not. -ERESTARTNOHAND means that we should restart
if do_signal()->get_signal() returns zero. This can happen when, say, another thread
has already dequeued the group-wide signal which was the reason for TIF_SIGPENDING.
Or signal_pending() was true because of debuger, or another reason, doesn't matter.

In this case do_signal() does

			regs->ax = regs->orig_ax;
			regs->ip -= 2;

and we return to user space. Note that after that the kernel can't know that the
task is going to restart the syscall which should be interrupted by signals.

Now suppose that another signal (with the handler) comes before this task executes
the "syscall" insn. In this case sigsuspend() will restart after the task runs the
handler.

> But it did get me to
> look at the patch again:
>
> +       while (!signal_pending(current)) {
> +               __set_current_state(TASK_INTERRUPTIBLE);
> +               schedule();
> +       }
>
> That should very much be:
>
> 	for (;;) {
> 		set_current_state(TASK_INTERRUPTIBLE);
> 		if (signal_pending(current))
> 			break;
> 		schedule();
> 	}
> 	__set_current_state(TASK_RUNNING);

Why? It should work either way. Yes, signal_wakeup() can come right before
__set_current_state(TASK_INTERRUPTIBLE) but this is fine, __schedule() must not
sleep if signal_pending() == T, that is why it checks signal_pending_state().
See also the comment above smp_mb__before_spinlock() in schedule().

IOW, signal_pending() is the "special" condition, you do not need to serialize
this check with task->state setting, exactly because schedule() knows about the
signals.

Oleg.

  reply	other threads:[~2016-01-27 16:42 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-25 15:21 [PATCH] signals: work around random wakeups in sigsuspend() Sasha Levin
2016-01-25 19:09 ` Oleg Nesterov
2016-01-25 19:37   ` Peter Zijlstra
2016-02-25  3:18   ` Al Viro
2016-02-25  8:11     ` Peter Zijlstra
2016-02-25 17:34       ` Al Viro
2016-01-25 21:32 ` Andrew Morton
2016-01-26 21:10   ` Oleg Nesterov
2016-01-27  8:44     ` Peter Zijlstra
2016-01-27 16:41       ` Oleg Nesterov [this message]
2016-01-27 17:54         ` Peter Zijlstra
2016-01-27 18:39         ` Andrew Morton
2016-01-27 21:07           ` Oleg Nesterov
2016-01-27 17:24       ` Sasha Levin
2016-01-26  6:44 ` Ingo Molnar
2016-01-26 15:05   ` Oleg Nesterov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160127164154.GB14320@redhat.com \
    --to=oleg@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=sasha.levin@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).