Re: [PATCH tip/core/rcu 02/15] rcu: Pull TINY_RCU dyntick-idle tracing into non-idle region

2012-08-31 Thread Josh Triplett
On Thu, Aug 30, 2012 at 11:56:15AM -0700, Paul E. McKenney wrote:
> From: "Paul E. McKenney" 
> 
> Because TINY_RCU's idle detection keys directly off of the nesting
> level, rather than from a separate variable as in TREE_RCU, the
> TINY_RCU dyntick-idle tracing on transition to idle must happen
> before the change to the nesting level.  This commit therefore makes
> this change by passing the desired new value (rather than the old value)
> of the nesting level in to rcu_idle_enter_common().
> 
> [ paulmck: Add fix for wrong-variable bug spotted by
>   Michael Wang . ]
> 
> Signed-off-by: Paul E. McKenney 
> Signed-off-by: Paul E. McKenney 

Reviewed-by: Josh Triplett 

> ---
>  kernel/rcutiny.c |   31 ---
>  1 files changed, 16 insertions(+), 15 deletions(-)
> 
> diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
> index 547b1fe..e4163c5 100644
> --- a/kernel/rcutiny.c
> +++ b/kernel/rcutiny.c
> @@ -56,24 +56,27 @@ static void __call_rcu(struct rcu_head *head,
>  static long long rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
>  
>  /* Common code for rcu_idle_enter() and rcu_irq_exit(), see 
> kernel/rcutree.c. */
> -static void rcu_idle_enter_common(long long oldval)
> +static void rcu_idle_enter_common(long long newval)
>  {
> - if (rcu_dynticks_nesting) {
> + if (newval) {
>   RCU_TRACE(trace_rcu_dyntick("--=",
> - oldval, rcu_dynticks_nesting));
> + rcu_dynticks_nesting, newval));
> + rcu_dynticks_nesting = newval;
>   return;
>   }
> - RCU_TRACE(trace_rcu_dyntick("Start", oldval, rcu_dynticks_nesting));
> + RCU_TRACE(trace_rcu_dyntick("Start", rcu_dynticks_nesting, newval));
>   if (!is_idle_task(current)) {
>   struct task_struct *idle = idle_task(smp_processor_id());
>  
>   RCU_TRACE(trace_rcu_dyntick("Error on entry: not idle task",
> - oldval, rcu_dynticks_nesting));
> + rcu_dynticks_nesting, newval));
>   ftrace_dump(DUMP_ALL);
>   WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
> current->pid, current->comm,
> idle->pid, idle->comm); /* must be idle task! */
>   }
> + barrier();
> + rcu_dynticks_nesting = newval;
>   rcu_sched_qs(0); /* implies rcu_bh_qsctr_inc(0) */
>  }
>  
> @@ -84,17 +87,16 @@ static void rcu_idle_enter_common(long long oldval)
>  void rcu_idle_enter(void)
>  {
>   unsigned long flags;
> - long long oldval;
> + long long newval;
>  
>   local_irq_save(flags);
> - oldval = rcu_dynticks_nesting;
>   WARN_ON_ONCE((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) == 0);
>   if ((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) ==
>   DYNTICK_TASK_NEST_VALUE)
> - rcu_dynticks_nesting = 0;
> + newval = 0;
>   else
> - rcu_dynticks_nesting  -= DYNTICK_TASK_NEST_VALUE;
> - rcu_idle_enter_common(oldval);
> + newval = rcu_dynticks_nesting - DYNTICK_TASK_NEST_VALUE;
> + rcu_idle_enter_common(newval);
>   local_irq_restore(flags);
>  }
>  EXPORT_SYMBOL_GPL(rcu_idle_enter);
> @@ -105,13 +107,12 @@ EXPORT_SYMBOL_GPL(rcu_idle_enter);
>  void rcu_irq_exit(void)
>  {
>   unsigned long flags;
> - long long oldval;
> + long long newval;
>  
>   local_irq_save(flags);
> - oldval = rcu_dynticks_nesting;
> - rcu_dynticks_nesting--;
> - WARN_ON_ONCE(rcu_dynticks_nesting < 0);
> - rcu_idle_enter_common(oldval);
> + newval = rcu_dynticks_nesting - 1;
> + WARN_ON_ONCE(newval < 0);
> + rcu_idle_enter_common(newval);
>   local_irq_restore(flags);
>  }
>  
> -- 
> 1.7.8
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH tip/core/rcu 02/15] rcu: Pull TINY_RCU dyntick-idle tracing into non-idle region

