xref: /openbmc/linux/include/linux/rcutree.h (revision 43a89bae)
1a9b7343eSPaul E. McKenney /* SPDX-License-Identifier: GPL-2.0+ */
264db4cffSPaul E. McKenney /*
364db4cffSPaul E. McKenney  * Read-Copy Update mechanism for mutual exclusion (tree-based version)
464db4cffSPaul E. McKenney  *
564db4cffSPaul E. McKenney  * Copyright IBM Corporation, 2008
664db4cffSPaul E. McKenney  *
764db4cffSPaul E. McKenney  * Author: Dipankar Sarma <dipankar@in.ibm.com>
8a9b7343eSPaul E. McKenney  *	   Paul E. McKenney <paulmck@linux.ibm.com> Hierarchical algorithm
964db4cffSPaul E. McKenney  *
10a9b7343eSPaul E. McKenney  * Based on the original work by Paul McKenney <paulmck@linux.ibm.com>
1164db4cffSPaul E. McKenney  * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
1264db4cffSPaul E. McKenney  *
1364db4cffSPaul E. McKenney  * For detailed explanation of Read-Copy Update mechanism see -
1464db4cffSPaul E. McKenney  *	Documentation/RCU
1564db4cffSPaul E. McKenney  */
1664db4cffSPaul E. McKenney 
1764db4cffSPaul E. McKenney #ifndef __LINUX_RCUTREE_H
1864db4cffSPaul E. McKenney #define __LINUX_RCUTREE_H
1964db4cffSPaul E. McKenney 
20d28139c4SPaul E. McKenney void rcu_softirq_qs(void);
21bcbfdd01SPaul E. McKenney void rcu_note_context_switch(bool preempt);
2229845399SFrederic Weisbecker int rcu_needs_cpu(void);
23584dc4ceSTeodora Baluta void rcu_cpu_stall_reset(void);
24*43a89baeSPaul E. McKenney void rcu_request_urgent_qs_task(struct task_struct *t);
2564db4cffSPaul E. McKenney 
2629ce8310SGleb Natapov /*
2729ce8310SGleb Natapov  * Note a virtualization-based context switch.  This is simply a
2829ce8310SGleb Natapov  * wrapper around rcu_note_context_switch(), which allows TINY_RCU
2946a5d164SPaul E. McKenney  * to save a few bytes. The caller must have disabled interrupts.
3029ce8310SGleb Natapov  */
rcu_virt_note_context_switch(void)31b5ad0d2eSZeng Heng static inline void rcu_virt_note_context_switch(void)
3229ce8310SGleb Natapov {
33bcbfdd01SPaul E. McKenney 	rcu_note_context_switch(false);
3429ce8310SGleb Natapov }
3529ce8310SGleb Natapov 
36584dc4ceSTeodora Baluta void synchronize_rcu_expedited(void);
3704a522b7SUladzislau Rezki (Sony) void kvfree_call_rcu(struct rcu_head *head, void *ptr);
38486e2593SPaul E. McKenney 
39584dc4ceSTeodora Baluta void rcu_barrier(void);
4017672480SYury Norov bool rcu_eqs_special_set(int cpu);
41366237e7SPaul E. McKenney void rcu_momentary_dyntick_idle(void);
42a35d1690SByungchul Park void kfree_rcu_scheduler_running(void);
436be7436dSPaul E. McKenney bool rcu_gp_might_be_stalled(void);
4491a967fdSPaul E. McKenney 
4591a967fdSPaul E. McKenney struct rcu_gp_oldstate {
4691a967fdSPaul E. McKenney 	unsigned long rgos_norm;
4791a967fdSPaul E. McKenney 	unsigned long rgos_exp;
4891a967fdSPaul E. McKenney };
4991a967fdSPaul E. McKenney 
5018538248SPaul E. McKenney // Maximum number of rcu_gp_oldstate values corresponding to
5118538248SPaul E. McKenney // not-yet-completed RCU grace periods.
5218538248SPaul E. McKenney #define NUM_ACTIVE_RCU_POLL_FULL_OLDSTATE 4
5318538248SPaul E. McKenney 
5418538248SPaul E. McKenney /**
5518538248SPaul E. McKenney  * same_state_synchronize_rcu_full - Are two old-state values identical?
5618538248SPaul E. McKenney  * @rgosp1: First old-state value.
5718538248SPaul E. McKenney  * @rgosp2: Second old-state value.
5818538248SPaul E. McKenney  *
5918538248SPaul E. McKenney  * The two old-state values must have been obtained from either
6018538248SPaul E. McKenney  * get_state_synchronize_rcu_full(), start_poll_synchronize_rcu_full(),
6118538248SPaul E. McKenney  * or get_completed_synchronize_rcu_full().  Returns @true if the two
6218538248SPaul E. McKenney  * values are identical and @false otherwise.  This allows structures
6318538248SPaul E. McKenney  * whose lifetimes are tracked by old-state values to push these values
6418538248SPaul E. McKenney  * to a list header, allowing those structures to be slightly smaller.
6518538248SPaul E. McKenney  *
6618538248SPaul E. McKenney  * Note that equality is judged on a bitwise basis, so that an
6718538248SPaul E. McKenney  * @rcu_gp_oldstate structure with an already-completed state in one field
6818538248SPaul E. McKenney  * will compare not-equal to a structure with an already-completed state
6918538248SPaul E. McKenney  * in the other field.  After all, the @rcu_gp_oldstate structure is opaque
7018538248SPaul E. McKenney  * so how did such a situation come to pass in the first place?
7118538248SPaul E. McKenney  */
same_state_synchronize_rcu_full(struct rcu_gp_oldstate * rgosp1,struct rcu_gp_oldstate * rgosp2)7218538248SPaul E. McKenney static inline bool same_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp1,
7318538248SPaul E. McKenney 						   struct rcu_gp_oldstate *rgosp2)
7418538248SPaul E. McKenney {
7518538248SPaul E. McKenney 	return rgosp1->rgos_norm == rgosp2->rgos_norm && rgosp1->rgos_exp == rgosp2->rgos_exp;
7618538248SPaul E. McKenney }
7718538248SPaul E. McKenney 
78d96c52feSPaul E. McKenney unsigned long start_poll_synchronize_rcu_expedited(void);
796c502b14SPaul E. McKenney void start_poll_synchronize_rcu_expedited_full(struct rcu_gp_oldstate *rgosp);
80d96c52feSPaul E. McKenney void cond_synchronize_rcu_expedited(unsigned long oldstate);
818df13f01SPaul E. McKenney void cond_synchronize_rcu_expedited_full(struct rcu_gp_oldstate *rgosp);
82765a3f4fSPaul E. McKenney unsigned long get_state_synchronize_rcu(void);
833fdefca9SPaul E. McKenney void get_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp);
847abb18bdSPaul E. McKenney unsigned long start_poll_synchronize_rcu(void);
8576ea3641SPaul E. McKenney void start_poll_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp);
867abb18bdSPaul E. McKenney bool poll_state_synchronize_rcu(unsigned long oldstate);
8791a967fdSPaul E. McKenney bool poll_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp);
88765a3f4fSPaul E. McKenney void cond_synchronize_rcu(unsigned long oldstate);
89b6fe4917SPaul E. McKenney void cond_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp);
90a57eb940SPaul E. McKenney 
9107325d4aSThomas Gleixner #ifdef CONFIG_PROVE_RCU
9207325d4aSThomas Gleixner void rcu_irq_exit_check_preempt(void);
9307325d4aSThomas Gleixner #else
rcu_irq_exit_check_preempt(void)9407325d4aSThomas Gleixner static inline void rcu_irq_exit_check_preempt(void) { }
9507325d4aSThomas Gleixner #endif
9607325d4aSThomas Gleixner 
9717211455SFrederic Weisbecker struct task_struct;
9817211455SFrederic Weisbecker void rcu_preempt_deferred_qs(struct task_struct *t);
9917211455SFrederic Weisbecker 
100584dc4ceSTeodora Baluta void exit_rcu(void);
1012439b696SPaul E. McKenney 
102584dc4ceSTeodora Baluta void rcu_scheduler_starting(void);
103e6339d3bSIngo Molnar extern int rcu_scheduler_active;
104d2b1654fSPaul E. McKenney void rcu_end_inkernel_boot(void);
10559ee0326SPaul E. McKenney bool rcu_inkernel_boot_has_ended(void);
106584dc4ceSTeodora Baluta bool rcu_is_watching(void);
10701b1d88bSThomas Gleixner #ifndef CONFIG_PREEMPTION
1085cd37193SPaul E. McKenney void rcu_all_qs(void);
109395a2f09SPaul E. McKenney #endif
1105cd37193SPaul E. McKenney 
1114df83742SThomas Gleixner /* RCUtree hotplug events */
1124df83742SThomas Gleixner int rcutree_prepare_cpu(unsigned int cpu);
1134df83742SThomas Gleixner int rcutree_online_cpu(unsigned int cpu);
1144df83742SThomas Gleixner int rcutree_offline_cpu(unsigned int cpu);
1154df83742SThomas Gleixner int rcutree_dead_cpu(unsigned int cpu);
1164df83742SThomas Gleixner int rcutree_dying_cpu(unsigned int cpu);
117f64c6013SPeter Zijlstra void rcu_cpu_starting(unsigned int cpu);
1184df83742SThomas Gleixner 
11964db4cffSPaul E. McKenney #endif /* __LINUX_RCUTREE_H */
120