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. */ 106*9b9500daSPaul E. McKenney unsigned long ffmask; /* Fully functional CPUs. */ 1074102adabSPaul E. McKenney unsigned long grpmask; /* Mask to apply to parent qsmask. */ 1084102adabSPaul E. McKenney /* Only one bit will be set in this mask. */ 1094102adabSPaul E. McKenney int grplo; /* lowest-numbered CPU or group here. */ 1104102adabSPaul E. McKenney int grphi; /* highest-numbered CPU or group here. */ 1114102adabSPaul E. McKenney u8 grpnum; /* CPU/group number for next level up. */ 1124102adabSPaul E. McKenney u8 level; /* root is at level 0. */ 1130aa04b05SPaul E. McKenney bool wait_blkd_tasks;/* Necessary to wait for blocked tasks to */ 1140aa04b05SPaul E. McKenney /* exit RCU read-side critical sections */ 1150aa04b05SPaul E. McKenney /* before propagating offline up the */ 1160aa04b05SPaul E. McKenney /* rcu_node tree? */ 1174102adabSPaul E. McKenney struct rcu_node *parent; 1184102adabSPaul E. McKenney struct list_head blkd_tasks; 1194102adabSPaul E. McKenney /* Tasks blocked in RCU read-side critical */ 1204102adabSPaul E. McKenney /* section. Tasks are placed at the head */ 1214102adabSPaul E. McKenney /* of this list and age towards the tail. */ 1224102adabSPaul E. McKenney struct list_head *gp_tasks; 1234102adabSPaul E. McKenney /* Pointer to the first task blocking the */ 1244102adabSPaul E. McKenney /* current grace period, or NULL if there */ 1254102adabSPaul E. McKenney /* is no such task. */ 1264102adabSPaul E. McKenney struct list_head *exp_tasks; 1274102adabSPaul E. McKenney /* Pointer to the first task blocking the */ 1284102adabSPaul E. McKenney /* current expedited grace period, or NULL */ 1294102adabSPaul E. McKenney /* if there is no such task. If there */ 1304102adabSPaul E. McKenney /* is no current expedited grace period, */ 1314102adabSPaul E. McKenney /* then there can cannot be any such task. */ 1324102adabSPaul E. McKenney struct list_head *boost_tasks; 1334102adabSPaul E. McKenney /* Pointer to first task that needs to be */ 1344102adabSPaul E. McKenney /* priority boosted, or NULL if no priority */ 1354102adabSPaul E. McKenney /* boosting is needed for this rcu_node */ 1364102adabSPaul E. McKenney /* structure. If there are no tasks */ 1374102adabSPaul E. McKenney /* queued on this rcu_node structure that */ 1384102adabSPaul E. McKenney /* are blocking the current grace period, */ 1394102adabSPaul E. McKenney /* there can be no such task. */ 140abaa93d9SPaul E. McKenney struct rt_mutex boost_mtx; 141abaa93d9SPaul E. McKenney /* Used only for the priority-boosting */ 142abaa93d9SPaul E. McKenney /* side effect, not as a lock. */ 1434102adabSPaul E. McKenney unsigned long boost_time; 1444102adabSPaul E. McKenney /* When to start boosting (jiffies). */ 1454102adabSPaul E. McKenney struct task_struct *boost_kthread_task; 1464102adabSPaul E. McKenney /* kthread that takes care of priority */ 1474102adabSPaul E. McKenney /* boosting for this rcu_node structure. */ 1484102adabSPaul E. McKenney unsigned int boost_kthread_status; 1494102adabSPaul E. McKenney /* State of boost_kthread_task for tracing. */ 1504102adabSPaul E. McKenney unsigned long n_tasks_boosted; 1514102adabSPaul E. McKenney /* Total number of tasks boosted. */ 1524102adabSPaul E. McKenney unsigned long n_exp_boosts; 1534102adabSPaul E. McKenney /* Number of tasks boosted for expedited GP. */ 1544102adabSPaul E. McKenney unsigned long n_normal_boosts; 1554102adabSPaul E. McKenney /* Number of tasks boosted for normal GP. */ 1564102adabSPaul E. McKenney #ifdef CONFIG_RCU_NOCB_CPU 157abedf8e2SPaul Gortmaker struct swait_queue_head nocb_gp_wq[2]; 1584102adabSPaul E. McKenney /* Place for rcu_nocb_kthread() to wait GP. */ 1594102adabSPaul E. McKenney #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ 1604102adabSPaul E. McKenney int need_future_gp[2]; 1614102adabSPaul E. McKenney /* Counts of upcoming no-CB GP requests. */ 1624102adabSPaul E. McKenney raw_spinlock_t fqslock ____cacheline_internodealigned_in_smp; 163385b73c0SPaul E. McKenney 164f6a12f34SPaul E. McKenney spinlock_t exp_lock ____cacheline_internodealigned_in_smp; 165f6a12f34SPaul E. McKenney unsigned long exp_seq_rq; 1663b5f668eSPaul E. McKenney wait_queue_head_t exp_wq[4]; 1674102adabSPaul E. McKenney } ____cacheline_internodealigned_in_smp; 1684102adabSPaul E. McKenney 1694102adabSPaul E. McKenney /* 170bc75e999SMark Rutland * Bitmasks in an rcu_node cover the interval [grplo, grphi] of CPU IDs, and 171bc75e999SMark Rutland * are indexed relative to this interval rather than the global CPU ID space. 172bc75e999SMark Rutland * This generates the bit for a CPU in node-local masks. 173bc75e999SMark Rutland */ 174bc75e999SMark Rutland #define leaf_node_cpu_bit(rnp, cpu) (1UL << ((cpu) - (rnp)->grplo)) 175bc75e999SMark Rutland 176bc75e999SMark Rutland /* 1775b74c458SPaul E. McKenney * Union to allow "aggregate OR" operation on the need for a quiescent 1785b74c458SPaul E. McKenney * state by the normal and expedited grace periods. 1795b74c458SPaul E. McKenney */ 1805b74c458SPaul E. McKenney union rcu_noqs { 1815b74c458SPaul E. McKenney struct { 1825b74c458SPaul E. McKenney u8 norm; 1835b74c458SPaul E. McKenney u8 exp; 1845b74c458SPaul E. McKenney } b; /* Bits. */ 1855b74c458SPaul E. McKenney u16 s; /* Set of bits, aggregate OR here. */ 1865b74c458SPaul E. McKenney }; 1875b74c458SPaul E. McKenney 1884102adabSPaul E. McKenney /* Index values for nxttail array in struct rcu_data. */ 1894102adabSPaul E. McKenney #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ 1904102adabSPaul E. McKenney #define RCU_WAIT_TAIL 1 /* Also RCU_NEXT_READY head. */ 1914102adabSPaul E. McKenney #define RCU_NEXT_READY_TAIL 2 /* Also RCU_NEXT head. */ 1924102adabSPaul E. McKenney #define RCU_NEXT_TAIL 3 1934102adabSPaul E. McKenney #define RCU_NEXT_SIZE 4 1944102adabSPaul E. McKenney 1954102adabSPaul E. McKenney /* Per-CPU data for read-copy update. */ 1964102adabSPaul E. McKenney struct rcu_data { 1974102adabSPaul E. McKenney /* 1) quiescent-state and grace-period handling : */ 1984102adabSPaul E. McKenney unsigned long completed; /* Track rsp->completed gp number */ 1994102adabSPaul E. McKenney /* in order to detect GP end. */ 2004102adabSPaul E. McKenney unsigned long gpnum; /* Highest gp number that this CPU */ 2014102adabSPaul E. McKenney /* is aware of having started. */ 2025cd37193SPaul E. McKenney unsigned long rcu_qs_ctr_snap;/* Snapshot of rcu_qs_ctr to check */ 2035cd37193SPaul E. McKenney /* for rcu_all_qs() invocations. */ 2045b74c458SPaul E. McKenney union rcu_noqs cpu_no_qs; /* No QSes yet for this CPU. */ 20597c668b8SPaul E. McKenney bool core_needs_qs; /* Core waits for quiesc state. */ 2064102adabSPaul E. McKenney bool beenonline; /* CPU online at least once. */ 207e3663b10SPaul E. McKenney bool gpwrap; /* Possible gpnum/completed wrap. */ 2084102adabSPaul E. McKenney struct rcu_node *mynode; /* This CPU's leaf of hierarchy */ 2094102adabSPaul E. McKenney unsigned long grpmask; /* Mask to apply to leaf qsmask. */ 2104102adabSPaul E. McKenney unsigned long ticks_this_gp; /* The number of scheduling-clock */ 2114102adabSPaul E. McKenney /* ticks this CPU has handled */ 2124102adabSPaul E. McKenney /* during and after the last grace */ 2134102adabSPaul E. McKenney /* period it is aware of. */ 2144102adabSPaul E. McKenney 2154102adabSPaul E. McKenney /* 2) batch handling */ 21615fecf89SPaul E. McKenney struct rcu_segcblist cblist; /* Segmented callback list, with */ 21715fecf89SPaul E. McKenney /* different callbacks waiting for */ 21815fecf89SPaul E. McKenney /* different grace periods. */ 2194102adabSPaul E. McKenney long qlen_last_fqs_check; 2204102adabSPaul E. McKenney /* qlen at last check for QS forcing */ 2214102adabSPaul E. McKenney unsigned long n_cbs_invoked; /* count of RCU cbs invoked. */ 2224102adabSPaul E. McKenney unsigned long n_nocbs_invoked; /* count of no-CBs RCU cbs invoked. */ 2234102adabSPaul E. McKenney unsigned long n_force_qs_snap; 2244102adabSPaul E. McKenney /* did other CPU force QS recently? */ 2254102adabSPaul E. McKenney long blimit; /* Upper limit on a processed batch */ 2264102adabSPaul E. McKenney 2274102adabSPaul E. McKenney /* 3) dynticks interface. */ 2284102adabSPaul E. McKenney struct rcu_dynticks *dynticks; /* Shared per-CPU dynticks state. */ 2294102adabSPaul E. McKenney int dynticks_snap; /* Per-GP tracking for dynticks. */ 2304102adabSPaul E. McKenney 2314102adabSPaul E. McKenney /* 4) reasons this CPU needed to be kicked by force_quiescent_state */ 2324102adabSPaul E. McKenney unsigned long dynticks_fqs; /* Kicked due to dynticks idle. */ 2334102adabSPaul E. McKenney unsigned long offline_fqs; /* Kicked due to being offline. */ 2344a81e832SPaul E. McKenney unsigned long cond_resched_completed; 2354a81e832SPaul E. McKenney /* Grace period that needs help */ 2364a81e832SPaul E. McKenney /* from cond_resched(). */ 2374102adabSPaul E. McKenney 2384102adabSPaul E. McKenney /* 5) __rcu_pending() statistics. */ 2394102adabSPaul E. McKenney unsigned long n_rcu_pending; /* rcu_pending() calls since boot. */ 24097c668b8SPaul E. McKenney unsigned long n_rp_core_needs_qs; 2414102adabSPaul E. McKenney unsigned long n_rp_report_qs; 2424102adabSPaul E. McKenney unsigned long n_rp_cb_ready; 2434102adabSPaul E. McKenney unsigned long n_rp_cpu_needs_gp; 2444102adabSPaul E. McKenney unsigned long n_rp_gp_completed; 2454102adabSPaul E. McKenney unsigned long n_rp_gp_started; 24696d3fd0dSPaul E. McKenney unsigned long n_rp_nocb_defer_wakeup; 2474102adabSPaul E. McKenney unsigned long n_rp_need_nothing; 2484102adabSPaul E. McKenney 2492cd6ffafSPaul E. McKenney /* 6) _rcu_barrier(), OOM callbacks, and expediting. */ 2504102adabSPaul E. McKenney struct rcu_head barrier_head; 2514102adabSPaul E. McKenney #ifdef CONFIG_RCU_FAST_NO_HZ 2524102adabSPaul E. McKenney struct rcu_head oom_head; 2534102adabSPaul E. McKenney #endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ 2548b355e3bSPaul E. McKenney atomic_long_t exp_workdone0; /* # done by workqueue. */ 255d40a4f09SPaul E. McKenney atomic_long_t exp_workdone1; /* # done by others #1. */ 256d40a4f09SPaul E. McKenney atomic_long_t exp_workdone2; /* # done by others #2. */ 257d40a4f09SPaul E. McKenney atomic_long_t exp_workdone3; /* # done by others #3. */ 2580742ac3eSPaul E. McKenney int exp_dynticks_snap; /* Double-check need for IPI. */ 2594102adabSPaul E. McKenney 2604102adabSPaul E. McKenney /* 7) Callback offloading. */ 2614102adabSPaul E. McKenney #ifdef CONFIG_RCU_NOCB_CPU 2624102adabSPaul E. McKenney struct rcu_head *nocb_head; /* CBs waiting for kthread. */ 2634102adabSPaul E. McKenney struct rcu_head **nocb_tail; 26441050a00SPaul E. McKenney atomic_long_t nocb_q_count; /* # CBs waiting for nocb */ 26541050a00SPaul E. McKenney atomic_long_t nocb_q_count_lazy; /* invocation (all stages). */ 266fbce7497SPaul E. McKenney struct rcu_head *nocb_follower_head; /* CBs ready to invoke. */ 267fbce7497SPaul E. McKenney struct rcu_head **nocb_follower_tail; 268abedf8e2SPaul Gortmaker struct swait_queue_head nocb_wq; /* For nocb kthreads to sleep on. */ 2694102adabSPaul E. McKenney struct task_struct *nocb_kthread; 2708be6e1b1SPaul E. McKenney raw_spinlock_t nocb_lock; /* Guard following pair of fields. */ 2719fdd3bc9SPaul E. McKenney int nocb_defer_wakeup; /* Defer wakeup of nocb_kthread. */ 2728be6e1b1SPaul E. McKenney struct timer_list nocb_timer; /* Enforce finite deferral. */ 273fbce7497SPaul E. McKenney 274fbce7497SPaul E. McKenney /* The following fields are used by the leader, hence own cacheline. */ 275fbce7497SPaul E. McKenney struct rcu_head *nocb_gp_head ____cacheline_internodealigned_in_smp; 276fbce7497SPaul E. McKenney /* CBs waiting for GP. */ 277fbce7497SPaul E. McKenney struct rcu_head **nocb_gp_tail; 27811ed7f93SPranith Kumar bool nocb_leader_sleep; /* Is the nocb leader thread asleep? */ 279fbce7497SPaul E. McKenney struct rcu_data *nocb_next_follower; 280fbce7497SPaul E. McKenney /* Next follower in wakeup chain. */ 281fbce7497SPaul E. McKenney 282fbce7497SPaul E. McKenney /* The following fields are used by the follower, hence new cachline. */ 283fbce7497SPaul E. McKenney struct rcu_data *nocb_leader ____cacheline_internodealigned_in_smp; 284fbce7497SPaul E. McKenney /* Leader CPU takes GP-end wakeups. */ 2854102adabSPaul E. McKenney #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ 2864102adabSPaul E. McKenney 2874102adabSPaul E. McKenney /* 8) RCU CPU stall data. */ 2884102adabSPaul E. McKenney unsigned int softirq_snap; /* Snapshot of softirq activity. */ 289*9b9500daSPaul E. McKenney /* ->rcu_iw* fields protected by leaf rcu_node ->lock. */ 290*9b9500daSPaul E. McKenney struct irq_work rcu_iw; /* Check for non-irq activity. */ 291*9b9500daSPaul E. McKenney bool rcu_iw_pending; /* Is ->rcu_iw pending? */ 292*9b9500daSPaul E. McKenney unsigned long rcu_iw_gpnum; /* ->gpnum associated with ->rcu_iw. */ 2934102adabSPaul E. McKenney 2944102adabSPaul E. McKenney int cpu; 2954102adabSPaul E. McKenney struct rcu_state *rsp; 2964102adabSPaul E. McKenney }; 2974102adabSPaul E. McKenney 2989fdd3bc9SPaul E. McKenney /* Values for nocb_defer_wakeup field in struct rcu_data. */ 299511324e4SPaul E. McKenney #define RCU_NOCB_WAKE_NOT 0 300511324e4SPaul E. McKenney #define RCU_NOCB_WAKE 1 301511324e4SPaul E. McKenney #define RCU_NOCB_WAKE_FORCE 2 3029fdd3bc9SPaul E. McKenney 3034102adabSPaul E. McKenney #define RCU_JIFFIES_TILL_FORCE_QS (1 + (HZ > 250) + (HZ > 500)) 3044102adabSPaul E. McKenney /* For jiffies_till_first_fqs and */ 3054102adabSPaul E. McKenney /* and jiffies_till_next_fqs. */ 3064102adabSPaul E. McKenney 3074102adabSPaul E. McKenney #define RCU_JIFFIES_FQS_DIV 256 /* Very large systems need more */ 3084102adabSPaul E. McKenney /* delay between bouts of */ 3094102adabSPaul E. McKenney /* quiescent-state forcing. */ 3104102adabSPaul E. McKenney 3114102adabSPaul E. McKenney #define RCU_STALL_RAT_DELAY 2 /* Allow other CPUs time to take */ 3124102adabSPaul E. McKenney /* at least one scheduling clock */ 3134102adabSPaul E. McKenney /* irq before ratting on them. */ 3144102adabSPaul E. McKenney 3154102adabSPaul E. McKenney #define rcu_wait(cond) \ 3164102adabSPaul E. McKenney do { \ 3174102adabSPaul E. McKenney for (;;) { \ 3184102adabSPaul E. McKenney set_current_state(TASK_INTERRUPTIBLE); \ 3194102adabSPaul E. McKenney if (cond) \ 3204102adabSPaul E. McKenney break; \ 3214102adabSPaul E. McKenney schedule(); \ 3224102adabSPaul E. McKenney } \ 3234102adabSPaul E. McKenney __set_current_state(TASK_RUNNING); \ 3244102adabSPaul E. McKenney } while (0) 3254102adabSPaul E. McKenney 3264102adabSPaul E. McKenney /* 3274102adabSPaul E. McKenney * RCU global state, including node hierarchy. This hierarchy is 3284102adabSPaul E. McKenney * represented in "heap" form in a dense array. The root (first level) 3294102adabSPaul E. McKenney * of the hierarchy is in ->node[0] (referenced by ->level[0]), the second 3304102adabSPaul E. McKenney * level in ->node[1] through ->node[m] (->node[1] referenced by ->level[1]), 3314102adabSPaul E. McKenney * and the third level in ->node[m+1] and following (->node[m+1] referenced 3324102adabSPaul E. McKenney * by ->level[2]). The number of levels is determined by the number of 3334102adabSPaul E. McKenney * CPUs and by CONFIG_RCU_FANOUT. Small systems will have a "hierarchy" 3344102adabSPaul E. McKenney * consisting of a single rcu_node. 3354102adabSPaul E. McKenney */ 3364102adabSPaul E. McKenney struct rcu_state { 3374102adabSPaul E. McKenney struct rcu_node node[NUM_RCU_NODES]; /* Hierarchy. */ 338032dfc87SAlexander Gordeev struct rcu_node *level[RCU_NUM_LVLS + 1]; 339032dfc87SAlexander Gordeev /* Hierarchy levels (+1 to */ 340032dfc87SAlexander Gordeev /* shut bogus gcc warning) */ 3414102adabSPaul E. McKenney struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ 342db3e8db4SBoqun Feng call_rcu_func_t call; /* call_rcu() flavor. */ 343b9585e94SPaul E. McKenney int ncpus; /* # CPUs seen so far. */ 3444102adabSPaul E. McKenney 3454102adabSPaul E. McKenney /* The following fields are guarded by the root rcu_node's lock. */ 3464102adabSPaul E. McKenney 34777f81fe0SPetr Mladek u8 boost ____cacheline_internodealigned_in_smp; 34877f81fe0SPetr Mladek /* Subject to priority boost. */ 3494102adabSPaul E. McKenney unsigned long gpnum; /* Current gp number. */ 3504102adabSPaul E. McKenney unsigned long completed; /* # of last completed gp. */ 3514102adabSPaul E. McKenney struct task_struct *gp_kthread; /* Task for grace periods. */ 352abedf8e2SPaul Gortmaker struct swait_queue_head gp_wq; /* Where GP task waits. */ 353afea227fSPaul E. McKenney short gp_flags; /* Commands for GP task. */ 354afea227fSPaul E. McKenney short gp_state; /* GP kthread sleep state. */ 3554102adabSPaul E. McKenney 3564102adabSPaul E. McKenney /* End of fields guarded by root rcu_node's lock. */ 3574102adabSPaul E. McKenney 3584102adabSPaul E. McKenney struct mutex barrier_mutex; /* Guards barrier fields. */ 3594102adabSPaul E. McKenney atomic_t barrier_cpu_count; /* # CPUs waiting on. */ 3604102adabSPaul E. McKenney struct completion barrier_completion; /* Wake at barrier end. */ 3614f525a52SPaul E. McKenney unsigned long barrier_sequence; /* ++ at start and end of */ 3624102adabSPaul E. McKenney /* _rcu_barrier(). */ 3634102adabSPaul E. McKenney /* End of fields guarded by barrier_mutex. */ 3644102adabSPaul E. McKenney 365f6a12f34SPaul E. McKenney struct mutex exp_mutex; /* Serialize expedited GP. */ 3663b5f668eSPaul E. McKenney struct mutex exp_wake_mutex; /* Serialize wakeup. */ 367d6ada2cfSPaul E. McKenney unsigned long expedited_sequence; /* Take a ticket. */ 3683a6d7c64SPeter Zijlstra atomic_t expedited_need_qs; /* # CPUs left to check in. */ 369abedf8e2SPaul Gortmaker struct swait_queue_head expedited_wq; /* Wait for check-ins. */ 370b9585e94SPaul E. McKenney int ncpus_snap; /* # CPUs seen last time. */ 3714102adabSPaul E. McKenney 3724102adabSPaul E. McKenney unsigned long jiffies_force_qs; /* Time at which to invoke */ 3734102adabSPaul E. McKenney /* force_quiescent_state(). */ 3748c7c4829SPaul E. McKenney unsigned long jiffies_kick_kthreads; /* Time at which to kick */ 3758c7c4829SPaul E. McKenney /* kthreads, if configured. */ 3764102adabSPaul E. McKenney unsigned long n_force_qs; /* Number of calls to */ 3774102adabSPaul E. McKenney /* force_quiescent_state(). */ 3784102adabSPaul E. McKenney unsigned long n_force_qs_lh; /* ~Number of calls leaving */ 3794102adabSPaul E. McKenney /* due to lock unavailable. */ 3804102adabSPaul E. McKenney unsigned long n_force_qs_ngp; /* Number of calls leaving */ 3814102adabSPaul E. McKenney /* due to no GP active. */ 3824102adabSPaul E. McKenney unsigned long gp_start; /* Time at which GP started, */ 3834102adabSPaul E. McKenney /* but in jiffies. */ 3846ccd2ecdSPaul E. McKenney unsigned long gp_activity; /* Time of last GP kthread */ 3856ccd2ecdSPaul E. McKenney /* activity in jiffies. */ 3864102adabSPaul E. McKenney unsigned long jiffies_stall; /* Time at which to check */ 3874102adabSPaul E. McKenney /* for CPU stalls. */ 3886193c76aSPaul E. McKenney unsigned long jiffies_resched; /* Time at which to resched */ 3896193c76aSPaul E. McKenney /* a reluctant CPU. */ 390fc908ed3SPaul E. McKenney unsigned long n_force_qs_gpstart; /* Snapshot of n_force_qs at */ 391fc908ed3SPaul E. McKenney /* GP start. */ 3924102adabSPaul E. McKenney unsigned long gp_max; /* Maximum GP duration in */ 3934102adabSPaul E. McKenney /* jiffies. */ 3944102adabSPaul E. McKenney const char *name; /* Name of structure. */ 3954102adabSPaul E. McKenney char abbr; /* Abbreviated name. */ 3964102adabSPaul E. McKenney struct list_head flavors; /* List of RCU flavors. */ 3974102adabSPaul E. McKenney }; 3984102adabSPaul E. McKenney 3994102adabSPaul E. McKenney /* Values for rcu_state structure's gp_flags field. */ 4004102adabSPaul E. McKenney #define RCU_GP_FLAG_INIT 0x1 /* Need grace-period initialization. */ 4014102adabSPaul E. McKenney #define RCU_GP_FLAG_FQS 0x2 /* Need grace-period quiescent-state forcing. */ 4024102adabSPaul E. McKenney 403c34d2f41SPaul E. McKenney /* Values for rcu_state structure's gp_state field. */ 40477f81fe0SPetr Mladek #define RCU_GP_IDLE 0 /* Initial state and no GP in progress. */ 405afea227fSPaul E. McKenney #define RCU_GP_WAIT_GPS 1 /* Wait for grace-period start. */ 406319362c9SPaul E. McKenney #define RCU_GP_DONE_GPS 2 /* Wait done for grace-period start. */ 407319362c9SPaul E. McKenney #define RCU_GP_WAIT_FQS 3 /* Wait for force-quiescent-state time. */ 40832bb1c79SPaul E. McKenney #define RCU_GP_DOING_FQS 4 /* Wait done for force-quiescent-state time. */ 409319362c9SPaul E. McKenney #define RCU_GP_CLEANUP 5 /* Grace-period cleanup started. */ 410319362c9SPaul E. McKenney #define RCU_GP_CLEANED 6 /* Grace-period cleanup complete. */ 411afea227fSPaul E. McKenney 4126b50e119SPaul E. McKenney #ifndef RCU_TREE_NONCORE 4136b50e119SPaul E. McKenney static const char * const gp_state_names[] = { 4146b50e119SPaul E. McKenney "RCU_GP_IDLE", 4156b50e119SPaul E. McKenney "RCU_GP_WAIT_GPS", 4166b50e119SPaul E. McKenney "RCU_GP_DONE_GPS", 4176b50e119SPaul E. McKenney "RCU_GP_WAIT_FQS", 4186b50e119SPaul E. McKenney "RCU_GP_DOING_FQS", 4196b50e119SPaul E. McKenney "RCU_GP_CLEANUP", 4206b50e119SPaul E. McKenney "RCU_GP_CLEANED", 4216b50e119SPaul E. McKenney }; 4226b50e119SPaul E. McKenney #endif /* #ifndef RCU_TREE_NONCORE */ 4236b50e119SPaul E. McKenney 4244102adabSPaul E. McKenney extern struct list_head rcu_struct_flavors; 4254102adabSPaul E. McKenney 4264102adabSPaul E. McKenney /* Sequence through rcu_state structures for each RCU flavor. */ 4274102adabSPaul E. McKenney #define for_each_rcu_flavor(rsp) \ 4284102adabSPaul E. McKenney list_for_each_entry((rsp), &rcu_struct_flavors, flavors) 4294102adabSPaul E. McKenney 4304102adabSPaul E. McKenney /* 4314102adabSPaul E. McKenney * RCU implementation internal declarations: 4324102adabSPaul E. McKenney */ 4334102adabSPaul E. McKenney extern struct rcu_state rcu_sched_state; 4344102adabSPaul E. McKenney 4354102adabSPaul E. McKenney extern struct rcu_state rcu_bh_state; 4364102adabSPaul E. McKenney 43728f6569aSPranith Kumar #ifdef CONFIG_PREEMPT_RCU 4384102adabSPaul E. McKenney extern struct rcu_state rcu_preempt_state; 43928f6569aSPranith Kumar #endif /* #ifdef CONFIG_PREEMPT_RCU */ 4404102adabSPaul E. McKenney 44102a5c550SPaul E. McKenney int rcu_dynticks_snap(struct rcu_dynticks *rdtp); 442b8c17e66SPaul E. McKenney bool rcu_eqs_special_set(int cpu); 44302a5c550SPaul E. McKenney 4444102adabSPaul E. McKenney #ifdef CONFIG_RCU_BOOST 4454102adabSPaul E. McKenney DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); 4464102adabSPaul E. McKenney DECLARE_PER_CPU(int, rcu_cpu_kthread_cpu); 4474102adabSPaul E. McKenney DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); 4484102adabSPaul E. McKenney DECLARE_PER_CPU(char, rcu_cpu_has_work); 4494102adabSPaul E. McKenney #endif /* #ifdef CONFIG_RCU_BOOST */ 4504102adabSPaul E. McKenney 4514102adabSPaul E. McKenney #ifndef RCU_TREE_NONCORE 4524102adabSPaul E. McKenney 4534102adabSPaul E. McKenney /* Forward declarations for rcutree_plugin.h */ 4544102adabSPaul E. McKenney static void rcu_bootup_announce(void); 4555b72f964SPaul E. McKenney static void rcu_preempt_note_context_switch(bool preempt); 4564102adabSPaul E. McKenney static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp); 4574102adabSPaul E. McKenney #ifdef CONFIG_HOTPLUG_CPU 4588af3a5e7SPaul E. McKenney static bool rcu_preempt_has_tasks(struct rcu_node *rnp); 4594102adabSPaul E. McKenney #endif /* #ifdef CONFIG_HOTPLUG_CPU */ 4604102adabSPaul E. McKenney static void rcu_print_detail_task_stall(struct rcu_state *rsp); 4614102adabSPaul E. McKenney static int rcu_print_task_stall(struct rcu_node *rnp); 46274611ecbSPaul E. McKenney static int rcu_print_task_exp_stall(struct rcu_node *rnp); 4634102adabSPaul E. McKenney static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); 46486aea0e6SPaul E. McKenney static void rcu_preempt_check_callbacks(void); 465b6a4ae76SBoqun Feng void call_rcu(struct rcu_head *head, rcu_callback_t func); 4664102adabSPaul E. McKenney static void __init __rcu_init_preempt(void); 4674102adabSPaul E. McKenney static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); 4684102adabSPaul E. McKenney static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); 4694102adabSPaul E. McKenney static void invoke_rcu_callbacks_kthread(void); 4704102adabSPaul E. McKenney static bool rcu_is_callbacks_kthread(void); 4714102adabSPaul E. McKenney #ifdef CONFIG_RCU_BOOST 4724102adabSPaul E. McKenney static void rcu_preempt_do_callbacks(void); 4734102adabSPaul E. McKenney static int rcu_spawn_one_boost_kthread(struct rcu_state *rsp, 4744102adabSPaul E. McKenney struct rcu_node *rnp); 4754102adabSPaul E. McKenney #endif /* #ifdef CONFIG_RCU_BOOST */ 4769386c0b7SPaul E. McKenney static void __init rcu_spawn_boost_kthreads(void); 4774102adabSPaul E. McKenney static void rcu_prepare_kthreads(int cpu); 4788fa7845dSPaul E. McKenney static void rcu_cleanup_after_idle(void); 479198bbf81SPaul E. McKenney static void rcu_prepare_for_idle(void); 4804102adabSPaul E. McKenney static void rcu_idle_count_callbacks_posted(void); 4810aa04b05SPaul E. McKenney static bool rcu_preempt_has_tasks(struct rcu_node *rnp); 4824102adabSPaul E. McKenney static void print_cpu_stall_info_begin(void); 4834102adabSPaul E. McKenney static void print_cpu_stall_info(struct rcu_state *rsp, int cpu); 4844102adabSPaul E. McKenney static void print_cpu_stall_info_end(void); 4854102adabSPaul E. McKenney static void zero_cpu_stall_ticks(struct rcu_data *rdp); 4864102adabSPaul E. McKenney static void increment_cpu_stall_ticks(void); 487d7e29933SPaul E. McKenney static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu); 4884102adabSPaul E. McKenney static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq); 489abedf8e2SPaul Gortmaker static struct swait_queue_head *rcu_nocb_gp_get(struct rcu_node *rnp); 490abedf8e2SPaul Gortmaker static void rcu_nocb_gp_cleanup(struct swait_queue_head *sq); 4914102adabSPaul E. McKenney static void rcu_init_one_nocb(struct rcu_node *rnp); 4924102adabSPaul E. McKenney static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, 49396d3fd0dSPaul E. McKenney bool lazy, unsigned long flags); 494b1a2d79fSPaul E. McKenney static bool rcu_nocb_adopt_orphan_cbs(struct rcu_data *my_rdp, 49596d3fd0dSPaul E. McKenney struct rcu_data *rdp, 49696d3fd0dSPaul E. McKenney unsigned long flags); 4979fdd3bc9SPaul E. McKenney static int rcu_nocb_need_deferred_wakeup(struct rcu_data *rdp); 49896d3fd0dSPaul E. McKenney static void do_nocb_deferred_wakeup(struct rcu_data *rdp); 4994102adabSPaul E. McKenney static void rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp); 50035ce7f29SPaul E. McKenney static void rcu_spawn_all_nocb_kthreads(int cpu); 50135ce7f29SPaul E. McKenney static void __init rcu_spawn_nocb_kthreads(void); 50235ce7f29SPaul E. McKenney #ifdef CONFIG_RCU_NOCB_CPU 50335ce7f29SPaul E. McKenney static void __init rcu_organize_nocb_kthreads(struct rcu_state *rsp); 50435ce7f29SPaul E. McKenney #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ 5054a81e832SPaul E. McKenney static void __maybe_unused rcu_kick_nohz_cpu(int cpu); 5064102adabSPaul E. McKenney static bool init_nocb_callback_list(struct rcu_data *rdp); 5074102adabSPaul E. McKenney static void rcu_bind_gp_kthread(void); 508a096932fSPaul E. McKenney static bool rcu_nohz_full_cpu(struct rcu_state *rsp); 509176f8f7aSPaul E. McKenney static void rcu_dynticks_task_enter(void); 510176f8f7aSPaul E. McKenney static void rcu_dynticks_task_exit(void); 5114102adabSPaul E. McKenney 512da915ad5SPaul E. McKenney #ifdef CONFIG_SRCU 513da915ad5SPaul E. McKenney void srcu_online_cpu(unsigned int cpu); 514da915ad5SPaul E. McKenney void srcu_offline_cpu(unsigned int cpu); 515da915ad5SPaul E. McKenney #else /* #ifdef CONFIG_SRCU */ 516da915ad5SPaul E. McKenney void srcu_online_cpu(unsigned int cpu) { } 517da915ad5SPaul E. McKenney void srcu_offline_cpu(unsigned int cpu) { } 518da915ad5SPaul E. McKenney #endif /* #else #ifdef CONFIG_SRCU */ 519da915ad5SPaul E. McKenney 5204102adabSPaul E. McKenney #endif /* #ifndef RCU_TREE_NONCORE */ 521