summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/rcupdate.h13
-rw-r--r--kernel/rcupdate.c11
2 files changed, 12 insertions, 12 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 3f6c5e4cb92c..4d747433916b 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -87,9 +87,7 @@ static inline int rcu_batch_after(long a, long b)
struct rcu_data {
/* 1) quiescent state handling : */
long quiescbatch; /* Batch # for grace period */
- long qsctr; /* User-mode/idle loop etc. */
- long last_qsctr; /* value of qsctr at beginning */
- /* of rcu grace period */
+ int passed_quiesc; /* User-mode/idle loop etc. */
int qs_pending; /* core waits for quiesc state */
/* 2) batch handling */
@@ -109,17 +107,20 @@ extern struct rcu_ctrlblk rcu_ctrlblk;
extern struct rcu_ctrlblk rcu_bh_ctrlblk;
/*
- * Increment the quiscent state counter.
+ * Increment the quiescent state counter.
+ * The counter is a bit degenerated: We do not need to know
+ * how many quiescent states passed, just if there was at least
+ * one since the start of the grace period. Thus just a flag.
*/
static inline void rcu_qsctr_inc(int cpu)
{
struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
- rdp->qsctr++;
+ rdp->passed_quiesc = 1;
}
static inline void rcu_bh_qsctr_inc(int cpu)
{
struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
- rdp->qsctr++;
+ rdp->passed_quiesc = 1;
}
static inline int __rcu_pending(struct rcu_ctrlblk *rcp,
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index ebe7e5d96b35..f0ae3c3c013e 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -219,9 +219,9 @@ static void rcu_check_quiescent_state(struct rcu_ctrlblk *rcp,
struct rcu_state *rsp, struct rcu_data *rdp)
{
if (rdp->quiescbatch != rcp->cur) {
- /* new grace period: record qsctr value. */
+ /* start new grace period: */
rdp->qs_pending = 1;
- rdp->last_qsctr = rdp->qsctr;
+ rdp->passed_quiesc = 0;
rdp->quiescbatch = rcp->cur;
return;
}
@@ -234,11 +234,10 @@ static void rcu_check_quiescent_state(struct rcu_ctrlblk *rcp,
return;
/*
- * Races with local timer interrupt - in the worst case
- * we may miss one quiescent state of that CPU. That is
- * tolerable. So no need to disable interrupts.
+ * Was there a quiescent state since the beginning of the grace
+ * period? If no, then exit and wait for the next call.
*/
- if (rdp->qsctr == rdp->last_qsctr)
+ if (!rdp->passed_quiesc)
return;
rdp->qs_pending = 0;