2012-08-31 Thread Josh Triplett
On Thu, Aug 30, 2012 at 11:56:15AM -0700, Paul E. McKenney wrote:
 From: Paul E. McKenney paul.mcken...@linaro.org
 
 Because TINY_RCU's idle detection keys directly off of the nesting
 level, rather than from a separate variable as in TREE_RCU, the
 TINY_RCU dyntick-idle tracing on transition to idle must happen
 before the change to the nesting level.  This commit therefore makes
 this change by passing the desired new value (rather than the old value)
 of the nesting level in to rcu_idle_enter_common().
 
 [ paulmck: Add fix for wrong-variable bug spotted by
   Michael Wang wang...@linux.vnet.ibm.com. ]
 
 Signed-off-by: Paul E. McKenney paul.mcken...@linaro.org
 Signed-off-by: Paul E. McKenney paul...@linux.vnet.ibm.com

Reviewed-by: Josh Triplett j...@joshtriplett.org

 ---
  kernel/rcutiny.c |   31 ---
  1 files changed, 16 insertions(+), 15 deletions(-)
 
 diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
 index 547b1fe..e4163c5 100644
 --- a/kernel/rcutiny.c
 +++ b/kernel/rcutiny.c
 @@ -56,24 +56,27 @@ static void __call_rcu(struct rcu_head *head,
  static long long rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
  
  /* Common code for rcu_idle_enter() and rcu_irq_exit(), see 
 kernel/rcutree.c. */
 -static void rcu_idle_enter_common(long long oldval)
 +static void rcu_idle_enter_common(long long newval)
  {
 - if (rcu_dynticks_nesting) {
 + if (newval) {
   RCU_TRACE(trace_rcu_dyntick(--=,
 - oldval, rcu_dynticks_nesting));
 + rcu_dynticks_nesting, newval));
 + rcu_dynticks_nesting = newval;
   return;
   }
 - RCU_TRACE(trace_rcu_dyntick(Start, oldval, rcu_dynticks_nesting));
 + RCU_TRACE(trace_rcu_dyntick(Start, rcu_dynticks_nesting, newval));
   if (!is_idle_task(current)) {
   struct task_struct *idle = idle_task(smp_processor_id());
  
   RCU_TRACE(trace_rcu_dyntick(Error on entry: not idle task,
 - oldval, rcu_dynticks_nesting));
 + rcu_dynticks_nesting, newval));
   ftrace_dump(DUMP_ALL);
   WARN_ONCE(1, Current pid: %d comm: %s / Idle pid: %d comm: %s,
 current-pid, current-comm,
 idle-pid, idle-comm); /* must be idle task! */
   }
 + barrier();
 + rcu_dynticks_nesting = newval;
   rcu_sched_qs(0); /* implies rcu_bh_qsctr_inc(0) */
  }
  
 @@ -84,17 +87,16 @@ static void rcu_idle_enter_common(long long oldval)
  void rcu_idle_enter(void)
  {
   unsigned long flags;
 - long long oldval;
 + long long newval;
  
   local_irq_save(flags);
 - oldval = rcu_dynticks_nesting;
   WARN_ON_ONCE((rcu_dynticks_nesting  DYNTICK_TASK_NEST_MASK) == 0);
   if ((rcu_dynticks_nesting  DYNTICK_TASK_NEST_MASK) ==
   DYNTICK_TASK_NEST_VALUE)
 - rcu_dynticks_nesting = 0;
 + newval = 0;
   else
 - rcu_dynticks_nesting  -= DYNTICK_TASK_NEST_VALUE;
 - rcu_idle_enter_common(oldval);
 + newval = rcu_dynticks_nesting - DYNTICK_TASK_NEST_VALUE;
 + rcu_idle_enter_common(newval);
   local_irq_restore(flags);
  }
  EXPORT_SYMBOL_GPL(rcu_idle_enter);
 @@ -105,13 +107,12 @@ EXPORT_SYMBOL_GPL(rcu_idle_enter);
  void rcu_irq_exit(void)
  {
   unsigned long flags;
 - long long oldval;
 + long long newval;
  
   local_irq_save(flags);
 - oldval = rcu_dynticks_nesting;
 - rcu_dynticks_nesting--;
 - WARN_ON_ONCE(rcu_dynticks_nesting  0);
 - rcu_idle_enter_common(oldval);
 + newval = rcu_dynticks_nesting - 1;
 + WARN_ON_ONCE(newval  0);
 + rcu_idle_enter_common(newval);
   local_irq_restore(flags);
  }
  
 -- 
 1.7.8
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH tip/core/rcu 02/15] rcu: Pull TINY_RCU dyntick-idle tracing into non-idle region

