diff options
Diffstat (limited to 'include/linux/rcupreempt.h')
| -rw-r--r-- | include/linux/rcupreempt.h | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/include/linux/rcupreempt.h b/include/linux/rcupreempt.h index 8a05c7e20bc4..f04b64eca636 100644 --- a/include/linux/rcupreempt.h +++ b/include/linux/rcupreempt.h | |||
| @@ -40,10 +40,39 @@ | |||
| 40 | #include <linux/cpumask.h> | 40 | #include <linux/cpumask.h> |
| 41 | #include <linux/seqlock.h> | 41 | #include <linux/seqlock.h> |
| 42 | 42 | ||
| 43 | #define rcu_qsctr_inc(cpu) | 43 | struct rcu_dyntick_sched { |
| 44 | int dynticks; | ||
| 45 | int dynticks_snap; | ||
| 46 | int sched_qs; | ||
| 47 | int sched_qs_snap; | ||
| 48 | int sched_dynticks_snap; | ||
| 49 | }; | ||
| 50 | |||
| 51 | DECLARE_PER_CPU(struct rcu_dyntick_sched, rcu_dyntick_sched); | ||
| 52 | |||
| 53 | static inline void rcu_qsctr_inc(int cpu) | ||
| 54 | { | ||
| 55 | struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu); | ||
| 56 | |||
| 57 | rdssp->sched_qs++; | ||
| 58 | } | ||
| 44 | #define rcu_bh_qsctr_inc(cpu) | 59 | #define rcu_bh_qsctr_inc(cpu) |
| 45 | #define call_rcu_bh(head, rcu) call_rcu(head, rcu) | 60 | #define call_rcu_bh(head, rcu) call_rcu(head, rcu) |
| 46 | 61 | ||
| 62 | /** | ||
| 63 | * call_rcu_sched - Queue RCU callback for invocation after sched grace period. | ||
| 64 | * @head: structure to be used for queueing the RCU updates. | ||
| 65 | * @func: actual update function to be invoked after the grace period | ||
| 66 | * | ||
| 67 | * The update function will be invoked some time after a full | ||
| 68 | * synchronize_sched()-style grace period elapses, in other words after | ||
| 69 | * all currently executing preempt-disabled sections of code (including | ||
| 70 | * hardirq handlers, NMI handlers, and local_irq_save() blocks) have | ||
| 71 | * completed. | ||
| 72 | */ | ||
| 73 | extern void call_rcu_sched(struct rcu_head *head, | ||
| 74 | void (*func)(struct rcu_head *head)); | ||
| 75 | |||
| 47 | extern void __rcu_read_lock(void) __acquires(RCU); | 76 | extern void __rcu_read_lock(void) __acquires(RCU); |
| 48 | extern void __rcu_read_unlock(void) __releases(RCU); | 77 | extern void __rcu_read_unlock(void) __releases(RCU); |
| 49 | extern int rcu_pending(int cpu); | 78 | extern int rcu_pending(int cpu); |
| @@ -55,6 +84,7 @@ extern int rcu_needs_cpu(int cpu); | |||
| 55 | extern void __synchronize_sched(void); | 84 | extern void __synchronize_sched(void); |
| 56 | 85 | ||
| 57 | extern void __rcu_init(void); | 86 | extern void __rcu_init(void); |
| 87 | extern void rcu_init_sched(void); | ||
| 58 | extern void rcu_check_callbacks(int cpu, int user); | 88 | extern void rcu_check_callbacks(int cpu, int user); |
| 59 | extern void rcu_restart_cpu(int cpu); | 89 | extern void rcu_restart_cpu(int cpu); |
| 60 | extern long rcu_batches_completed(void); | 90 | extern long rcu_batches_completed(void); |
| @@ -81,20 +111,20 @@ extern struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu); | |||
| 81 | struct softirq_action; | 111 | struct softirq_action; |
| 82 | 112 | ||
| 83 | #ifdef CONFIG_NO_HZ | 113 | #ifdef CONFIG_NO_HZ |
| 84 | DECLARE_PER_CPU(long, dynticks_progress_counter); | 114 | DECLARE_PER_CPU(struct rcu_dyntick_sched, rcu_dyntick_sched); |
| 85 | 115 | ||
| 86 | static inline void rcu_enter_nohz(void) | 116 | static inline void rcu_enter_nohz(void) |
| 87 | { | 117 | { |
| 88 | smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */ | 118 | smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */ |
| 89 | __get_cpu_var(dynticks_progress_counter)++; | 119 | __get_cpu_var(rcu_dyntick_sched).dynticks++; |
| 90 | WARN_ON(__get_cpu_var(dynticks_progress_counter) & 0x1); | 120 | WARN_ON(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1); |
| 91 | } | 121 | } |
| 92 | 122 | ||
| 93 | static inline void rcu_exit_nohz(void) | 123 | static inline void rcu_exit_nohz(void) |
| 94 | { | 124 | { |
| 95 | __get_cpu_var(dynticks_progress_counter)++; | ||
| 96 | smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ | 125 | smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ |
| 97 | WARN_ON(!(__get_cpu_var(dynticks_progress_counter) & 0x1)); | 126 | __get_cpu_var(rcu_dyntick_sched).dynticks++; |
| 127 | WARN_ON(!(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1)); | ||
| 98 | } | 128 | } |
| 99 | 129 | ||
| 100 | #else /* CONFIG_NO_HZ */ | 130 | #else /* CONFIG_NO_HZ */ |
