diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-31 12:43:41 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-31 12:43:41 -0400 |
commit | 85e9ca333d03fbd56b9e123c8456f0d98e20faad (patch) | |
tree | 7bb15ada5f536950efa23ad60ea9eea60380ca1c /include/linux/rcupreempt.h | |
parent | a300bec952127d9a15e666b391bb35c9aecb3002 (diff) | |
parent | 6e86841d05f371b5b9b86ce76c02aaee83352298 (diff) |
Merge branch 'linus' into timers/hpet
Diffstat (limited to 'include/linux/rcupreempt.h')
-rw-r--r-- | include/linux/rcupreempt.h | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/include/linux/rcupreempt.h b/include/linux/rcupreempt.h index 8a05c7e20bc4..0967f03b0705 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,25 @@ 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 | { |
118 | static DEFINE_RATELIMIT_STATE(rs, 10 * HZ, 1); | ||
119 | |||
88 | smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */ | 120 | smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */ |
89 | __get_cpu_var(dynticks_progress_counter)++; | 121 | __get_cpu_var(rcu_dyntick_sched).dynticks++; |
90 | WARN_ON(__get_cpu_var(dynticks_progress_counter) & 0x1); | 122 | WARN_ON_RATELIMIT(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1, &rs); |
91 | } | 123 | } |
92 | 124 | ||
93 | static inline void rcu_exit_nohz(void) | 125 | static inline void rcu_exit_nohz(void) |
94 | { | 126 | { |
95 | __get_cpu_var(dynticks_progress_counter)++; | 127 | static DEFINE_RATELIMIT_STATE(rs, 10 * HZ, 1); |
128 | |||
96 | smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ | 129 | smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ |
97 | WARN_ON(!(__get_cpu_var(dynticks_progress_counter) & 0x1)); | 130 | __get_cpu_var(rcu_dyntick_sched).dynticks++; |
131 | WARN_ON_RATELIMIT(!(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1), | ||
132 | &rs); | ||
98 | } | 133 | } |
99 | 134 | ||
100 | #else /* CONFIG_NO_HZ */ | 135 | #else /* CONFIG_NO_HZ */ |