diff options
| author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2011-04-01 10:15:14 -0400 |
|---|---|---|
| committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2011-04-01 10:27:31 -0400 |
| commit | a4dd99250dc49031e6a92a895dbcc230a4832083 (patch) | |
| tree | 3d0b6f45620f66044400ea14a6af019bf0af67e7 | |
| parent | 0ce790e7d736cedc563e1fb4e998babf5a4dbc3d (diff) | |
rcu: create new rcu_access_index() and use in mce
The MCE subsystem needs to sample an RCU-protected index outside of
any protection for that index. If this was a pointer, we would use
rcu_access_pointer(), but there is no corresponding rcu_access_index().
This commit therefore creates an rcu_access_index() and applies it
to MCE.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Tested-by: Zdenek Kabelac <zkabelac@redhat.com>
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 2 | ||||
| -rw-r--r-- | include/linux/rcupdate.h | 20 |
2 files changed, 21 insertions, 1 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 5a05ef63eb4a..3385ea26f684 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -1626,7 +1626,7 @@ out: | |||
| 1626 | static unsigned int mce_poll(struct file *file, poll_table *wait) | 1626 | static unsigned int mce_poll(struct file *file, poll_table *wait) |
| 1627 | { | 1627 | { |
| 1628 | poll_wait(file, &mce_wait, wait); | 1628 | poll_wait(file, &mce_wait, wait); |
| 1629 | if (rcu_dereference_check_mce(mcelog.next)) | 1629 | if (rcu_access_index(mcelog.next)) |
| 1630 | return POLLIN | POLLRDNORM; | 1630 | return POLLIN | POLLRDNORM; |
| 1631 | if (!mce_apei_read_done && apei_check_mce()) | 1631 | if (!mce_apei_read_done && apei_check_mce()) |
| 1632 | return POLLIN | POLLRDNORM; | 1632 | return POLLIN | POLLRDNORM; |
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index af5614856285..ff422d2b7f90 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
| @@ -339,6 +339,12 @@ extern int rcu_my_thread_group_empty(void); | |||
| 339 | ((typeof(*p) __force __kernel *)(p)); \ | 339 | ((typeof(*p) __force __kernel *)(p)); \ |
| 340 | }) | 340 | }) |
| 341 | 341 | ||
| 342 | #define __rcu_access_index(p, space) \ | ||
| 343 | ({ \ | ||
| 344 | typeof(p) _________p1 = ACCESS_ONCE(p); \ | ||
| 345 | rcu_dereference_sparse(p, space); \ | ||
| 346 | (_________p1); \ | ||
| 347 | }) | ||
| 342 | #define __rcu_dereference_index_check(p, c) \ | 348 | #define __rcu_dereference_index_check(p, c) \ |
| 343 | ({ \ | 349 | ({ \ |
| 344 | typeof(p) _________p1 = ACCESS_ONCE(p); \ | 350 | typeof(p) _________p1 = ACCESS_ONCE(p); \ |
| @@ -429,6 +435,20 @@ extern int rcu_my_thread_group_empty(void); | |||
| 429 | #define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/ | 435 | #define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/ |
| 430 | 436 | ||
| 431 | /** | 437 | /** |
| 438 | * rcu_access_index() - fetch RCU index with no dereferencing | ||
| 439 | * @p: The index to read | ||
| 440 | * | ||
| 441 | * Return the value of the specified RCU-protected index, but omit the | ||
| 442 | * smp_read_barrier_depends() and keep the ACCESS_ONCE(). This is useful | ||
| 443 | * when the value of this index is accessed, but the index is not | ||
| 444 | * dereferenced, for example, when testing an RCU-protected index against | ||
| 445 | * -1. Although rcu_access_index() may also be used in cases where | ||
| 446 | * update-side locks prevent the value of the index from changing, you | ||
| 447 | * should instead use rcu_dereference_index_protected() for this use case. | ||
| 448 | */ | ||
| 449 | #define rcu_access_index(p) __rcu_access_index((p), __rcu) | ||
| 450 | |||
| 451 | /** | ||
| 432 | * rcu_dereference_index_check() - rcu_dereference for indices with debug checking | 452 | * rcu_dereference_index_check() - rcu_dereference for indices with debug checking |
| 433 | * @p: The pointer to read, prior to dereferencing | 453 | * @p: The pointer to read, prior to dereferencing |
| 434 | * @c: The conditions under which the dereference will take place | 454 | * @c: The conditions under which the dereference will take place |
