diff options
Diffstat (limited to 'kernel/rcu/tree.c')
| -rw-r--r-- | kernel/rcu/tree.c | 42 |
1 files changed, 10 insertions, 32 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index a54587dc13f0..fd2f582a6db0 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
| @@ -3183,16 +3183,10 @@ unsigned long get_state_synchronize_rcu(void) | |||
| 3183 | { | 3183 | { |
| 3184 | /* | 3184 | /* |
| 3185 | * Any prior manipulation of RCU-protected data must happen | 3185 | * Any prior manipulation of RCU-protected data must happen |
| 3186 | * before the load from ->gpnum. | 3186 | * before the load from ->gp_seq. |
| 3187 | */ | 3187 | */ |
| 3188 | smp_mb(); /* ^^^ */ | 3188 | smp_mb(); /* ^^^ */ |
| 3189 | 3189 | return rcu_seq_snap(&rcu_state_p->gp_seq); | |
| 3190 | /* | ||
| 3191 | * Make sure this load happens before the purportedly | ||
| 3192 | * time-consuming work between get_state_synchronize_rcu() | ||
| 3193 | * and cond_synchronize_rcu(). | ||
| 3194 | */ | ||
| 3195 | return smp_load_acquire(&rcu_state_p->gpnum); | ||
| 3196 | } | 3190 | } |
| 3197 | EXPORT_SYMBOL_GPL(get_state_synchronize_rcu); | 3191 | EXPORT_SYMBOL_GPL(get_state_synchronize_rcu); |
| 3198 | 3192 | ||
| @@ -3212,15 +3206,10 @@ EXPORT_SYMBOL_GPL(get_state_synchronize_rcu); | |||
| 3212 | */ | 3206 | */ |
| 3213 | void cond_synchronize_rcu(unsigned long oldstate) | 3207 | void cond_synchronize_rcu(unsigned long oldstate) |
| 3214 | { | 3208 | { |
| 3215 | unsigned long newstate; | 3209 | if (!rcu_seq_done(&rcu_state_p->gp_seq, oldstate)) |
| 3216 | |||
| 3217 | /* | ||
| 3218 | * Ensure that this load happens before any RCU-destructive | ||
| 3219 | * actions the caller might carry out after we return. | ||
| 3220 | */ | ||
| 3221 | newstate = smp_load_acquire(&rcu_state_p->completed); | ||
| 3222 | if (ULONG_CMP_GE(oldstate, newstate)) | ||
| 3223 | synchronize_rcu(); | 3210 | synchronize_rcu(); |
| 3211 | else | ||
| 3212 | smp_mb(); /* Ensure GP ends before subsequent accesses. */ | ||
| 3224 | } | 3213 | } |
| 3225 | EXPORT_SYMBOL_GPL(cond_synchronize_rcu); | 3214 | EXPORT_SYMBOL_GPL(cond_synchronize_rcu); |
| 3226 | 3215 | ||
| @@ -3235,16 +3224,10 @@ unsigned long get_state_synchronize_sched(void) | |||
| 3235 | { | 3224 | { |
| 3236 | /* | 3225 | /* |
| 3237 | * Any prior manipulation of RCU-protected data must happen | 3226 | * Any prior manipulation of RCU-protected data must happen |
| 3238 | * before the load from ->gpnum. | 3227 | * before the load from ->gp_seq. |
| 3239 | */ | 3228 | */ |
| 3240 | smp_mb(); /* ^^^ */ | 3229 | smp_mb(); /* ^^^ */ |
| 3241 | 3230 | return rcu_seq_snap(&rcu_sched_state.gp_seq); | |
| 3242 | /* | ||
| 3243 | * Make sure this load happens before the purportedly | ||
| 3244 | * time-consuming work between get_state_synchronize_sched() | ||
| 3245 | * and cond_synchronize_sched(). | ||
| 3246 | */ | ||
| 3247 | return smp_load_acquire(&rcu_sched_state.gpnum); | ||
| 3248 | } | 3231 | } |
| 3249 | EXPORT_SYMBOL_GPL(get_state_synchronize_sched); | 3232 | EXPORT_SYMBOL_GPL(get_state_synchronize_sched); |
| 3250 | 3233 | ||
| @@ -3264,15 +3247,10 @@ EXPORT_SYMBOL_GPL(get_state_synchronize_sched); | |||
| 3264 | */ | 3247 | */ |
| 3265 | void cond_synchronize_sched(unsigned long oldstate) | 3248 | void cond_synchronize_sched(unsigned long oldstate) |
| 3266 | { | 3249 | { |
| 3267 | unsigned long newstate; | 3250 | if (!rcu_seq_done(&rcu_sched_state.gp_seq, oldstate)) |
| 3268 | |||
| 3269 | /* | ||
| 3270 | * Ensure that this load happens before any RCU-destructive | ||
| 3271 | * actions the caller might carry out after we return. | ||
| 3272 | */ | ||
| 3273 | newstate = smp_load_acquire(&rcu_sched_state.completed); | ||
| 3274 | if (ULONG_CMP_GE(oldstate, newstate)) | ||
| 3275 | synchronize_sched(); | 3251 | synchronize_sched(); |
| 3252 | else | ||
| 3253 | smp_mb(); /* Ensure GP ends before subsequent accesses. */ | ||
| 3276 | } | 3254 | } |
| 3277 | EXPORT_SYMBOL_GPL(cond_synchronize_sched); | 3255 | EXPORT_SYMBOL_GPL(cond_synchronize_sched); |
| 3278 | 3256 | ||
