diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2010-02-22 20:05:01 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-02-25 04:34:57 -0500 |
commit | 20133cfce7d0bbdcc0c398301030c091f5675c88 (patch) | |
tree | 337f242bfc89f5880cf86234fa6b574f52a2f0a5 /kernel/rcutree.h | |
parent | 1bd22e374b20c2f0ba1d2723c1f585acab2251c5 (diff) |
rcu: Stop overflowing signed integers
The C standard does not specify the result of an operation that
overflows a signed integer, so such operations need to be
avoided. This patch changes the type of several fields from
"long" to "unsigned long" and adjusts operations as needed.
ULONG_CMP_GE() and ULONG_CMP_LT() macros are introduced to do
the modular comparisons that are appropriate given that overflow
is an expected event.
Acked-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: laijs@cn.fujitsu.com
Cc: dipankar@in.ibm.com
Cc: mathieu.desnoyers@polymtl.ca
Cc: josh@joshtriplett.org
Cc: dvhltc@us.ibm.com
Cc: niv@us.ibm.com
Cc: peterz@infradead.org
Cc: rostedt@goodmis.org
Cc: Valdis.Kletnieks@vt.edu
Cc: dhowells@redhat.com
LKML-Reference: <1266887105-1528-17-git-send-email-paulmck@linux.vnet.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/rcutree.h')
-rw-r--r-- | kernel/rcutree.h | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index d9d032abd665..7495fed49c30 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
@@ -92,10 +92,10 @@ struct rcu_dynticks { | |||
92 | struct rcu_node { | 92 | struct rcu_node { |
93 | spinlock_t lock; /* Root rcu_node's lock protects some */ | 93 | spinlock_t lock; /* Root rcu_node's lock protects some */ |
94 | /* rcu_state fields as well as following. */ | 94 | /* rcu_state fields as well as following. */ |
95 | long gpnum; /* Current grace period for this node. */ | 95 | unsigned long gpnum; /* Current grace period for this node. */ |
96 | /* This will either be equal to or one */ | 96 | /* This will either be equal to or one */ |
97 | /* behind the root rcu_node's gpnum. */ | 97 | /* behind the root rcu_node's gpnum. */ |
98 | long completed; /* Last grace period completed for this node. */ | 98 | unsigned long completed; /* Last GP completed for this node. */ |
99 | /* This will either be equal to or one */ | 99 | /* This will either be equal to or one */ |
100 | /* behind the root rcu_node's gpnum. */ | 100 | /* behind the root rcu_node's gpnum. */ |
101 | unsigned long qsmask; /* CPUs or groups that need to switch in */ | 101 | unsigned long qsmask; /* CPUs or groups that need to switch in */ |
@@ -161,11 +161,11 @@ struct rcu_node { | |||
161 | /* Per-CPU data for read-copy update. */ | 161 | /* Per-CPU data for read-copy update. */ |
162 | struct rcu_data { | 162 | struct rcu_data { |
163 | /* 1) quiescent-state and grace-period handling : */ | 163 | /* 1) quiescent-state and grace-period handling : */ |
164 | long completed; /* Track rsp->completed gp number */ | 164 | unsigned long completed; /* Track rsp->completed gp number */ |
165 | /* in order to detect GP end. */ | 165 | /* in order to detect GP end. */ |
166 | long gpnum; /* Highest gp number that this CPU */ | 166 | unsigned long gpnum; /* Highest gp number that this CPU */ |
167 | /* is aware of having started. */ | 167 | /* is aware of having started. */ |
168 | long passed_quiesc_completed; | 168 | unsigned long passed_quiesc_completed; |
169 | /* Value of completed at time of qs. */ | 169 | /* Value of completed at time of qs. */ |
170 | bool passed_quiesc; /* User-mode/idle loop etc. */ | 170 | bool passed_quiesc; /* User-mode/idle loop etc. */ |
171 | bool qs_pending; /* Core waits for quiesc state. */ | 171 | bool qs_pending; /* Core waits for quiesc state. */ |
@@ -221,14 +221,14 @@ struct rcu_data { | |||
221 | unsigned long resched_ipi; /* Sent a resched IPI. */ | 221 | unsigned long resched_ipi; /* Sent a resched IPI. */ |
222 | 222 | ||
223 | /* 5) __rcu_pending() statistics. */ | 223 | /* 5) __rcu_pending() statistics. */ |
224 | long n_rcu_pending; /* rcu_pending() calls since boot. */ | 224 | unsigned long n_rcu_pending; /* rcu_pending() calls since boot. */ |
225 | long n_rp_qs_pending; | 225 | unsigned long n_rp_qs_pending; |
226 | long n_rp_cb_ready; | 226 | unsigned long n_rp_cb_ready; |
227 | long n_rp_cpu_needs_gp; | 227 | unsigned long n_rp_cpu_needs_gp; |
228 | long n_rp_gp_completed; | 228 | unsigned long n_rp_gp_completed; |
229 | long n_rp_gp_started; | 229 | unsigned long n_rp_gp_started; |
230 | long n_rp_need_fqs; | 230 | unsigned long n_rp_need_fqs; |
231 | long n_rp_need_nothing; | 231 | unsigned long n_rp_need_nothing; |
232 | 232 | ||
233 | int cpu; | 233 | int cpu; |
234 | }; | 234 | }; |
@@ -255,6 +255,9 @@ struct rcu_data { | |||
255 | 255 | ||
256 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ | 256 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ |
257 | 257 | ||
258 | #define ULONG_CMP_GE(a, b) (ULONG_MAX / 2 >= (a) - (b)) | ||
259 | #define ULONG_CMP_LT(a, b) (ULONG_MAX / 2 < (a) - (b)) | ||
260 | |||
258 | /* | 261 | /* |
259 | * RCU global state, including node hierarchy. This hierarchy is | 262 | * RCU global state, including node hierarchy. This hierarchy is |
260 | * represented in "heap" form in a dense array. The root (first level) | 263 | * represented in "heap" form in a dense array. The root (first level) |
@@ -283,8 +286,8 @@ struct rcu_state { | |||
283 | /* period because */ | 286 | /* period because */ |
284 | /* force_quiescent_state() */ | 287 | /* force_quiescent_state() */ |
285 | /* was running. */ | 288 | /* was running. */ |
286 | long gpnum; /* Current gp number. */ | 289 | unsigned long gpnum; /* Current gp number. */ |
287 | long completed; /* # of last completed gp. */ | 290 | unsigned long completed; /* # of last completed gp. */ |
288 | 291 | ||
289 | /* End of fields guarded by root rcu_node's lock. */ | 292 | /* End of fields guarded by root rcu_node's lock. */ |
290 | 293 | ||