diff options
Diffstat (limited to 'kernel/rcutree.h')
| -rw-r--r-- | kernel/rcutree.h | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 19b61ac1079f..4d29169f2124 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
| @@ -42,28 +42,28 @@ | |||
| 42 | #define RCU_FANOUT_4 (RCU_FANOUT_3 * CONFIG_RCU_FANOUT) | 42 | #define RCU_FANOUT_4 (RCU_FANOUT_3 * CONFIG_RCU_FANOUT) |
| 43 | 43 | ||
| 44 | #if NR_CPUS <= RCU_FANOUT_1 | 44 | #if NR_CPUS <= RCU_FANOUT_1 |
| 45 | # define NUM_RCU_LVLS 1 | 45 | # define RCU_NUM_LVLS 1 |
| 46 | # define NUM_RCU_LVL_0 1 | 46 | # define NUM_RCU_LVL_0 1 |
| 47 | # define NUM_RCU_LVL_1 (NR_CPUS) | 47 | # define NUM_RCU_LVL_1 (NR_CPUS) |
| 48 | # define NUM_RCU_LVL_2 0 | 48 | # define NUM_RCU_LVL_2 0 |
| 49 | # define NUM_RCU_LVL_3 0 | 49 | # define NUM_RCU_LVL_3 0 |
| 50 | # define NUM_RCU_LVL_4 0 | 50 | # define NUM_RCU_LVL_4 0 |
| 51 | #elif NR_CPUS <= RCU_FANOUT_2 | 51 | #elif NR_CPUS <= RCU_FANOUT_2 |
| 52 | # define NUM_RCU_LVLS 2 | 52 | # define RCU_NUM_LVLS 2 |
| 53 | # define NUM_RCU_LVL_0 1 | 53 | # define NUM_RCU_LVL_0 1 |
| 54 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) | 54 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) |
| 55 | # define NUM_RCU_LVL_2 (NR_CPUS) | 55 | # define NUM_RCU_LVL_2 (NR_CPUS) |
| 56 | # define NUM_RCU_LVL_3 0 | 56 | # define NUM_RCU_LVL_3 0 |
| 57 | # define NUM_RCU_LVL_4 0 | 57 | # define NUM_RCU_LVL_4 0 |
| 58 | #elif NR_CPUS <= RCU_FANOUT_3 | 58 | #elif NR_CPUS <= RCU_FANOUT_3 |
| 59 | # define NUM_RCU_LVLS 3 | 59 | # define RCU_NUM_LVLS 3 |
| 60 | # define NUM_RCU_LVL_0 1 | 60 | # define NUM_RCU_LVL_0 1 |
| 61 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) | 61 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) |
| 62 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) | 62 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) |
| 63 | # define NUM_RCU_LVL_3 (NR_CPUS) | 63 | # define NUM_RCU_LVL_3 (NR_CPUS) |
| 64 | # define NUM_RCU_LVL_4 0 | 64 | # define NUM_RCU_LVL_4 0 |
| 65 | #elif NR_CPUS <= RCU_FANOUT_4 | 65 | #elif NR_CPUS <= RCU_FANOUT_4 |
| 66 | # define NUM_RCU_LVLS 4 | 66 | # define RCU_NUM_LVLS 4 |
| 67 | # define NUM_RCU_LVL_0 1 | 67 | # define NUM_RCU_LVL_0 1 |
| 68 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_3) | 68 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_3) |
| 69 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) | 69 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) |
| @@ -76,6 +76,9 @@ | |||
| 76 | #define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 + NUM_RCU_LVL_4) | 76 | #define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 + NUM_RCU_LVL_4) |
| 77 | #define NUM_RCU_NODES (RCU_SUM - NR_CPUS) | 77 | #define NUM_RCU_NODES (RCU_SUM - NR_CPUS) |
| 78 | 78 | ||
| 79 | extern int rcu_num_lvls; | ||
| 80 | extern int rcu_num_nodes; | ||
| 81 | |||
| 79 | /* | 82 | /* |
| 80 | * Dynticks per-CPU state. | 83 | * Dynticks per-CPU state. |
| 81 | */ | 84 | */ |
| @@ -97,6 +100,7 @@ struct rcu_dynticks { | |||
| 97 | /* # times non-lazy CBs posted to CPU. */ | 100 | /* # times non-lazy CBs posted to CPU. */ |
| 98 | unsigned long nonlazy_posted_snap; | 101 | unsigned long nonlazy_posted_snap; |
| 99 | /* idle-period nonlazy_posted snapshot. */ | 102 | /* idle-period nonlazy_posted snapshot. */ |
| 103 | int tick_nohz_enabled_snap; /* Previously seen value from sysfs. */ | ||
| 100 | #endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ | 104 | #endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ |
| 101 | }; | 105 | }; |
| 102 | 106 | ||
| @@ -206,7 +210,7 @@ struct rcu_node { | |||
| 206 | */ | 210 | */ |
| 207 | #define rcu_for_each_node_breadth_first(rsp, rnp) \ | 211 | #define rcu_for_each_node_breadth_first(rsp, rnp) \ |
| 208 | for ((rnp) = &(rsp)->node[0]; \ | 212 | for ((rnp) = &(rsp)->node[0]; \ |
| 209 | (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++) | 213 | (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++) |
| 210 | 214 | ||
| 211 | /* | 215 | /* |
| 212 | * Do a breadth-first scan of the non-leaf rcu_node structures for the | 216 | * Do a breadth-first scan of the non-leaf rcu_node structures for the |
| @@ -215,7 +219,7 @@ struct rcu_node { | |||
| 215 | */ | 219 | */ |
| 216 | #define rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) \ | 220 | #define rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) \ |
| 217 | for ((rnp) = &(rsp)->node[0]; \ | 221 | for ((rnp) = &(rsp)->node[0]; \ |
| 218 | (rnp) < (rsp)->level[NUM_RCU_LVLS - 1]; (rnp)++) | 222 | (rnp) < (rsp)->level[rcu_num_lvls - 1]; (rnp)++) |
| 219 | 223 | ||
| 220 | /* | 224 | /* |
| 221 | * Scan the leaves of the rcu_node hierarchy for the specified rcu_state | 225 | * Scan the leaves of the rcu_node hierarchy for the specified rcu_state |
| @@ -224,8 +228,8 @@ struct rcu_node { | |||
| 224 | * It is still a leaf node, even if it is also the root node. | 228 | * It is still a leaf node, even if it is also the root node. |
| 225 | */ | 229 | */ |
| 226 | #define rcu_for_each_leaf_node(rsp, rnp) \ | 230 | #define rcu_for_each_leaf_node(rsp, rnp) \ |
| 227 | for ((rnp) = (rsp)->level[NUM_RCU_LVLS - 1]; \ | 231 | for ((rnp) = (rsp)->level[rcu_num_lvls - 1]; \ |
| 228 | (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++) | 232 | (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++) |
| 229 | 233 | ||
| 230 | /* Index values for nxttail array in struct rcu_data. */ | 234 | /* Index values for nxttail array in struct rcu_data. */ |
| 231 | #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ | 235 | #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ |
| @@ -311,6 +315,9 @@ struct rcu_data { | |||
| 311 | unsigned long n_rp_need_fqs; | 315 | unsigned long n_rp_need_fqs; |
| 312 | unsigned long n_rp_need_nothing; | 316 | unsigned long n_rp_need_nothing; |
| 313 | 317 | ||
| 318 | /* 6) _rcu_barrier() callback. */ | ||
| 319 | struct rcu_head barrier_head; | ||
| 320 | |||
| 314 | int cpu; | 321 | int cpu; |
| 315 | struct rcu_state *rsp; | 322 | struct rcu_state *rsp; |
| 316 | }; | 323 | }; |
| @@ -357,10 +364,12 @@ do { \ | |||
| 357 | */ | 364 | */ |
| 358 | struct rcu_state { | 365 | struct rcu_state { |
| 359 | struct rcu_node node[NUM_RCU_NODES]; /* Hierarchy. */ | 366 | struct rcu_node node[NUM_RCU_NODES]; /* Hierarchy. */ |
| 360 | struct rcu_node *level[NUM_RCU_LVLS]; /* Hierarchy levels. */ | 367 | struct rcu_node *level[RCU_NUM_LVLS]; /* Hierarchy levels. */ |
| 361 | u32 levelcnt[MAX_RCU_LVLS + 1]; /* # nodes in each level. */ | 368 | u32 levelcnt[MAX_RCU_LVLS + 1]; /* # nodes in each level. */ |
| 362 | u8 levelspread[NUM_RCU_LVLS]; /* kids/node in each level. */ | 369 | u8 levelspread[RCU_NUM_LVLS]; /* kids/node in each level. */ |
| 363 | struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ | 370 | struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ |
| 371 | void (*call)(struct rcu_head *head, /* call_rcu() flavor. */ | ||
| 372 | void (*func)(struct rcu_head *head)); | ||
| 364 | 373 | ||
| 365 | /* The following fields are guarded by the root rcu_node's lock. */ | 374 | /* The following fields are guarded by the root rcu_node's lock. */ |
| 366 | 375 | ||
| @@ -392,6 +401,11 @@ struct rcu_state { | |||
| 392 | struct task_struct *rcu_barrier_in_progress; | 401 | struct task_struct *rcu_barrier_in_progress; |
| 393 | /* Task doing rcu_barrier(), */ | 402 | /* Task doing rcu_barrier(), */ |
| 394 | /* or NULL if no barrier. */ | 403 | /* or NULL if no barrier. */ |
| 404 | struct mutex barrier_mutex; /* Guards barrier fields. */ | ||
| 405 | atomic_t barrier_cpu_count; /* # CPUs waiting on. */ | ||
| 406 | struct completion barrier_completion; /* Wake at barrier end. */ | ||
| 407 | unsigned long n_barrier_done; /* ++ at start and end of */ | ||
| 408 | /* _rcu_barrier(). */ | ||
| 395 | raw_spinlock_t fqslock; /* Only one task forcing */ | 409 | raw_spinlock_t fqslock; /* Only one task forcing */ |
| 396 | /* quiescent states. */ | 410 | /* quiescent states. */ |
| 397 | unsigned long jiffies_force_qs; /* Time at which to invoke */ | 411 | unsigned long jiffies_force_qs; /* Time at which to invoke */ |
| @@ -409,8 +423,13 @@ struct rcu_state { | |||
| 409 | unsigned long gp_max; /* Maximum GP duration in */ | 423 | unsigned long gp_max; /* Maximum GP duration in */ |
| 410 | /* jiffies. */ | 424 | /* jiffies. */ |
| 411 | char *name; /* Name of structure. */ | 425 | char *name; /* Name of structure. */ |
| 426 | struct list_head flavors; /* List of RCU flavors. */ | ||
| 412 | }; | 427 | }; |
| 413 | 428 | ||
| 429 | extern struct list_head rcu_struct_flavors; | ||
| 430 | #define for_each_rcu_flavor(rsp) \ | ||
| 431 | list_for_each_entry((rsp), &rcu_struct_flavors, flavors) | ||
| 432 | |||
| 414 | /* Return values for rcu_preempt_offline_tasks(). */ | 433 | /* Return values for rcu_preempt_offline_tasks(). */ |
| 415 | 434 | ||
| 416 | #define RCU_OFL_TASKS_NORM_GP 0x1 /* Tasks blocking normal */ | 435 | #define RCU_OFL_TASKS_NORM_GP 0x1 /* Tasks blocking normal */ |
| @@ -453,25 +472,18 @@ static void rcu_stop_cpu_kthread(int cpu); | |||
| 453 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 472 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ |
| 454 | static void rcu_print_detail_task_stall(struct rcu_state *rsp); | 473 | static void rcu_print_detail_task_stall(struct rcu_state *rsp); |
| 455 | static int rcu_print_task_stall(struct rcu_node *rnp); | 474 | static int rcu_print_task_stall(struct rcu_node *rnp); |
| 456 | static void rcu_preempt_stall_reset(void); | ||
| 457 | static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); | 475 | static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); |
| 458 | #ifdef CONFIG_HOTPLUG_CPU | 476 | #ifdef CONFIG_HOTPLUG_CPU |
| 459 | static int rcu_preempt_offline_tasks(struct rcu_state *rsp, | 477 | static int rcu_preempt_offline_tasks(struct rcu_state *rsp, |
| 460 | struct rcu_node *rnp, | 478 | struct rcu_node *rnp, |
| 461 | struct rcu_data *rdp); | 479 | struct rcu_data *rdp); |
| 462 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 480 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ |
| 463 | static void rcu_preempt_cleanup_dead_cpu(int cpu); | ||
| 464 | static void rcu_preempt_check_callbacks(int cpu); | 481 | static void rcu_preempt_check_callbacks(int cpu); |
| 465 | static void rcu_preempt_process_callbacks(void); | ||
| 466 | void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); | 482 | void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); |
| 467 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) | 483 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) |
| 468 | static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp, | 484 | static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp, |
| 469 | bool wake); | 485 | bool wake); |
| 470 | #endif /* #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) */ | 486 | #endif /* #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) */ |
| 471 | static int rcu_preempt_pending(int cpu); | ||
| 472 | static int rcu_preempt_cpu_has_callbacks(int cpu); | ||
| 473 | static void __cpuinit rcu_preempt_init_percpu_data(int cpu); | ||
| 474 | static void rcu_preempt_cleanup_dying_cpu(void); | ||
| 475 | static void __init __rcu_init_preempt(void); | 487 | static void __init __rcu_init_preempt(void); |
| 476 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); | 488 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); |
| 477 | static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); | 489 | static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); |
