Commit 4cdfc175 authored by Paul E. McKenney's avatar Paul E. McKenney

rcu: Move quiescent-state forcing into kthread

As the first step towards allowing quiescent-state forcing to be
preemptible, this commit moves RCU quiescent-state forcing into the
same kthread that is now used to initialize and clean up after grace
periods.  This is yet another step towards keeping scheduling
latency down to a dull roar.

Updated to change from raw_spin_lock_irqsave() to raw_spin_lock_irq()
and to remove the now-unused rcu_state structure fields as suggested by
Peter Zijlstra.
Reported-by: default avatarMike Galbraith <mgalbraith@suse.de>
Reported-by: default avatarDimitri Sivanich <sivanich@sgi.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
parent b402b73b
This diff is collapsed.
...@@ -378,13 +378,6 @@ struct rcu_state { ...@@ -378,13 +378,6 @@ struct rcu_state {
u8 fqs_state ____cacheline_internodealigned_in_smp; u8 fqs_state ____cacheline_internodealigned_in_smp;
/* Force QS state. */ /* Force QS state. */
u8 fqs_active; /* force_quiescent_state() */
/* is running. */
u8 fqs_need_gp; /* A CPU was prevented from */
/* starting a new grace */
/* period because */
/* force_quiescent_state() */
/* was running. */
u8 boost; /* Subject to priority boost. */ u8 boost; /* Subject to priority boost. */
unsigned long gpnum; /* Current gp number. */ unsigned long gpnum; /* Current gp number. */
unsigned long completed; /* # of last completed gp. */ unsigned long completed; /* # of last completed gp. */
...@@ -413,8 +406,6 @@ struct rcu_state { ...@@ -413,8 +406,6 @@ struct rcu_state {
struct completion barrier_completion; /* Wake at barrier end. */ struct completion barrier_completion; /* Wake at barrier end. */
unsigned long n_barrier_done; /* ++ at start and end of */ unsigned long n_barrier_done; /* ++ at start and end of */
/* _rcu_barrier(). */ /* _rcu_barrier(). */
raw_spinlock_t fqslock; /* Only one task forcing */
/* quiescent states. */
unsigned long jiffies_force_qs; /* Time at which to invoke */ unsigned long jiffies_force_qs; /* Time at which to invoke */
/* force_quiescent_state(). */ /* force_quiescent_state(). */
unsigned long n_force_qs; /* Number of calls to */ unsigned long n_force_qs; /* Number of calls to */
...@@ -433,6 +424,10 @@ struct rcu_state { ...@@ -433,6 +424,10 @@ struct rcu_state {
struct list_head flavors; /* List of RCU flavors. */ struct list_head flavors; /* List of RCU flavors. */
}; };
/* Values for rcu_state structure's gp_flags field. */
#define RCU_GP_FLAG_INIT 0x1 /* Need grace-period initialization. */
#define RCU_GP_FLAG_FQS 0x2 /* Need grace-period quiescent-state forcing. */
extern struct list_head rcu_struct_flavors; extern struct list_head rcu_struct_flavors;
#define for_each_rcu_flavor(rsp) \ #define for_each_rcu_flavor(rsp) \
list_for_each_entry((rsp), &rcu_struct_flavors, flavors) list_for_each_entry((rsp), &rcu_struct_flavors, flavors)
......
...@@ -119,7 +119,7 @@ EXPORT_SYMBOL_GPL(rcu_batches_completed); ...@@ -119,7 +119,7 @@ EXPORT_SYMBOL_GPL(rcu_batches_completed);
*/ */
void rcu_force_quiescent_state(void) void rcu_force_quiescent_state(void)
{ {
force_quiescent_state(&rcu_preempt_state, 0); force_quiescent_state(&rcu_preempt_state);
} }
EXPORT_SYMBOL_GPL(rcu_force_quiescent_state); EXPORT_SYMBOL_GPL(rcu_force_quiescent_state);
...@@ -2076,16 +2076,16 @@ static void rcu_prepare_for_idle(int cpu) ...@@ -2076,16 +2076,16 @@ static void rcu_prepare_for_idle(int cpu)
#ifdef CONFIG_TREE_PREEMPT_RCU #ifdef CONFIG_TREE_PREEMPT_RCU
if (per_cpu(rcu_preempt_data, cpu).nxtlist) { if (per_cpu(rcu_preempt_data, cpu).nxtlist) {
rcu_preempt_qs(cpu); rcu_preempt_qs(cpu);
force_quiescent_state(&rcu_preempt_state, 0); force_quiescent_state(&rcu_preempt_state);
} }
#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */ #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
if (per_cpu(rcu_sched_data, cpu).nxtlist) { if (per_cpu(rcu_sched_data, cpu).nxtlist) {
rcu_sched_qs(cpu); rcu_sched_qs(cpu);
force_quiescent_state(&rcu_sched_state, 0); force_quiescent_state(&rcu_sched_state);
} }
if (per_cpu(rcu_bh_data, cpu).nxtlist) { if (per_cpu(rcu_bh_data, cpu).nxtlist) {
rcu_bh_qs(cpu); rcu_bh_qs(cpu);
force_quiescent_state(&rcu_bh_state, 0); force_quiescent_state(&rcu_bh_state);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment