14102adabSPaul E. McKenney /* 24102adabSPaul E. McKenney * Read-Copy Update mechanism for mutual exclusion (tree-based version) 34102adabSPaul E. McKenney * Internal non-public definitions. 44102adabSPaul E. McKenney * 54102adabSPaul E. McKenney * This program is free software; you can redistribute it and/or modify 64102adabSPaul E. McKenney * it under the terms of the GNU General Public License as published by 74102adabSPaul E. McKenney * the Free Software Foundation; either version 2 of the License, or 84102adabSPaul E. McKenney * (at your option) any later version. 94102adabSPaul E. McKenney * 104102adabSPaul E. McKenney * This program is distributed in the hope that it will be useful, 114102adabSPaul E. McKenney * but WITHOUT ANY WARRANTY; without even the implied warranty of 124102adabSPaul E. McKenney * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 134102adabSPaul E. McKenney * GNU General Public License for more details. 144102adabSPaul E. McKenney * 154102adabSPaul E. McKenney * You should have received a copy of the GNU General Public License 1687de1cfdSPaul E. McKenney * along with this program; if not, you can access it online at 1787de1cfdSPaul E. McKenney * http://www.gnu.org/licenses/gpl-2.0.html. 184102adabSPaul E. McKenney * 194102adabSPaul E. McKenney * Copyright IBM Corporation, 2008 204102adabSPaul E. McKenney * 214102adabSPaul E. McKenney * Author: Ingo Molnar <mingo@elte.hu> 224102adabSPaul E. McKenney * Paul E. McKenney <paulmck@linux.vnet.ibm.com> 234102adabSPaul E. McKenney */ 244102adabSPaul E. McKenney 254102adabSPaul E. McKenney #include <linux/cache.h> 264102adabSPaul E. McKenney #include <linux/spinlock.h> 27037741a6SIngo Molnar #include <linux/rtmutex.h> 284102adabSPaul E. McKenney #include <linux/threads.h> 294102adabSPaul E. McKenney #include <linux/cpumask.h> 304102adabSPaul E. McKenney #include <linux/seqlock.h> 31abedf8e2SPaul Gortmaker #include <linux/swait.h> 323a6d7c64SPeter Zijlstra #include <linux/stop_machine.h> 33f2425b4eSPaul E. McKenney #include <linux/rcu_node_tree.h> 344102adabSPaul E. McKenney 3545753c5fSIngo Molnar #include "rcu_segcblist.h" 3645753c5fSIngo Molnar 374102adabSPaul E. McKenney /* 384102adabSPaul E. McKenney * Dynticks per-CPU state. 394102adabSPaul E. McKenney */ 404102adabSPaul E. McKenney struct rcu_dynticks { 414102adabSPaul E. McKenney long long dynticks_nesting; /* Track irq/process nesting level. */ 424102adabSPaul E. McKenney /* Process level is worth LLONG_MAX/2. */ 434102adabSPaul E. McKenney int dynticks_nmi_nesting; /* Track NMI nesting level. */ 444102adabSPaul E. McKenney atomic_t dynticks; /* Even value for idle, else odd. */ 450f9be8caSPaul E. McKenney bool rcu_need_heavy_qs; /* GP old, need heavy quiescent state. */ 469577df9aSPaul E. McKenney unsigned long rcu_qs_ctr; /* Light universal quiescent state ctr. */ 479226b10dSPaul E. McKenney bool rcu_urgent_qs; /* GP old need light quiescent state. */ 484102adabSPaul E. McKenney #ifdef CONFIG_RCU_FAST_NO_HZ 494102adabSPaul E. McKenney bool all_lazy; /* Are all CPU's CBs lazy? */ 504102adabSPaul E. McKenney unsigned long nonlazy_posted; 514102adabSPaul E. McKenney /* # times non-lazy CBs posted to CPU. */ 524102adabSPaul E. McKenney unsigned long nonlazy_posted_snap; 534102adabSPaul E. McKenney /* idle-period nonlazy_posted snapshot. */ 544102adabSPaul E. McKenney unsigned long last_accelerate; 554102adabSPaul E. McKenney /* Last jiffy CBs were accelerated. */ 564102adabSPaul E. McKenney unsigned long last_advance_all; 574102adabSPaul E. McKenney /* Last jiffy CBs were all advanced. */ 584102adabSPaul E. McKenney int tick_nohz_enabled_snap; /* Previously seen value from sysfs. */ 594102adabSPaul E. McKenney #endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ 604102adabSPaul E. McKenney }; 614102adabSPaul E. McKenney 624102adabSPaul E. McKenney /* RCU's kthread states for tracing. */ 634102adabSPaul E. McKenney #define RCU_KTHREAD_STOPPED 0 644102adabSPaul E. McKenney #define RCU_KTHREAD_RUNNING 1 654102adabSPaul E. McKenney #define RCU_KTHREAD_WAITING 2 664102adabSPaul E. McKenney #define RCU_KTHREAD_OFFCPU 3 674102adabSPaul E. McKenney #define RCU_KTHREAD_YIELDING 4 684102adabSPaul E. McKenney #define RCU_KTHREAD_MAX 4 694102adabSPaul E. McKenney 704102adabSPaul E. McKenney /* 714102adabSPaul E. McKenney * Definition for node within the RCU grace-period-detection hierarchy. 724102adabSPaul E. McKenney */ 734102adabSPaul E. McKenney struct rcu_node { 7467c583a7SBoqun Feng raw_spinlock_t __private lock; /* Root rcu_node's lock protects */ 7567c583a7SBoqun Feng /* some rcu_state fields as well as */ 7667c583a7SBoqun Feng /* following. */ 774102adabSPaul E. McKenney unsigned long gpnum; /* Current grace period for this node. */ 784102adabSPaul E. McKenney /* This will either be equal to or one */ 794102adabSPaul E. McKenney /* behind the root rcu_node's gpnum. */ 804102adabSPaul E. McKenney unsigned long completed; /* Last GP completed for this node. */ 814102adabSPaul E. McKenney /* This will either be equal to or one */ 824102adabSPaul E. McKenney /* behind the root rcu_node's gpnum. */ 834102adabSPaul E. McKenney unsigned long qsmask; /* CPUs or groups that need to switch in */ 844102adabSPaul E. McKenney /* order for current grace period to proceed.*/ 854102adabSPaul E. McKenney /* In leaf rcu_node, each bit corresponds to */ 864102adabSPaul E. McKenney /* an rcu_data structure, otherwise, each */ 874102adabSPaul E. McKenney /* bit corresponds to a child rcu_node */ 884102adabSPaul E. McKenney /* structure. */ 894102adabSPaul E. McKenney unsigned long qsmaskinit; 90b9585e94SPaul E. McKenney /* Per-GP initial value for qsmask. */ 910aa04b05SPaul E. McKenney /* Initialized from ->qsmaskinitnext at the */ 920aa04b05SPaul E. McKenney /* beginning of each grace period. */ 930aa04b05SPaul E. McKenney unsigned long qsmaskinitnext; 940aa04b05SPaul E. McKenney /* Online CPUs for next grace period. */ 95b9585e94SPaul E. McKenney unsigned long expmask; /* CPUs or groups that need to check in */ 96b9585e94SPaul E. McKenney /* to allow the current expedited GP */ 97b9585e94SPaul E. McKenney /* to complete. */ 98b9585e94SPaul E. McKenney unsigned long expmaskinit; 99b9585e94SPaul E. McKenney /* Per-GP initial values for expmask. */ 100b9585e94SPaul E. McKenney /* Initialized from ->expmaskinitnext at the */ 101b9585e94SPaul E. McKenney /* beginning of each expedited GP. */ 102b9585e94SPaul E. McKenney unsigned long expmaskinitnext; 103b9585e94SPaul E. McKenney /* Online CPUs for next expedited GP. */ 1041de6e56dSPaul E. McKenney /* Any CPU that has ever been online will */ 1051de6e56dSPaul E. McKenney /* have its bit set. */ 1064102adabSPaul E. McKenney unsigned long grpmask; /* Mask to apply to parent qsmask. */ 1074102adabSPaul E. McKenney /* Only one bit will be set in this mask. */ 1084102adabSPaul E. McKenney int grplo; /* lowest-numbered CPU or group here. */ 1094102adabSPaul E. McKenney int grphi; /* highest-numbered CPU or group here. */ 1104102adabSPaul E. McKenney u8 grpnum; /* CPU/group number for next level up. */ 1114102adabSPaul E. McKenney u8 level; /* root is at level 0. */ 1120aa04b05SPaul E. McKenney bool wait_blkd_tasks;/* Necessary to wait for blocked tasks to */ 1130aa04b05SPaul E. McKenney /* exit RCU read-side critical sections */ 1140aa04b05SPaul E. McKenney /* before propagating offline up the */ 1150aa04b05SPaul E. McKenney /* rcu_node tree? */ 1164102adabSPaul E. McKenney struct rcu_node *parent; 1174102adabSPaul E. McKenney struct list_head blkd_tasks; 1184102adabSPaul E. McKenney /* Tasks blocked in RCU read-side critical */ 1194102adabSPaul E. McKenney /* section. Tasks are placed at the head */ 1204102adabSPaul E. McKenney /* of this list and age towards the tail. */ 1214102adabSPaul E. McKenney struct list_head *gp_tasks; 1224102adabSPaul E. McKenney /* Pointer to the first task blocking the */ 1234102adabSPaul E. McKenney /* current grace period, or NULL if there */ 1244102adabSPaul E. McKenney /* is no such task. */ 1254102adabSPaul E. McKenney struct list_head *exp_tasks; 1264102adabSPaul E. McKenney /* Pointer to the first task blocking the */ 1274102adabSPaul E. McKenney /* current expedited grace period, or NULL */ 1284102adabSPaul E. McKenney /* if there is no such task. If there */ 1294102adabSPaul E. McKenney /* is no current expedited grace period, */ 1304102adabSPaul E. McKenney /* then there can cannot be any such task. */ 1314102adabSPaul E. McKenney struct list_head *boost_tasks; 1324102adabSPaul E. McKenney /* Pointer to first task that needs to be */ 1334102adabSPaul E. McKenney /* priority boosted, or NULL if no priority */ 1344102adabSPaul E. McKenney /* boosting is needed for this rcu_node */ 1354102adabSPaul E. McKenney /* structure. If there are no tasks */ 1364102adabSPaul E. McKenney /* queued on this rcu_node structure that */ 1374102adabSPaul E. McKenney /* are blocking the current grace period, */ 1384102adabSPaul E. McKenney /* there can be no such task. */ 139abaa93d9SPaul E. McKenney struct rt_mutex boost_mtx; 140abaa93d9SPaul E. McKenney /* Used only for the priority-boosting */ 141abaa93d9SPaul E. McKenney /* side effect, not as a lock. */ 1424102adabSPaul E. McKenney unsigned long boost_time; 1434102adabSPaul E. McKenney /* When to start boosting (jiffies). */ 1444102adabSPaul E. McKenney struct task_struct *boost_kthread_task; 1454102adabSPaul E. McKenney /* kthread that takes care of priority */ 1464102adabSPaul E. McKenney /* boosting for this rcu_node structure. */ 1474102adabSPaul E. McKenney unsigned int boost_kthread_status; 1484102adabSPaul E. McKenney /* State of boost_kthread_task for tracing. */ 1494102adabSPaul E. McKenney unsigned long n_tasks_boosted; 1504102adabSPaul E. McKenney /* Total number of tasks boosted. */ 1514102adabSPaul E. McKenney unsigned long n_exp_boosts; 1524102adabSPaul E. McKenney /* Number of tasks boosted for expedited GP. */ 1534102adabSPaul E. McKenney unsigned long n_normal_boosts; 1544102adabSPaul E. McKenney /* Number of tasks boosted for normal GP. */ 1554102adabSPaul E. McKenney #ifdef CONFIG_RCU_NOCB_CPU 156abedf8e2SPaul Gortmaker struct swait_queue_head nocb_gp_wq[2]; 1574102adabSPaul E. McKenney /* Place for rcu_nocb_kthread() to wait GP. */ 1584102adabSPaul E. McKenney #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ 1594102adabSPaul E. McKenney int need_future_gp[2]; 1604102adabSPaul E. McKenney /* Counts of upcoming no-CB GP requests. */ 1614102adabSPaul E. McKenney raw_spinlock_t fqslock ____cacheline_internodealigned_in_smp; 162385b73c0SPaul E. McKenney 163f6a12f34SPaul E. McKenney spinlock_t exp_lock ____cacheline_internodealigned_in_smp; 164f6a12f34SPaul E. McKenney unsigned long exp_seq_rq; 1653b5f668eSPaul E. McKenney wait_queue_head_t exp_wq[4]; 1664102adabSPaul E. McKenney } ____cacheline_internodealigned_in_smp; 1674102adabSPaul E. McKenney 1684102adabSPaul E. McKenney /* 169bc75e999SMark Rutland * Bitmasks in an rcu_node cover the interval [grplo, grphi] of CPU IDs, and 170bc75e999SMark Rutland * are indexed relative to this interval rather than the global CPU ID space. 171bc75e999SMark Rutland * This generates the bit for a CPU in node-local masks. 172bc75e999SMark Rutland */ 173bc75e999SMark Rutland #define leaf_node_cpu_bit(rnp, cpu) (1UL << ((cpu) - (rnp)->grplo)) 174bc75e999SMark Rutland 175bc75e999SMark Rutland /* 1765b74c458SPaul E. McKenney * Union to allow "aggregate OR" operation on the need for a quiescent 1775b74c458SPaul E. McKenney * state by the normal and expedited grace periods. 1785b74c458SPaul E. McKenney */ 1795b74c458SPaul E. McKenney union rcu_noqs { 1805b74c458SPaul E. McKenney struct { 1815b74c458SPaul E. McKenney u8 norm; 1825b74c458SPaul E. McKenney u8 exp; 1835b74c458SPaul E. McKenney } b; /* Bits. */ 1845b74c458SPaul E. McKenney u16 s; /* Set of bits, aggregate OR here. */ 1855b74c458SPaul E. McKenney }; 1865b74c458SPaul E. McKenney 1874102adabSPaul E. McKenney /* Index values for nxttail array in struct rcu_data. */ 1884102adabSPaul E. McKenney #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ 1894102adabSPaul E. McKenney #define RCU_WAIT_TAIL 1 /* Also RCU_NEXT_READY head. */ 1904102adabSPaul E. McKenney #define RCU_NEXT_READY_TAIL 2 /* Also RCU_NEXT head. */ 1914102adabSPaul E. McKenney #define RCU_NEXT_TAIL 3 1924102adabSPaul E. McKenney #define RCU_NEXT_SIZE 4 1934102adabSPaul E. McKenney 1944102adabSPaul E. McKenney /* Per-CPU data for read-copy update. */ 1954102adabSPaul E. McKenney struct rcu_data { 1964102adabSPaul E. McKenney /* 1) quiescent-state and grace-period handling : */ 1974102adabSPaul E. McKenney unsigned long completed; /* Track rsp->completed gp number */ 1984102adabSPaul E. McKenney /* in order to detect GP end. */ 1994102adabSPaul E. McKenney unsigned long gpnum; /* Highest gp number that this CPU */ 2004102adabSPaul E. McKenney /* is aware of having started. */ 2015cd37193SPaul E. McKenney unsigned long rcu_qs_ctr_snap;/* Snapshot of rcu_qs_ctr to check */ 2025cd37193SPaul E. McKenney /* for rcu_all_qs() invocations. */ 2035b74c458SPaul E. McKenney union rcu_noqs cpu_no_qs; /* No QSes yet for this CPU. */ 20497c668b8SPaul E. McKenney bool core_needs_qs; /* Core waits for quiesc state. */ 2054102adabSPaul E. McKenney bool beenonline; /* CPU online at least once. */ 206e3663b10SPaul E. McKenney bool gpwrap; /* Possible gpnum/completed wrap. */ 2074102adabSPaul E. McKenney struct rcu_node *mynode; /* This CPU's leaf of hierarchy */ 2084102adabSPaul E. McKenney unsigned long grpmask; /* Mask to apply to leaf qsmask. */ 2094102adabSPaul E. McKenney unsigned long ticks_this_gp; /* The number of scheduling-clock */ 2104102adabSPaul E. McKenney /* ticks this CPU has handled */ 2114102adabSPaul E. McKenney /* during and after the last grace */ 2124102adabSPaul E. McKenney /* period it is aware of. */ 2134102adabSPaul E. McKenney 2144102adabSPaul E. McKenney /* 2) batch handling */ 21515fecf89SPaul E. McKenney struct rcu_segcblist cblist; /* Segmented callback list, with */ 21615fecf89SPaul E. McKenney /* different callbacks waiting for */ 21715fecf89SPaul E. McKenney /* different grace periods. */ 2184102adabSPaul E. McKenney long qlen_last_fqs_check; 2194102adabSPaul E. McKenney /* qlen at last check for QS forcing */ 2204102adabSPaul E. McKenney unsigned long n_cbs_invoked; /* count of RCU cbs invoked. */ 2214102adabSPaul E. McKenney unsigned long n_nocbs_invoked; /* count of no-CBs RCU cbs invoked. */ 2224102adabSPaul E. McKenney unsigned long n_force_qs_snap; 2234102adabSPaul E. McKenney /* did other CPU force QS recently? */ 2244102adabSPaul E. McKenney long blimit; /* Upper limit on a processed batch */ 2254102adabSPaul E. McKenney 2264102adabSPaul E. McKenney /* 3) dynticks interface. */ 2274102adabSPaul E. McKenney struct rcu_dynticks *dynticks; /* Shared per-CPU dynticks state. */ 2284102adabSPaul E. McKenney int dynticks_snap; /* Per-GP tracking for dynticks. */ 2294102adabSPaul E. McKenney 2304102adabSPaul E. McKenney /* 4) reasons this CPU needed to be kicked by force_quiescent_state */ 2314102adabSPaul E. McKenney unsigned long dynticks_fqs; /* Kicked due to dynticks idle. */ 2324102adabSPaul E. McKenney unsigned long offline_fqs; /* Kicked due to being offline. */ 2334a81e832SPaul E. McKenney unsigned long cond_resched_completed; 2344a81e832SPaul E. McKenney /* Grace period that needs help */ 2354a81e832SPaul E. McKenney /* from cond_resched(). */ 2364102adabSPaul E. McKenney 2374102adabSPaul E. McKenney /* 5) __rcu_pending() statistics. */ 2384102adabSPaul E. McKenney unsigned long n_rcu_pending; /* rcu_pending() calls since boot. */ 23997c668b8SPaul E. McKenney unsigned long n_rp_core_needs_qs; 2404102adabSPaul E. McKenney unsigned long n_rp_report_qs; 2414102adabSPaul E. McKenney unsigned long n_rp_cb_ready; 2424102adabSPaul E. McKenney unsigned long n_rp_cpu_needs_gp; 2434102adabSPaul E. McKenney unsigned long n_rp_gp_completed; 2444102adabSPaul E. McKenney unsigned long n_rp_gp_started; 24596d3fd0dSPaul E. McKenney unsigned long n_rp_nocb_defer_wakeup; 2464102adabSPaul E. McKenney unsigned long n_rp_need_nothing; 2474102adabSPaul E. McKenney 2482cd6ffafSPaul E. McKenney /* 6) _rcu_barrier(), OOM callbacks, and expediting. */ 2494102adabSPaul E. McKenney struct rcu_head barrier_head; 2504102adabSPaul E. McKenney #ifdef CONFIG_RCU_FAST_NO_HZ 2514102adabSPaul E. McKenney struct rcu_head oom_head; 2524102adabSPaul E. McKenney #endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ 2538b355e3bSPaul E. McKenney atomic_long_t exp_workdone0; /* # done by workqueue. */ 254d40a4f09SPaul E. McKenney atomic_long_t exp_workdone1; /* # done by others #1. */ 255d40a4f09SPaul E. McKenney atomic_long_t exp_workdone2; /* # done by others #2. */ 256d40a4f09SPaul E. McKenney atomic_long_t exp_workdone3; /* # done by others #3. */ 2570742ac3eSPaul E. McKenney int exp_dynticks_snap; /* Double-check need for IPI. */ 2584102adabSPaul E. McKenney 2594102adabSPaul E. McKenney /* 7) Callback offloading. */ 2604102adabSPaul E. McKenney #ifdef CONFIG_RCU_NOCB_CPU 2614102adabSPaul E. McKenney struct rcu_head *nocb_head; /* CBs waiting for kthread. */ 2624102adabSPaul E. McKenney struct rcu_head **nocb_tail; 26341050a00SPaul E. McKenney atomic_long_t nocb_q_count; /* # CBs waiting for nocb */ 26441050a00SPaul E. McKenney atomic_long_t nocb_q_count_lazy; /* invocation (all stages). */ 265fbce7497SPaul E. McKenney struct rcu_head *nocb_follower_head; /* CBs ready to invoke. */ 266fbce7497SPaul E. McKenney struct rcu_head **nocb_follower_tail; 267abedf8e2SPaul Gortmaker struct swait_queue_head nocb_wq; /* For nocb kthreads to sleep on. */ 2684102adabSPaul E. McKenney struct task_struct *nocb_kthread; 2699fdd3bc9SPaul E. McKenney int nocb_defer_wakeup; /* Defer wakeup of nocb_kthread. */ 270fbce7497SPaul E. McKenney 271fbce7497SPaul E. McKenney /* The following fields are used by the leader, hence own cacheline. */ 272fbce7497SPaul E. McKenney struct rcu_head *nocb_gp_head ____cacheline_internodealigned_in_smp; 273fbce7497SPaul E. McKenney /* CBs waiting for GP. */ 274fbce7497SPaul E. McKenney struct rcu_head **nocb_gp_tail; 27511ed7f93SPranith Kumar bool nocb_leader_sleep; /* Is the nocb leader thread asleep? */ 276fbce7497SPaul E. McKenney struct rcu_data *nocb_next_follower; 277fbce7497SPaul E. McKenney /* Next follower in wakeup chain. */ 278fbce7497SPaul E. McKenney 279fbce7497SPaul E. McKenney /* The following fields are used by the follower, hence new cachline. */ 280fbce7497SPaul E. McKenney struct rcu_data *nocb_leader ____cacheline_internodealigned_in_smp; 281fbce7497SPaul E. McKenney /* Leader CPU takes GP-end wakeups. */ 2824102adabSPaul E. McKenney #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ 2834102adabSPaul E. McKenney 2844102adabSPaul E. McKenney /* 8) RCU CPU stall data. */ 2854102adabSPaul E. McKenney unsigned int softirq_snap; /* Snapshot of softirq activity. */ 2864102adabSPaul E. McKenney 2874102adabSPaul E. McKenney int cpu; 2884102adabSPaul E. McKenney struct rcu_state *rsp; 2894102adabSPaul E. McKenney }; 2904102adabSPaul E. McKenney 2919fdd3bc9SPaul E. McKenney /* Values for nocb_defer_wakeup field in struct rcu_data. */ 292511324e4SPaul E. McKenney #define RCU_NOCB_WAKE_NOT 0 293511324e4SPaul E. McKenney #define RCU_NOCB_WAKE 1 294511324e4SPaul E. McKenney #define RCU_NOCB_WAKE_FORCE 2 2959fdd3bc9SPaul E. McKenney 2964102adabSPaul E. McKenney #define RCU_JIFFIES_TILL_FORCE_QS (1 + (HZ > 250) + (HZ > 500)) 2974102adabSPaul E. McKenney /* For jiffies_till_first_fqs and */ 2984102adabSPaul E. McKenney /* and jiffies_till_next_fqs. */ 2994102adabSPaul E. McKenney 3004102adabSPaul E. McKenney #define RCU_JIFFIES_FQS_DIV 256 /* Very large systems need more */ 3014102adabSPaul E. McKenney /* delay between bouts of */ 3024102adabSPaul E. McKenney /* quiescent-state forcing. */ 3034102adabSPaul E. McKenney 3044102adabSPaul E. McKenney #define RCU_STALL_RAT_DELAY 2 /* Allow other CPUs time to take */ 3054102adabSPaul E. McKenney /* at least one scheduling clock */ 3064102adabSPaul E. McKenney /* irq before ratting on them. */ 3074102adabSPaul E. McKenney 3084102adabSPaul E. McKenney #define rcu_wait(cond) \ 3094102adabSPaul E. McKenney do { \ 3104102adabSPaul E. McKenney for (;;) { \ 3114102adabSPaul E. McKenney set_current_state(TASK_INTERRUPTIBLE); \ 3124102adabSPaul E. McKenney if (cond) \ 3134102adabSPaul E. McKenney break; \ 3144102adabSPaul E. McKenney schedule(); \ 3154102adabSPaul E. McKenney } \ 3164102adabSPaul E. McKenney __set_current_state(TASK_RUNNING); \ 3174102adabSPaul E. McKenney } while (0) 3184102adabSPaul E. McKenney 3194102adabSPaul E. McKenney /* 3204102adabSPaul E. McKenney * RCU global state, including node hierarchy. This hierarchy is 3214102adabSPaul E. McKenney * represented in "heap" form in a dense array. The root (first level) 3224102adabSPaul E. McKenney * of the hierarchy is in ->node[0] (referenced by ->level[0]), the second 3234102adabSPaul E. McKenney * level in ->node[1] through ->node[m] (->node[1] referenced by ->level[1]), 3244102adabSPaul E. McKenney * and the third level in ->node[m+1] and following (->node[m+1] referenced 3254102adabSPaul E. McKenney * by ->level[2]). The number of levels is determined by the number of 3264102adabSPaul E. McKenney * CPUs and by CONFIG_RCU_FANOUT. Small systems will have a "hierarchy" 3274102adabSPaul E. McKenney * consisting of a single rcu_node. 3284102adabSPaul E. McKenney */ 3294102adabSPaul E. McKenney struct rcu_state { 3304102adabSPaul E. McKenney struct rcu_node node[NUM_RCU_NODES]; /* Hierarchy. */ 331032dfc87SAlexander Gordeev struct rcu_node *level[RCU_NUM_LVLS + 1]; 332032dfc87SAlexander Gordeev /* Hierarchy levels (+1 to */ 333032dfc87SAlexander Gordeev /* shut bogus gcc warning) */ 3344102adabSPaul E. McKenney struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ 335db3e8db4SBoqun Feng call_rcu_func_t call; /* call_rcu() flavor. */ 336b9585e94SPaul E. McKenney int ncpus; /* # CPUs seen so far. */ 3374102adabSPaul E. McKenney 3384102adabSPaul E. McKenney /* The following fields are guarded by the root rcu_node's lock. */ 3394102adabSPaul E. McKenney 34077f81fe0SPetr Mladek u8 boost ____cacheline_internodealigned_in_smp; 34177f81fe0SPetr Mladek /* Subject to priority boost. */ 3424102adabSPaul E. McKenney unsigned long gpnum; /* Current gp number. */ 3434102adabSPaul E. McKenney unsigned long completed; /* # of last completed gp. */ 3444102adabSPaul E. McKenney struct task_struct *gp_kthread; /* Task for grace periods. */ 345abedf8e2SPaul Gortmaker struct swait_queue_head gp_wq; /* Where GP task waits. */ 346afea227fSPaul E. McKenney short gp_flags; /* Commands for GP task. */ 347afea227fSPaul E. McKenney short gp_state; /* GP kthread sleep state. */ 3484102adabSPaul E. McKenney 3494102adabSPaul E. McKenney /* End of fields guarded by root rcu_node's lock. */ 3504102adabSPaul E. McKenney 3514102adabSPaul E. McKenney raw_spinlock_t orphan_lock ____cacheline_internodealigned_in_smp; 3524102adabSPaul E. McKenney /* Protect following fields. */ 35315fecf89SPaul E. McKenney struct rcu_cblist orphan_pend; /* Orphaned callbacks that */ 3544102adabSPaul E. McKenney /* need a grace period. */ 35515fecf89SPaul E. McKenney struct rcu_cblist orphan_done; /* Orphaned callbacks that */ 3564102adabSPaul E. McKenney /* are ready to invoke. */ 35715fecf89SPaul E. McKenney /* (Contains counts.) */ 3584102adabSPaul E. McKenney /* End of fields guarded by orphan_lock. */ 3594102adabSPaul E. McKenney 3604102adabSPaul E. McKenney struct mutex barrier_mutex; /* Guards barrier fields. */ 3614102adabSPaul E. McKenney atomic_t barrier_cpu_count; /* # CPUs waiting on. */ 3624102adabSPaul E. McKenney struct completion barrier_completion; /* Wake at barrier end. */ 3634f525a52SPaul E. McKenney unsigned long barrier_sequence; /* ++ at start and end of */ 3644102adabSPaul E. McKenney /* _rcu_barrier(). */ 3654102adabSPaul E. McKenney /* End of fields guarded by barrier_mutex. */ 3664102adabSPaul E. McKenney 367f6a12f34SPaul E. McKenney struct mutex exp_mutex; /* Serialize expedited GP. */ 3683b5f668eSPaul E. McKenney struct mutex exp_wake_mutex; /* Serialize wakeup. */ 369d6ada2cfSPaul E. McKenney unsigned long expedited_sequence; /* Take a ticket. */ 3703a6d7c64SPeter Zijlstra atomic_t expedited_need_qs; /* # CPUs left to check in. */ 371abedf8e2SPaul Gortmaker struct swait_queue_head expedited_wq; /* Wait for check-ins. */ 372b9585e94SPaul E. McKenney int ncpus_snap; /* # CPUs seen last time. */ 3734102adabSPaul E. McKenney 3744102adabSPaul E. McKenney unsigned long jiffies_force_qs; /* Time at which to invoke */ 3754102adabSPaul E. McKenney /* force_quiescent_state(). */ 3768c7c4829SPaul E. McKenney unsigned long jiffies_kick_kthreads; /* Time at which to kick */ 3778c7c4829SPaul E. McKenney /* kthreads, if configured. */ 3784102adabSPaul E. McKenney unsigned long n_force_qs; /* Number of calls to */ 3794102adabSPaul E. McKenney /* force_quiescent_state(). */ 3804102adabSPaul E. McKenney unsigned long n_force_qs_lh; /* ~Number of calls leaving */ 3814102adabSPaul E. McKenney /* due to lock unavailable. */ 3824102adabSPaul E. McKenney unsigned long n_force_qs_ngp; /* Number of calls leaving */ 3834102adabSPaul E. McKenney /* due to no GP active. */ 3844102adabSPaul E. McKenney unsigned long gp_start; /* Time at which GP started, */ 3854102adabSPaul E. McKenney /* but in jiffies. */ 3866ccd2ecdSPaul E. McKenney unsigned long gp_activity; /* Time of last GP kthread */ 3876ccd2ecdSPaul E. McKenney /* activity in jiffies. */ 3884102adabSPaul E. McKenney unsigned long jiffies_stall; /* Time at which to check */ 3894102adabSPaul E. McKenney /* for CPU stalls. */ 3906193c76aSPaul E. McKenney unsigned long jiffies_resched; /* Time at which to resched */ 3916193c76aSPaul E. McKenney /* a reluctant CPU. */ 392fc908ed3SPaul E. McKenney unsigned long n_force_qs_gpstart; /* Snapshot of n_force_qs at */ 393fc908ed3SPaul E. McKenney /* GP start. */ 3944102adabSPaul E. McKenney unsigned long gp_max; /* Maximum GP duration in */ 3954102adabSPaul E. McKenney /* jiffies. */ 3964102adabSPaul E. McKenney const char *name; /* Name of structure. */ 3974102adabSPaul E. McKenney char abbr; /* Abbreviated name. */ 3984102adabSPaul E. McKenney struct list_head flavors; /* List of RCU flavors. */ 3994102adabSPaul E. McKenney }; 4004102adabSPaul E. McKenney 4014102adabSPaul E. McKenney /* Values for rcu_state structure's gp_flags field. */ 4024102adabSPaul E. McKenney #define RCU_GP_FLAG_INIT 0x1 /* Need grace-period initialization. */ 4034102adabSPaul E. McKenney #define RCU_GP_FLAG_FQS 0x2 /* Need grace-period quiescent-state forcing. */ 4044102adabSPaul E. McKenney 405c34d2f41SPaul E. McKenney /* Values for rcu_state structure's gp_state field. */ 40677f81fe0SPetr Mladek #define RCU_GP_IDLE 0 /* Initial state and no GP in progress. */ 407afea227fSPaul E. McKenney #define RCU_GP_WAIT_GPS 1 /* Wait for grace-period start. */ 408319362c9SPaul E. McKenney #define RCU_GP_DONE_GPS 2 /* Wait done for grace-period start. */ 409319362c9SPaul E. McKenney #define RCU_GP_WAIT_FQS 3 /* Wait for force-quiescent-state time. */ 41032bb1c79SPaul E. McKenney #define RCU_GP_DOING_FQS 4 /* Wait done for force-quiescent-state time. */ 411319362c9SPaul E. McKenney #define RCU_GP_CLEANUP 5 /* Grace-period cleanup started. */ 412319362c9SPaul E. McKenney #define RCU_GP_CLEANED 6 /* Grace-period cleanup complete. */ 413afea227fSPaul E. McKenney 4146b50e119SPaul E. McKenney #ifndef RCU_TREE_NONCORE 4156b50e119SPaul E. McKenney static const char * const gp_state_names[] = { 4166b50e119SPaul E. McKenney "RCU_GP_IDLE", 4176b50e119SPaul E. McKenney "RCU_GP_WAIT_GPS", 4186b50e119SPaul E. McKenney "RCU_GP_DONE_GPS", 4196b50e119SPaul E. McKenney "RCU_GP_WAIT_FQS", 4206b50e119SPaul E. McKenney "RCU_GP_DOING_FQS", 4216b50e119SPaul E. McKenney "RCU_GP_CLEANUP", 4226b50e119SPaul E. McKenney "RCU_GP_CLEANED", 4236b50e119SPaul E. McKenney }; 4246b50e119SPaul E. McKenney #endif /* #ifndef RCU_TREE_NONCORE */ 4256b50e119SPaul E. McKenney 4264102adabSPaul E. McKenney extern struct list_head rcu_struct_flavors; 4274102adabSPaul E. McKenney 4284102adabSPaul E. McKenney /* Sequence through rcu_state structures for each RCU flavor. */ 4294102adabSPaul E. McKenney #define for_each_rcu_flavor(rsp) \ 4304102adabSPaul E. McKenney list_for_each_entry((rsp), &rcu_struct_flavors, flavors) 4314102adabSPaul E. McKenney 4324102adabSPaul E. McKenney /* 4334102adabSPaul E. McKenney * RCU implementation internal declarations: 4344102adabSPaul E. McKenney */ 4354102adabSPaul E. McKenney extern struct rcu_state rcu_sched_state; 4364102adabSPaul E. McKenney 4374102adabSPaul E. McKenney extern struct rcu_state rcu_bh_state; 4384102adabSPaul E. McKenney 43928f6569aSPranith Kumar #ifdef CONFIG_PREEMPT_RCU 4404102adabSPaul E. McKenney extern struct rcu_state rcu_preempt_state; 44128f6569aSPranith Kumar #endif /* #ifdef CONFIG_PREEMPT_RCU */ 4424102adabSPaul E. McKenney 44302a5c550SPaul E. McKenney int rcu_dynticks_snap(struct rcu_dynticks *rdtp); 444b8c17e66SPaul E. McKenney bool rcu_eqs_special_set(int cpu); 44502a5c550SPaul E. McKenney 4464102adabSPaul E. McKenney #ifdef CONFIG_RCU_BOOST 4474102adabSPaul E. McKenney DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); 4484102adabSPaul E. McKenney DECLARE_PER_CPU(int, rcu_cpu_kthread_cpu); 4494102adabSPaul E. McKenney DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); 4504102adabSPaul E. McKenney DECLARE_PER_CPU(char, rcu_cpu_has_work); 4514102adabSPaul E. McKenney #endif /* #ifdef CONFIG_RCU_BOOST */ 4524102adabSPaul E. McKenney 4534102adabSPaul E. McKenney #ifndef RCU_TREE_NONCORE 4544102adabSPaul E. McKenney 4554102adabSPaul E. McKenney /* Forward declarations for rcutree_plugin.h */ 4564102adabSPaul E. McKenney static void rcu_bootup_announce(void); 4575b72f964SPaul E. McKenney static void rcu_preempt_note_context_switch(bool preempt); 4584102adabSPaul E. McKenney static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp); 4594102adabSPaul E. McKenney #ifdef CONFIG_HOTPLUG_CPU 4608af3a5e7SPaul E. McKenney static bool rcu_preempt_has_tasks(struct rcu_node *rnp); 4614102adabSPaul E. McKenney #endif /* #ifdef CONFIG_HOTPLUG_CPU */ 4624102adabSPaul E. McKenney static void rcu_print_detail_task_stall(struct rcu_state *rsp); 4634102adabSPaul E. McKenney static int rcu_print_task_stall(struct rcu_node *rnp); 46474611ecbSPaul E. McKenney static int rcu_print_task_exp_stall(struct rcu_node *rnp); 4654102adabSPaul E. McKenney static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); 46686aea0e6SPaul E. McKenney static void rcu_preempt_check_callbacks(void); 467b6a4ae76SBoqun Feng void call_rcu(struct rcu_head *head, rcu_callback_t func); 4684102adabSPaul E. McKenney static void __init __rcu_init_preempt(void); 4694102adabSPaul E. McKenney static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); 4704102adabSPaul E. McKenney static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); 4714102adabSPaul E. McKenney static void invoke_rcu_callbacks_kthread(void); 4724102adabSPaul E. McKenney static bool rcu_is_callbacks_kthread(void); 4734102adabSPaul E. McKenney #ifdef CONFIG_RCU_BOOST 4744102adabSPaul E. McKenney static void rcu_preempt_do_callbacks(void); 4754102adabSPaul E. McKenney static int rcu_spawn_one_boost_kthread(struct rcu_state *rsp, 4764102adabSPaul E. McKenney struct rcu_node *rnp); 4774102adabSPaul E. McKenney #endif /* #ifdef CONFIG_RCU_BOOST */ 4789386c0b7SPaul E. McKenney static void __init rcu_spawn_boost_kthreads(void); 4794102adabSPaul E. McKenney static void rcu_prepare_kthreads(int cpu); 4808fa7845dSPaul E. McKenney static void rcu_cleanup_after_idle(void); 481198bbf81SPaul E. McKenney static void rcu_prepare_for_idle(void); 4824102adabSPaul E. McKenney static void rcu_idle_count_callbacks_posted(void); 4830aa04b05SPaul E. McKenney static bool rcu_preempt_has_tasks(struct rcu_node *rnp); 4844102adabSPaul E. McKenney static void print_cpu_stall_info_begin(void); 4854102adabSPaul E. McKenney static void print_cpu_stall_info(struct rcu_state *rsp, int cpu); 4864102adabSPaul E. McKenney static void print_cpu_stall_info_end(void); 4874102adabSPaul E. McKenney static void zero_cpu_stall_ticks(struct rcu_data *rdp); 4884102adabSPaul E. McKenney static void increment_cpu_stall_ticks(void); 489d7e29933SPaul E. McKenney static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu); 4904102adabSPaul E. McKenney static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq); 491abedf8e2SPaul Gortmaker static struct swait_queue_head *rcu_nocb_gp_get(struct rcu_node *rnp); 492abedf8e2SPaul Gortmaker static void rcu_nocb_gp_cleanup(struct swait_queue_head *sq); 4934102adabSPaul E. McKenney static void rcu_init_one_nocb(struct rcu_node *rnp); 4944102adabSPaul E. McKenney static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, 49596d3fd0dSPaul E. McKenney bool lazy, unsigned long flags); 496*b1a2d79fSPaul E. McKenney static bool rcu_nocb_adopt_orphan_cbs(struct rcu_data *my_rdp, 49796d3fd0dSPaul E. McKenney struct rcu_data *rdp, 49896d3fd0dSPaul E. McKenney unsigned long flags); 4999fdd3bc9SPaul E. McKenney static int rcu_nocb_need_deferred_wakeup(struct rcu_data *rdp); 50096d3fd0dSPaul E. McKenney static void do_nocb_deferred_wakeup(struct rcu_data *rdp); 5014102adabSPaul E. McKenney static void rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp); 50235ce7f29SPaul E. McKenney static void rcu_spawn_all_nocb_kthreads(int cpu); 50335ce7f29SPaul E. McKenney static void __init rcu_spawn_nocb_kthreads(void); 50435ce7f29SPaul E. McKenney #ifdef CONFIG_RCU_NOCB_CPU 50535ce7f29SPaul E. McKenney static void __init rcu_organize_nocb_kthreads(struct rcu_state *rsp); 50635ce7f29SPaul E. McKenney #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ 5074a81e832SPaul E. McKenney static void __maybe_unused rcu_kick_nohz_cpu(int cpu); 5084102adabSPaul E. McKenney static bool init_nocb_callback_list(struct rcu_data *rdp); 5094102adabSPaul E. McKenney static void rcu_bind_gp_kthread(void); 510a096932fSPaul E. McKenney static bool rcu_nohz_full_cpu(struct rcu_state *rsp); 511176f8f7aSPaul E. McKenney static void rcu_dynticks_task_enter(void); 512176f8f7aSPaul E. McKenney static void rcu_dynticks_task_exit(void); 5134102adabSPaul E. McKenney 514da915ad5SPaul E. McKenney #ifdef CONFIG_SRCU 515da915ad5SPaul E. McKenney void srcu_online_cpu(unsigned int cpu); 516da915ad5SPaul E. McKenney void srcu_offline_cpu(unsigned int cpu); 517da915ad5SPaul E. McKenney #else /* #ifdef CONFIG_SRCU */ 518da915ad5SPaul E. McKenney void srcu_online_cpu(unsigned int cpu) { } 519da915ad5SPaul E. McKenney void srcu_offline_cpu(unsigned int cpu) { } 520da915ad5SPaul E. McKenney #endif /* #else #ifdef CONFIG_SRCU */ 521da915ad5SPaul E. McKenney 5224102adabSPaul E. McKenney #endif /* #ifndef RCU_TREE_NONCORE */ 523