public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH tip/core/rcu 0/2] Signal-related changes for 3.19
@ 2014-10-28 22:13 Paul E. McKenney
  2014-10-28 22:13 ` [PATCH tip/core/rcu 1/2] signal: Exit RCU read-side critical section on each pass through loop Paul E. McKenney
  2014-10-29  2:13 ` [PATCH tip/core/rcu 0/2] Signal-related changes for 3.19 Pranith Kumar
  0 siblings, 2 replies; 4+ messages in thread
From: Paul E. McKenney @ 2014-10-28 22:13 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, tglx,
	peterz, rostedt, dhowells, edumazet, dvhart, fweisbec, oleg,
	bobby.prani

Hello!

This series updates RCU handling in signals:

1.	Prevents a possible very long RCU read-side critical section
	in kill_pid_info().

2.	Explain why the "obviously buggy" freeing of sighand by
	__cleanup_sighand() without an RCU grace period really isn't
	buggy, courtesy of Oleg Nesterov.

							Thanx, Paul

------------------------------------------------------------------------

 b/kernel/fork.c   |    5 ++++-
 b/kernel/signal.c |   42 +++++++++++++++++++++++++-----------------
 2 files changed, 29 insertions(+), 18 deletions(-)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH tip/core/rcu 1/2] signal: Exit RCU read-side critical section on each pass through loop
  2014-10-28 22:13 [PATCH tip/core/rcu 0/2] Signal-related changes for 3.19 Paul E. McKenney
@ 2014-10-28 22:13 ` Paul E. McKenney
  2014-10-28 22:13   ` [PATCH tip/core/rcu 2/2] signal: Document the RCU protection of ->sighand Paul E. McKenney
  2014-10-29  2:13 ` [PATCH tip/core/rcu 0/2] Signal-related changes for 3.19 Pranith Kumar
  1 sibling, 1 reply; 4+ messages in thread
From: Paul E. McKenney @ 2014-10-28 22:13 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, tglx,
	peterz, rostedt, dhowells, edumazet, dvhart, fweisbec, oleg,
	bobby.prani, Paul E. McKenney

From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>

The kill_pid_info() can potentially loop indefinitely if tasks are created
and deleted sufficiently quickly, and if this happens, this function
will remain in a single RCU read-side critical section indefinitely.
This commit therefore exits the RCU read-side critical section on each
pass through the loop.  Because a race must happen to retry the loop,
this should have no performance impact in the common case.

Reported-by: Dave Jones <davej@redhat.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/signal.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index 8f0876f9f6dd..54820984a872 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1331,23 +1331,21 @@ int kill_pid_info(int sig, struct siginfo *info, struct pid *pid)
 	int error = -ESRCH;
 	struct task_struct *p;
 
-	rcu_read_lock();
-retry:
-	p = pid_task(pid, PIDTYPE_PID);
-	if (p) {
-		error = group_send_sig_info(sig, info, p);
-		if (unlikely(error == -ESRCH))
-			/*
-			 * The task was unhashed in between, try again.
-			 * If it is dead, pid_task() will return NULL,
-			 * if we race with de_thread() it will find the
-			 * new leader.
-			 */
-			goto retry;
-	}
-	rcu_read_unlock();
+	for (;;) {
+		rcu_read_lock();
+		p = pid_task(pid, PIDTYPE_PID);
+		if (p)
+			error = group_send_sig_info(sig, info, p);
+		rcu_read_unlock();
+		if (likely(!p || error != -ESRCH))
+			return error;
 
-	return error;
+		/*
+		 * The task was unhashed in between, try again.  If it
+		 * is dead, pid_task() will return NULL, if we race with
+		 * de_thread() it will find the new leader.
+		 */
+	}
 }
 
 int kill_proc_info(int sig, struct siginfo *info, pid_t pid)
-- 
1.8.1.5


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH tip/core/rcu 2/2] signal: Document the RCU protection of ->sighand
  2014-10-28 22:13 ` [PATCH tip/core/rcu 1/2] signal: Exit RCU read-side critical section on each pass through loop Paul E. McKenney