2012-08-30 Thread Paul E. McKenney
From: "Paul E. McKenney" 

Because TINY_RCU's idle detection keys directly off of the nesting
level, rather than from a separate variable as in TREE_RCU, the
TINY_RCU dyntick-idle tracing on transition to idle must happen
before the change to the nesting level.  This commit therefore makes
this change by passing the desired new value (rather than the old value)
of the nesting level in to rcu_idle_enter_common().

[ paulmck: Add fix for wrong-variable bug spotted by
  Michael Wang . ]

Signed-off-by: Paul E. McKenney 
Signed-off-by: Paul E. McKenney 
---
 kernel/rcutiny.c |   31 ---
 1 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
index 547b1fe..e4163c5 100644
--- a/kernel/rcutiny.c
+++ b/kernel/rcutiny.c
@@ -56,24 +56,27 @@ static void __call_rcu(struct rcu_head *head,
 static long long rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
 
 /* Common code for rcu_idle_enter() and rcu_irq_exit(), see kernel/rcutree.c. 
*/
-static void rcu_idle_enter_common(long long oldval)
+static void rcu_idle_enter_common(long long newval)
 {
-   if (rcu_dynticks_nesting) {
+   if (newval) {
RCU_TRACE(trace_rcu_dyntick("--=",
-   oldval, rcu_dynticks_nesting));
+   rcu_dynticks_nesting, newval));
+   rcu_dynticks_nesting = newval;
return;
}
-   RCU_TRACE(trace_rcu_dyntick("Start", oldval, rcu_dynticks_nesting));
+   RCU_TRACE(trace_rcu_dyntick("Start", rcu_dynticks_nesting, newval));
if (!is_idle_task(current)) {
struct task_struct *idle = idle_task(smp_processor_id());
 
RCU_TRACE(trace_rcu_dyntick("Error on entry: not idle task",
-   oldval, rcu_dynticks_nesting));
+   rcu_dynticks_nesting, newval));
ftrace_dump(DUMP_ALL);
WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
  current->pid, current->comm,
  idle->pid, idle->comm); /* must be idle task! */
}
+   barrier();
+   rcu_dynticks_nesting = newval;
rcu_sched_qs(0); /* implies rcu_bh_qsctr_inc(0) */
 }
 
@@ -84,17 +87,16 @@ static void rcu_idle_enter_common(long long oldval)
 void rcu_idle_enter(void)
 {
unsigned long flags;
-   long long oldval;
+   long long newval;
 
local_irq_save(flags);
-   oldval = rcu_dynticks_nesting;
WARN_ON_ONCE((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) == 0);
if ((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) ==
DYNTICK_TASK_NEST_VALUE)
-   rcu_dynticks_nesting = 0;
+   newval = 0;
else
-   rcu_dynticks_nesting  -= DYNTICK_TASK_NEST_VALUE;
-   rcu_idle_enter_common(oldval);
+   newval = rcu_dynticks_nesting - DYNTICK_TASK_NEST_VALUE;
+   rcu_idle_enter_common(newval);
local_irq_restore(flags);
 }
 EXPORT_SYMBOL_GPL(rcu_idle_enter);
@@ -105,13 +107,12 @@ EXPORT_SYMBOL_GPL(rcu_idle_enter);
 void rcu_irq_exit(void)
 {
unsigned long flags;
-   long long oldval;
+   long long newval;
 
local_irq_save(flags);
-   oldval = rcu_dynticks_nesting;
-   rcu_dynticks_nesting--;
-   WARN_ON_ONCE(rcu_dynticks_nesting < 0);
-   rcu_idle_enter_common(oldval);
+   newval = rcu_dynticks_nesting - 1;
+   WARN_ON_ONCE(newval < 0);
+   rcu_idle_enter_common(newval);
local_irq_restore(flags);
 }
 
