Skip to contentSkip to conversation

FAILED: patch "[PATCH] rcu: Do RCU GP kthread self-wakeup from softirq and interrupt" failed to apply to 5.0-stable tree

PATCH [email protected] 3 participants 6 messages Mar 20, 2019 – Mar 21, 2019

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 5.0-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 1d1f898df6586c5ea9aeaf349f13089c6fa37903 Mon Sep 17 00:00:00 2001
From: "Zhang, Jun" <[email protected]>
Date: Tue, 18 Dec 2018 06:55:01 -0800
Subject: [PATCH] rcu: Do RCU GP kthread self-wakeup from softirq and interrupt

The rcu_gp_kthread_wake() function is invoked when it might be necessary to wake the RCU grace-period kthread. Because self-wakeups are normally a useless waste of CPU cycles, if rcu_gp_kthread_wake() is invoked from this kthread, it naturally refuses to do the wakeup.

Unfortunately, natural though it might be, this heuristic fails when rcu_gp_kthread_wake() is invoked from an interrupt or softirq handler that interrupted the grace-period kthread just after the final check of the wait-event condition but just before the schedule() call. In this case, a wakeup is required, even though the call to rcu_gp_kthread_wake() is within the RCU grace-period kthread's context. Failing to provide this wakeup can result in grace periods failing to start, which in turn results in out-of-memory conditions.

This race window is quite narrow, but it actually did happen during real testing. It would of course need to be fixed even if it was strictly theoretical in nature.

This patch does not Cc stable because it does not apply cleanly to earlier kernel versions.

Fixes 48a7639ce80c ("rcu: Make callers awaken grace-period kthread")

Signed-off: "Zhang, Jun" <[email protected]>
Signed-off: "He, Bo" <[email protected]>
Signed-off: "xiao, jin" <[email protected]>
Signed-off: Bai, Jie A <[email protected]>

[ paulmck: Switch from !in_softirq() to "!in_interrupt() &&
!in_serving_softirq() to avoid redundant wakeups and to also handle the interrupt-handler scenario as well as the softirq-handler scenario that actually occurred in testing. ]

