Commit 90a4d2c0106bb690f0b6af3d506febc35c658aa7

Authored by Paul E. McKenney
Committed by Ingo Molnar
1 parent c12172c025

rcu: make treercu safe for suspend and resume

Impact: fix kernel warnings [and potential crash] during suspend+resume

Kudos to both Dhaval Giani and Jens Axboe for finding a bug in treercu
that causes warnings after suspend-resume cycles in Dhaval's case and
during stress tests in Jens's case.  It would also probably cause failures
if heavily stressed.  The solution, ironically enough, is to revert to
rcupreempt's code for initializing the dynticks state.  And the patch
even results in smaller code -- so what was I thinking???

This is 2.6.29 material, given that people really do suspend and resume
Linux these days.  ;-)

Reported-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
Reported-by: Jens Axboe <jens.axboe@oracle.com>
Tested-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
Tested-by: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 1 changed file with 4 additions and 8 deletions Side-by-side Diff

... ... @@ -79,7 +79,10 @@
79 79 DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
80 80  
81 81 #ifdef CONFIG_NO_HZ
82   -DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks);
  82 +DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
  83 + .dynticks_nesting = 1,
  84 + .dynticks = 1,
  85 +};
83 86 #endif /* #ifdef CONFIG_NO_HZ */
84 87  
85 88 static int blimit = 10; /* Maximum callbacks per softirq. */
... ... @@ -1380,13 +1383,6 @@
1380 1383  
1381 1384 static void __cpuinit rcu_online_cpu(int cpu)
1382 1385 {
1383   -#ifdef CONFIG_NO_HZ
1384   - struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
1385   -
1386   - rdtp->dynticks_nesting = 1;
1387   - rdtp->dynticks |= 1; /* need consecutive #s even for hotplug. */
1388   - rdtp->dynticks_nmi = (rdtp->dynticks_nmi + 1) & ~0x1;
1389   -#endif /* #ifdef CONFIG_NO_HZ */
1390 1386 rcu_init_percpu_data(cpu, &rcu_state);
1391 1387 rcu_init_percpu_data(cpu, &rcu_bh_state);
1392 1388 open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);