-- 
1.7.8

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH tip/core/rcu 02/15] rcu: Pull TINY_RCU dyntick-idle tracing into non-idle region

2012-08-30 Thread Paul E. McKenney
From: Paul E. McKenney paul.mcken...@linaro.org

Because TINY_RCU's idle detection keys directly off of the nesting
level, rather than from a separate variable as in TREE_RCU, the
TINY_RCU dyntick-idle tracing on transition to idle must happen
before the change to the nesting level.  This commit therefore makes
this change by passing the desired new value (rather than the old value)
of the nesting level in to rcu_idle_enter_common().

[ paulmck: Add fix for wrong-variable bug spotted by
  Michael Wang wang...@linux.vnet.ibm.com. ]

Signed-off-by: Paul E. McKenney paul.mcken...@linaro.org
Signed-off-by: Paul E. McKenney paul...@linux.vnet.ibm.com
---
 kernel/rcutiny.c |   31 ---
 1 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
index 547b1fe..e4163c5 100644
--- a/kernel/rcutiny.c
+++ b/kernel/rcutiny.c
@@ -56,24 +56,27 @@ static void __call_rcu(struct rcu_head *head,
 static long long rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
 
 /* Common code for rcu_idle_enter() and rcu_irq_exit(), see kernel/rcutree.c. 
*/
-static void rcu_idle_enter_common(long long oldval)
+static void rcu_idle_enter_common(long long newval)
 {
-   if (rcu_dynticks_nesting) {
+   if (newval) {
RCU_TRACE(trace_rcu_dyntick(--=,
-   oldval, rcu_dynticks_nesting));
+   rcu_dynticks_nesting, newval));
+   rcu_dynticks_nesting = newval;
return;
}
-   RCU_TRACE(trace_rcu_dyntick(Start, oldval, rcu_dynticks_nesting));
+   RCU_TRACE(trace_rcu_dyntick(Start, rcu_dynticks_nesting, newval));
if (!is_idle_task(current)) {
struct task_struct *idle = idle_task(smp_processor_id());
 
RCU_TRACE(trace_rcu_dyntick(Error on entry: not idle task,
-   oldval, rcu_dynticks_nesting));
+   rcu_dynticks_nesting, newval));
ftrace_dump(DUMP_ALL);
WARN_ONCE(1, Current pid: %d comm: %s / Idle pid: %d comm: %s,
  current-pid, current-comm,
  idle-pid, idle-comm); /* must be idle task! */
}
+   barrier();
+   rcu_dynticks_nesting = newval;
rcu_sched_qs(0); /* implies rcu_bh_qsctr_inc(0) */
 }
 
@@ -84,17 +87,16 @@ static void rcu_idle_enter_common(long long oldval)
 void rcu_idle_enter(void)
 {
unsigned long flags;
-   long long oldval;
+   long long newval;
 
local_irq_save(flags);
-   oldval = rcu_dynticks_nesting;
WARN_ON_ONCE((rcu_dynticks_nesting  DYNTICK_TASK_NEST_MASK) == 0);
if ((rcu_dynticks_nesting  DYNTICK_TASK_NEST_MASK) ==
DYNTICK_TASK_NEST_VALUE)
-   rcu_dynticks_nesting = 0;
+   newval = 0;
else
-   rcu_dynticks_nesting  -= DYNTICK_TASK_NEST_VALUE;
-   rcu_idle_enter_common(oldval);
+   newval = rcu_dynticks_nesting - DYNTICK_TASK_NEST_VALUE;
+   rcu_idle_enter_common(newval);
local_irq_restore(flags);
 }
 EXPORT_SYMBOL_GPL(rcu_idle_enter);
@@ -105,13 +107,12 @@ EXPORT_SYMBOL_GPL(rcu_idle_enter);
 void rcu_irq_exit(void)
 {
unsigned long flags;
-   long long oldval;
+   long long newval;
 
local_irq_save(flags);
-   oldval = rcu_dynticks_nesting;
-   rcu_dynticks_nesting--;
-   WARN_ON_ONCE(rcu_dynticks_nesting  0);
-   rcu_idle_enter_common(oldval);
+   newval = rcu_dynticks_nesting - 1;
+   WARN_ON_ONCE(newval  0);
+   rcu_idle_enter_common(newval);
local_irq_restore(flags);
 }
 
-- 
1.7.8

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/