kernel/rcu/tree.c +14 -6
index 9ceb93f848cd..21775eebb8f0 100644
@@ -1593,15 +1593,23 @@ static bool rcu_future_gp_cleanup(struct rcu_node *rnp)
 }
 
 /*
- * Awaken the grace-period kthread.  Don't do a self-awaken, and don't
- * bother awakening when there is nothing for the grace-period kthread
- * to do (as in several CPUs raced to awaken, and we lost), and finally
- * don't try to awaken a kthread that has not yet been created.  If
- * all those checks are passed, track some debug information and awaken.
+ * Awaken the grace-period kthread.  Don't do a self-awaken (unless in
+ * an interrupt or softirq handler), and don't bother awakening when there
+ * is nothing for the grace-period kthread to do (as in several CPUs raced
+ * to awaken, and we lost), and finally don't try to awaken a kthread that
+ * has not yet been created.  If all those checks are passed, track some
+ * debug information and awaken.
+ *
+ * So why do the self-wakeup when in an interrupt or softirq handler
+ * in the grace-period kthread's context?  Because the kthread might have
+ * been interrupted just as it was going to sleep, and just after the final
+ * pre-sleep check of the awaken condition.  In this case, a wakeup really
+ * is required, and is therefore supplied.
  */
 static void rcu_gp_kthread_wake(void)
 {
-	if (current == rcu_state.gp_kthread ||
+	if ((current == rcu_state.gp_kthread &&
+	     !in_interrupt() && !in_serving_softirq()) ||
 	    !READ_ONCE(rcu_state.gp_flags) ||
 	    !rcu_state.gp_kthread)
 		return;
#1 lore raw
Quoted 5 lines · On Wed, Mar 20, 2019 at 06:43:02PM +0100, [email protected] wrote:

The patch below does not apply to the 5.0-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

Hello, Greg,

"This patch does not Cc stable because it does not apply cleanly to earlier kernel versions." ;-)

Bo, Jin, Jie, would any of you be interested in doing the backports? I would of course be happy to review them.

Thanx, Paul

Quoted 81 lines

------------------ original commit in Linus's tree ------------------

Quoted 1 line

From 1d1f898df6586c5ea9aeaf349f13089c6fa37903 Mon Sep 17 00:00:00 2001

From: "Zhang, Jun" <[email protected]>
Date: Tue, 18 Dec 2018 06:55:01 -0800
Subject: [PATCH] rcu: Do RCU GP kthread self-wakeup from softirq and interrupt

The rcu_gp_kthread_wake() function is invoked when it might be necessary to wake the RCU grace-period kthread. Because self-wakeups are normally a useless waste of CPU cycles, if rcu_gp_kthread_wake() is invoked from this kthread, it naturally refuses to do the wakeup.

Unfortunately, natural though it might be, this heuristic fails when rcu_gp_kthread_wake() is invoked from an interrupt or softirq handler that interrupted the grace-period kthread just after the final check of the wait-event condition but just before the schedule() call. In this case, a wakeup is required, even though the call to rcu_gp_kthread_wake() is within the RCU grace-period kthread's context. Failing to provide this wakeup can result in grace periods failing to start, which in turn results in out-of-memory conditions.

This race window is quite narrow, but it actually did happen during real testing. It would of course need to be fixed even if it was strictly theoretical in nature.

This patch does not Cc stable because it does not apply cleanly to earlier kernel versions.

Fixes 48a7639ce80c ("rcu: Make callers awaken grace-period kthread")

Signed-off: "Zhang, Jun" <[email protected]>
Signed-off: "He, Bo" <[email protected]>
Signed-off: "xiao, jin" <[email protected]>
Signed-off: Bai, Jie A <[email protected]>

[ paulmck: Switch from !in_softirq() to "!in_interrupt() &&
!in_serving_softirq() to avoid redundant wakeups and to also handle the interrupt-handler scenario as well as the softirq-handler scenario that actually occurred in testing. ]

kernel/rcu/tree.c +14 -6
index 9ceb93f848cd..21775eebb8f0 100644
@@ -1593,15 +1593,23 @@ static bool rcu_future_gp_cleanup(struct rcu_node *rnp)
 }
 
 /*
- * Awaken the grace-period kthread.  Don't do a self-awaken, and don't
- * bother awakening when there is nothing for the grace-period kthread
- * to do (as in several CPUs raced to awaken, and we lost), and finally
- * don't try to awaken a kthread that has not yet been created.  If
- * all those checks are passed, track some debug information and awaken.
+ * Awaken the grace-period kthread.  Don't do a self-awaken (unless in
+ * an interrupt or softirq handler), and don't bother awakening when there
+ * is nothing for the grace-period kthread to do (as in several CPUs raced
+ * to awaken, and we lost), and finally don't try to awaken a kthread that
+ * has not yet been created.  If all those checks are passed, track some
+ * debug information and awaken.
+ *
+ * So why do the self-wakeup when in an interrupt or softirq handler
+ * in the grace-period kthread's context?  Because the kthread might have
+ * been interrupted just as it was going to sleep, and just after the final
+ * pre-sleep check of the awaken condition.  In this case, a wakeup really
+ * is required, and is therefore supplied.
  */
 static void rcu_gp_kthread_wake(void)
 {
-	if (current == rcu_state.gp_kthread ||
+	if ((current == rcu_state.gp_kthread &&
+	     !in_interrupt() && !in_serving_softirq()) ||
 	    !READ_ONCE(rcu_state.gp_flags) ||
 	    !rcu_state.gp_kthread)
 		return;
author maintainer
#2 lore raw
Quoted 11 lines · Paul E. McKenney
Quoted 5 lines · On Wed, Mar 20, 2019 at 06:43:02PM +0100, [email protected] wrote:

The patch below does not apply to the 5.0-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

Hello, Greg,

"This patch does not Cc stable because it does not apply cleanly to earlier kernel versions." ;-)

I know, that's why I sent out these emails to remind people about it :)

Quoted 2 lines

Bo, Jin, Jie, would any of you be interested in doing the backports? I would of course be happy to review them.

That would be most wonderful, thanks!

greg k-h

#3 lore raw
Quoted 8 lines · Greg KH
Quoted 7 lines · Paul E. McKenney
Quoted 5 lines · On Wed, Mar 20, 2019 at 06:43:02PM +0100, [email protected] wrote:

The patch below does not apply to the 5.0-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

Quoted 6 lines
Quoted 4 lines

Hello, Greg,

"This patch does not Cc stable because it does not apply cleanly to earlier kernel versions." ;-)

I know, that's why I sent out these emails to remind people about it :)

Fair enough! ;-)

Thanx, Paul

Quoted 7 lines
Quoted 2 lines

Bo, Jin, Jie, would any of you be interested in doing the backports? I would of course be happy to review them.

That would be most wonderful, thanks!

greg k-h

#4 lore raw

sure, we have backported the patch to lts4.19 in intel local branch, and will also send out the backport patches for other LTS.

-----Original Message-----
From: Paul E. McKenney <[email protected]>
Sent: Thursday, March 21, 2019 2:34 AM
To: Greg KH <[email protected]>
Cc: Zhang, Jun <[email protected]>; He, Bo <[email protected]>; Bai, Jie A <[email protected]>; Xiao, Jin <[email protected]>; [email protected]
Subject: Re: FAILED: patch "[PATCH] rcu: Do RCU GP kthread self-wakeup from softirq and interrupt" failed to apply to 5.0-stable tree

Quoted 8 lines · Greg KH
Quoted 7 lines · Paul E. McKenney
Quoted 5 lines · On Wed, Mar 20, 2019 at 06:43:02PM +0100, [email protected] wrote:

The patch below does not apply to the 5.0-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

Quoted 7 lines
Quoted 4 lines

Hello, Greg,

"This patch does not Cc stable because it does not apply cleanly to earlier kernel versions." ;-)

I know, that's why I sent out these emails to remind people about it :)

Fair enough! ;-)

Thanx, Paul

Quoted 7 lines
Quoted 2 lines

Bo, Jin, Jie, would any of you be interested in doing the backports? I would of course be happy to review them.

That would be most wonderful, thanks!

greg k-h

#5 lore raw
In reply to [email protected]

The rcu_gp_kthread_wake() function is invoked when it might be necessary to wake the RCU grace-period kthread. Because self-wakeups are normally a useless waste of CPU cycles, if rcu_gp_kthread_wake() is invoked from this kthread, it naturally refuses to do the wakeup.

Unfortunately, natural though it might be, this heuristic fails when rcu_gp_kthread_wake() is invoked from an interrupt or softirq handler that interrupted the grace-period kthread just after the final check of the wait-event condition but just before the schedule() call. In this case, a wakeup is required, even though the call to rcu_gp_kthread_wake() is within the RCU grace-period kthread's context. Failing to provide this wakeup can result in grace periods failing to start, which in turn results in out-of-memory conditions.

This race window is quite narrow, but it actually did happen during real testing. It would of course need to be fixed even if it was strictly theoretical in nature.

[ backport for 5.0 commit 1d1f898df6586c5ea9aeaf349f13089c6fa37903 upstream. ]

Fixes 48a7639ce80c ("rcu: Make callers awaken grace-period kthread")

Signed-off: "Zhang, Jun" <[email protected]>
Signed-off: "He, Bo" <[email protected]>
Signed-off: "xiao, jin" <[email protected]>
Signed-off: Bai, Jie A <[email protected]>

[ paulmck: Switch from !in_softirq() to "!in_interrupt() &&
!in_serving_softirq() to avoid redundant wakeups and to also handle the interrupt-handler scenario as well as the softirq-handler scenario that actually occurred in testing. ]

---
 kernel/rcu/tree.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)
