|
@@ -176,8 +176,6 @@ void rcu_sched_qs(int cpu)
|
|
|
{
|
|
|
struct rcu_data *rdp = &per_cpu(rcu_sched_data, cpu);
|
|
|
|
|
|
- rdp->passed_quiesce_gpnum = rdp->gpnum;
|
|
|
- barrier();
|
|
|
if (rdp->passed_quiesce == 0)
|
|
|
trace_rcu_grace_period("rcu_sched", rdp->gpnum, "cpuqs");
|
|
|
rdp->passed_quiesce = 1;
|
|
@@ -187,8 +185,6 @@ void rcu_bh_qs(int cpu)
|
|
|
{
|
|
|
struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
|
|
|
|
|
|
- rdp->passed_quiesce_gpnum = rdp->gpnum;
|
|
|
- barrier();
|
|
|
if (rdp->passed_quiesce == 0)
|
|
|
trace_rcu_grace_period("rcu_bh", rdp->gpnum, "cpuqs");
|
|
|
rdp->passed_quiesce = 1;
|
|
@@ -899,12 +895,8 @@ static void __note_new_gpnum(struct rcu_state *rsp, struct rcu_node *rnp, struct
|
|
|
*/
|
|
|
rdp->gpnum = rnp->gpnum;
|
|
|
trace_rcu_grace_period(rsp->name, rdp->gpnum, "cpustart");
|
|
|
- if (rnp->qsmask & rdp->grpmask) {
|
|
|
- rdp->qs_pending = 1;
|
|
|
- rdp->passed_quiesce = 0;
|
|
|
- } else {
|
|
|
- rdp->qs_pending = 0;
|
|
|
- }
|
|
|
+ rdp->passed_quiesce = 0;
|
|
|
+ rdp->qs_pending = !!(rnp->qsmask & rdp->grpmask);
|
|
|
zero_cpu_stall_ticks(rdp);
|
|
|
}
|
|
|
}
|
|
@@ -984,10 +976,13 @@ __rcu_process_gp_end(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_dat
|
|
|
* our behalf. Catch up with this state to avoid noting
|
|
|
* spurious new grace periods. If another grace period
|
|
|
* has started, then rnp->gpnum will have advanced, so
|
|
|
- * we will detect this later on.
|
|
|
+ * we will detect this later on. Of course, any quiescent
|
|
|
+ * states we found for the old GP are now invalid.
|
|
|
*/
|
|
|
- if (ULONG_CMP_LT(rdp->gpnum, rdp->completed))
|
|
|
+ if (ULONG_CMP_LT(rdp->gpnum, rdp->completed)) {
|
|
|
rdp->gpnum = rdp->completed;
|
|
|
+ rdp->passed_quiesce = 0;
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* If RCU does not need a quiescent state from this CPU,
|
|
@@ -1358,7 +1353,7 @@ rcu_report_qs_rnp(unsigned long mask, struct rcu_state *rsp,
|
|
|
* based on quiescent states detected in an earlier grace period!
|
|
|
*/
|
|
|
static void
|
|
|
-rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastgp)
|
|
|
+rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp)
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
unsigned long mask;
|
|
@@ -1366,7 +1361,8 @@ rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long las
|
|
|
|
|
|
rnp = rdp->mynode;
|
|
|
raw_spin_lock_irqsave(&rnp->lock, flags);
|
|
|
- if (lastgp != rnp->gpnum || rnp->completed == rnp->gpnum) {
|
|
|
+ if (rdp->passed_quiesce == 0 || rdp->gpnum != rnp->gpnum ||
|
|
|
+ rnp->completed == rnp->gpnum) {
|
|
|
|
|
|
/*
|
|
|
* The grace period in which this quiescent state was
|
|
@@ -1425,7 +1421,7 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
|
|
|
* Tell RCU we are done (but rcu_report_qs_rdp() will be the
|
|
|
* judge of that).
|
|
|
*/
|
|
|
- rcu_report_qs_rdp(rdp->cpu, rsp, rdp, rdp->passed_quiesce_gpnum);
|
|
|
+ rcu_report_qs_rdp(rdp->cpu, rsp, rdp);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_HOTPLUG_CPU
|
|
@@ -2600,7 +2596,6 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible)
|
|
|
rdp->completed = rnp->completed;
|
|
|
rdp->passed_quiesce = 0;
|
|
|
rdp->qs_pending = 0;
|
|
|
- rdp->passed_quiesce_gpnum = rnp->gpnum - 1;
|
|
|
trace_rcu_grace_period(rsp->name, rdp->gpnum, "cpuonl");
|
|
|
}
|
|
|
raw_spin_unlock(&rnp->lock); /* irqs already disabled. */
|