@ 2014-10-28 22:13   ` Paul E. McKenney
  0 siblings, 0 replies; 4+ messages in thread
From: Paul E. McKenney @ 2014-10-28 22:13 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, tglx,
	peterz, rostedt, dhowells, edumazet, dvhart, fweisbec, oleg,
	bobby.prani, Paul E. McKenney

From: Oleg Nesterov <oleg@redhat.com>

__cleanup_sighand() frees sighand without RCU grace period. This is
correct but this looks "obviously buggy" and constantly confuses the
readers, add the comments to explain how this works.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Reviewed-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
 kernel/fork.c   |  5 ++++-
 kernel/signal.c | 12 +++++++++++-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/kernel/fork.c b/kernel/fork.c
index 9b7d746d6d62..9ca84189cfc2 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1022,11 +1022,14 @@ void __cleanup_sighand(struct sighand_struct *sighand)
 {
 	if (atomic_dec_and_test(&sighand->count)) {
 		signalfd_cleanup(sighand);
+		/*
+		 * sighand_cachep is SLAB_DESTROY_BY_RCU so we can free it
+		 * without an RCU grace period, see __lock_task_sighand().
+		 */
 		kmem_cache_free(sighand_cachep, sighand);
 	}
 }
 
-
 /*
  * Initialize POSIX timer handling for a thread group.
  */
diff --git a/kernel/signal.c b/kernel/signal.c
index 54820984a872..19e35135fc60 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1275,7 +1275,17 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
 			local_irq_restore(*flags);
 			break;
 		}
-
+		/*
+		 * This sighand can be already freed and even reused, but
+		 * we rely on SLAB_DESTROY_BY_RCU and sighand_ctor() which
+		 * initializes ->siglock: this slab can't go away, it has
+		 * the same object type, ->siglock can't be reinitialized.
+		 *
+		 * We need to ensure that tsk->sighand is still the same
+		 * after we take the lock, we can race with de_thread() or
+		 * __exit_signal(). In the latter case the next iteration
+		 * must see ->sighand == NULL.
+		 */
 		spin_lock(&sighand->siglock);
 		if (likely(sighand == tsk->sighand)) {
 			rcu_read_unlock();
-- 
1.8.1.5


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH tip/core/rcu 0/2] Signal-related changes for 3.19
  2014-10-28 22:13 [PATCH tip/core/rcu 0/2] Signal-related changes for 3.19 Paul E. McKenney
  2014-10-28 22:13 ` [PATCH tip/core/rcu 1/2] signal: Exit RCU read-side critical section on each pass through loop Paul E. McKenney
@ 2014-10-29  2:13 ` Pranith Kumar
  1 sibling, 0 replies; 4+ messages in thread
From: Pranith Kumar @ 2014-10-29  2:13 UTC (permalink / raw)
  To: Paul McKenney
  Cc: LKML, Ingo Molnar, Lai Jiangshan, Dipankar Sarma, Andrew Morton,
	Mathieu Desnoyers, Josh Triplett, Thomas Gleixner, Peter Zijlstra,
	Steven Rostedt, David Howells, Eric Dumazet, dvhart,
	Frédéric Weisbecker, Oleg Nesterov

On Tue, Oct 28, 2014 at 6:13 PM, Paul E. McKenney
<paulmck@linux.vnet.ibm.com> wrote:
> Hello!
>
> This series updates RCU handling in signals:
>
> 1.      Prevents a possible very long RCU read-side critical section
>         in kill_pid_info().
>
> 2.      Explain why the "obviously buggy" freeing of sighand by
>         __cleanup_sighand() without an RCU grace period really isn't
>         buggy, courtesy of Oleg Nesterov.


Reviewed-by: Pranith Kumar <bobby.prani@gmail.com>

>
>                                                         Thanx, Paul
>
> ------------------------------------------------------------------------
>
>  b/kernel/fork.c   |    5 ++++-
>  b/kernel/signal.c |   42 +++++++++++++++++++++++++-----------------
>  2 files changed, 29 insertions(+), 18 deletions(-)
>



-- 
Pranith

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-10-29  2:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-28 22:13 [PATCH tip/core/rcu 0/2] Signal-related changes for 3.19 Paul E. McKenney
2014-10-28 22:13 ` [PATCH tip/core/rcu 1/2] signal: Exit RCU read-side critical section on each pass through loop Paul E. McKenney
2014-10-28 22:13   ` [PATCH tip/core/rcu 2/2] signal: Document the RCU protection of ->sighand Paul E. McKenney
2014-10-29  2:13 ` [PATCH tip/core/rcu 0/2] Signal-related changes for 3.19 Pranith Kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox