diff options
author | Paul E. McKenney <paul.mckenney@linaro.org> | 2013-01-07 16:37:42 -0500 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-03-12 14:17:51 -0400 |
commit | 34ed62461ae4970695974afb9a60ac3df0086830 (patch) | |
tree | d65a582953a66ee089074fd5a57e39460d4ce2c6 /kernel/rcutree.h | |
parent | f6161aa153581da4a3867a2d1a7caf4be19b6ec9 (diff) |
rcu: Remove restrictions on no-CBs CPUs
Currently, CPU 0 is constrained to not be a no-CBs CPU, and furthermore
at least one no-CBs CPU must remain online at any given time. These
restrictions are problematic in some situations, such as cases where
all CPUs must run a real-time workload that needs to be insulated from
OS jitter and latencies due to RCU callback invocation. This commit
therefore provides no-CBs CPUs a (very crude and energy-inefficient)
way to start and to wait for grace periods independently of the normal
RCU callback mechanisms. This approach allows any or all of the CPUs to
be designated as no-CBs CPUs, and allows any proper subset of the CPUs
(whether no-CBs CPUs or not) to be offlined.
This commit also provides a fix for a locking bug spotted by Xie
ChanglongX <changlongx.xie@intel.com>.
Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcutree.h')
-rw-r--r-- | kernel/rcutree.h | 12 |
1 files changed, 3 insertions, 9 deletions
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index c896b5045d9d..7af39f4aaac4 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
@@ -326,6 +326,7 @@ struct rcu_data { | |||
326 | int nocb_p_count_lazy; /* (approximate). */ | 326 | int nocb_p_count_lazy; /* (approximate). */ |
327 | wait_queue_head_t nocb_wq; /* For nocb kthreads to sleep on. */ | 327 | wait_queue_head_t nocb_wq; /* For nocb kthreads to sleep on. */ |
328 | struct task_struct *nocb_kthread; | 328 | struct task_struct *nocb_kthread; |
329 | bool nocb_needs_gp; | ||
329 | #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ | 330 | #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ |
330 | 331 | ||
331 | int cpu; | 332 | int cpu; |
@@ -375,12 +376,6 @@ struct rcu_state { | |||
375 | struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ | 376 | struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ |
376 | void (*call)(struct rcu_head *head, /* call_rcu() flavor. */ | 377 | void (*call)(struct rcu_head *head, /* call_rcu() flavor. */ |
377 | void (*func)(struct rcu_head *head)); | 378 | void (*func)(struct rcu_head *head)); |
378 | #ifdef CONFIG_RCU_NOCB_CPU | ||
379 | void (*call_remote)(struct rcu_head *head, | ||
380 | void (*func)(struct rcu_head *head)); | ||
381 | /* call_rcu() flavor, but for */ | ||
382 | /* placing on remote CPU. */ | ||
383 | #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ | ||
384 | 379 | ||
385 | /* The following fields are guarded by the root rcu_node's lock. */ | 380 | /* The following fields are guarded by the root rcu_node's lock. */ |
386 | 381 | ||
@@ -529,16 +524,15 @@ static void print_cpu_stall_info(struct rcu_state *rsp, int cpu); | |||
529 | static void print_cpu_stall_info_end(void); | 524 | static void print_cpu_stall_info_end(void); |
530 | static void zero_cpu_stall_ticks(struct rcu_data *rdp); | 525 | static void zero_cpu_stall_ticks(struct rcu_data *rdp); |
531 | static void increment_cpu_stall_ticks(void); | 526 | static void increment_cpu_stall_ticks(void); |
527 | static int rcu_nocb_needs_gp(struct rcu_data *rdp); | ||
532 | static bool is_nocb_cpu(int cpu); | 528 | static bool is_nocb_cpu(int cpu); |
533 | static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, | 529 | static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, |
534 | bool lazy); | 530 | bool lazy); |
535 | static bool rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, | 531 | static bool rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, |
536 | struct rcu_data *rdp); | 532 | struct rcu_data *rdp); |
537 | static bool nocb_cpu_expendable(int cpu); | ||
538 | static void rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp); | 533 | static void rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp); |
539 | static void rcu_spawn_nocb_kthreads(struct rcu_state *rsp); | 534 | static void rcu_spawn_nocb_kthreads(struct rcu_state *rsp); |
540 | static void init_nocb_callback_list(struct rcu_data *rdp); | 535 | static bool init_nocb_callback_list(struct rcu_data *rdp); |
541 | static void __init rcu_init_nocb(void); | ||
542 | 536 | ||
543 | #endif /* #ifndef RCU_TREE_NONCORE */ | 537 | #endif /* #ifndef RCU_TREE_NONCORE */ |
544 | 538 | ||