kernel/rcu/tree.c +14 -5
index 9180158756d2..38d44d27e37a 100644
@@ -1557,14 +1557,23 @@ static bool rcu_future_gp_cleanup(struct rcu_node *rnp)
 }
 
 /*
- * Awaken the grace-period kthread.  Don't do a self-awaken, and don't
- * bother awakening when there is nothing for the grace-period kthread
- * to do (as in several CPUs raced to awaken, and we lost), and finally
- * don't try to awaken a kthread that has not yet been created.
+ * Awaken the grace-period kthread.  Don't do a self-awaken (unless in
+ * an interrupt or softirq handler), and don't bother awakening when there
+ * is nothing for the grace-period kthread to do (as in several CPUs raced
+ * to awaken, and we lost), and finally don't try to awaken a kthread that
+ * has not yet been created.  If all those checks are passed, track some
+ * debug information and awaken.
+ *
+ * So why do the self-wakeup when in an interrupt or softirq handler
+ * in the grace-period kthread's context?  Because the kthread might have
+ * been interrupted just as it was going to sleep, and just after the final
+ * pre-sleep check of the awaken condition.  In this case, a wakeup really
+ * is required, and is therefore supplied.
  */
 static void rcu_gp_kthread_wake(void)
 {
-	if (current == rcu_state.gp_kthread ||
+	if ((current == rcu_state.gp_kthread &&
+	     !in_interrupt() && !in_serving_softirq()) ||
 	    !READ_ONCE(rcu_state.gp_flags) ||
 	    !rcu_state.gp_kthread)
 		return;
Signature · 1 line
2.20.1

-----Original Message-----
From: [email protected] <[email protected]>
Sent: Thursday, March 21, 2019 1:43 AM
To: Zhang, Jun <[email protected]>; He, Bo <[email protected]>; Bai, Jie A <[email protected]>; Xiao, Jin <[email protected]>; [email protected]
Cc: [email protected]
Subject: FAILED: patch "[PATCH] rcu: Do RCU GP kthread self-wakeup from softirq and interrupt" failed to apply to 5.0-stable tree

The patch below does not apply to the 5.0-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 1d1f898df6586c5ea9aeaf349f13089c6fa37903 Mon Sep 17 00:00:00 2001
From: "Zhang, Jun" <[email protected]>
Date: Tue, 18 Dec 2018 06:55:01 -0800
Subject: [PATCH] rcu: Do RCU GP kthread self-wakeup from softirq and interrupt

The rcu_gp_kthread_wake() function is invoked when it might be necessary to wake the RCU grace-period kthread. Because self-wakeups are normally a useless waste of CPU cycles, if rcu_gp_kthread_wake() is invoked from this kthread, it naturally refuses to do the wakeup.

Unfortunately, natural though it might be, this heuristic fails when
rcu_gp_kthread_wake() is invoked from an interrupt or softirq handler that interrupted the grace-period kthread just after the final check of the wait-event condition but just before the schedule() call. In this case, a wakeup is required, even though the call to rcu_gp_kthread_wake() is within the RCU grace-period kthread's context. Failing to provide this wakeup can result in grace periods failing to start, which in turn results in out-of-memory conditions.

This race window is quite narrow, but it actually did happen during real testing. It would of course need to be fixed even if it was strictly theoretical in nature.

This patch does not Cc stable because it does not apply cleanly to earlier kernel versions.

Fixes 48a7639ce80c ("rcu: Make callers awaken grace-period kthread")

Signed-off: "Zhang, Jun" <[email protected]>
Signed-off: "He, Bo" <[email protected]>
Signed-off: "xiao, jin" <[email protected]>
Signed-off: Bai, Jie A <[email protected]>

!in_serving_softirq() to avoid redundant wakeups and to also handle the interrupt-handler scenario as well as the softirq-handler scenario that actually occurred in testing. ]

kernel/rcu/tree.c +19 -5
@@ -1593,15 +1593,23 @@ static bool rcu_future_gp_cleanup(struct rcu_node *rnp)  }
 
 /*
- * Awaken the grace-period kthread.  Don't do a self-awaken, and don't
- * bother awakening when there is nothing for the grace-period kthread
- * to do (as in several CPUs raced to awaken, and we lost), and finally
- * don't try to awaken a kthread that has not yet been created.  If
- * all those checks are passed, track some debug information and awaken.
+ * Awaken the grace-period kthread.  Don't do a self-awaken (unless in
+ * an interrupt or softirq handler), and don't bother awakening when 
+ there
+ * is nothing for the grace-period kthread to do (as in several CPUs 
+ raced
+ * to awaken, and we lost), and finally don't try to awaken a kthread 
+ that
+ * has not yet been created.  If all those checks are passed, track 
+ some
+ * debug information and awaken.
+ *
+ * So why do the self-wakeup when in an interrupt or softirq handler
+ * in the grace-period kthread's context?  Because the kthread might 
+ have
+ * been interrupted just as it was going to sleep, and just after the 
+ final
+ * pre-sleep check of the awaken condition.  In this case, a wakeup 
+ really
+ * is required, and is therefore supplied.
  */
 static void rcu_gp_kthread_wake(void)

{
- if (current == rcu_state.gp_kthread ||
+ if ((current == rcu_state.gp_kthread &&
+ !in_interrupt() && !in_serving_softirq()) ||
!READ_ONCE(rcu_state.gp_flags) ||
!rcu_state.gp_kthread)
return;