diff options
author | Peter Zijlstra <peterz@infradead.org> | 2014-03-13 14:00:35 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-04-18 08:20:48 -0400 |
commit | 1b15611e1c30b37abe393d411c316cd659920bf5 (patch) | |
tree | 99992be63b630b8a64135f47e2f93f90db7cbab1 | |
parent | 09a01c0ccb1837abb28afcfdd668fa0dfabed928 (diff) |
arch,doc: Convert smp_mb__*()
Update the documentation to reflect the change of barrier primitives.
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Acked-by: David Howells <dhowells@redhat.com>
Link: http://lkml.kernel.org/n/tip-xslfehiga1twbk5uk94rij1e@git.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | Documentation/atomic_ops.txt | 31 | ||||
-rw-r--r-- | Documentation/memory-barriers.txt | 42 |
2 files changed, 23 insertions, 50 deletions
diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt index d9ca5be9b471..68542fe13b85 100644 --- a/Documentation/atomic_ops.txt +++ b/Documentation/atomic_ops.txt | |||
@@ -285,15 +285,13 @@ If a caller requires memory barrier semantics around an atomic_t | |||
285 | operation which does not return a value, a set of interfaces are | 285 | operation which does not return a value, a set of interfaces are |
286 | defined which accomplish this: | 286 | defined which accomplish this: |
287 | 287 | ||
288 | void smp_mb__before_atomic_dec(void); | 288 | void smp_mb__before_atomic(void); |
289 | void smp_mb__after_atomic_dec(void); | 289 | void smp_mb__after_atomic(void); |
290 | void smp_mb__before_atomic_inc(void); | ||
291 | void smp_mb__after_atomic_inc(void); | ||
292 | 290 | ||
293 | For example, smp_mb__before_atomic_dec() can be used like so: | 291 | For example, smp_mb__before_atomic() can be used like so: |
294 | 292 | ||
295 | obj->dead = 1; | 293 | obj->dead = 1; |
296 | smp_mb__before_atomic_dec(); | 294 | smp_mb__before_atomic(); |
297 | atomic_dec(&obj->ref_count); | 295 | atomic_dec(&obj->ref_count); |
298 | 296 | ||
299 | It makes sure that all memory operations preceding the atomic_dec() | 297 | It makes sure that all memory operations preceding the atomic_dec() |
@@ -302,15 +300,10 @@ operation. In the above example, it guarantees that the assignment of | |||
302 | "1" to obj->dead will be globally visible to other cpus before the | 300 | "1" to obj->dead will be globally visible to other cpus before the |
303 | atomic counter decrement. | 301 | atomic counter decrement. |
304 | 302 | ||
305 | Without the explicit smp_mb__before_atomic_dec() call, the | 303 | Without the explicit smp_mb__before_atomic() call, the |
306 | implementation could legally allow the atomic counter update visible | 304 | implementation could legally allow the atomic counter update visible |
307 | to other cpus before the "obj->dead = 1;" assignment. | 305 | to other cpus before the "obj->dead = 1;" assignment. |
308 | 306 | ||
309 | The other three interfaces listed are used to provide explicit | ||
310 | ordering with respect to memory operations after an atomic_dec() call | ||
311 | (smp_mb__after_atomic_dec()) and around atomic_inc() calls | ||
312 | (smp_mb__{before,after}_atomic_inc()). | ||
313 | |||
314 | A missing memory barrier in the cases where they are required by the | 307 | A missing memory barrier in the cases where they are required by the |
315 | atomic_t implementation above can have disastrous results. Here is | 308 | atomic_t implementation above can have disastrous results. Here is |
316 | an example, which follows a pattern occurring frequently in the Linux | 309 | an example, which follows a pattern occurring frequently in the Linux |
@@ -487,12 +480,12 @@ Finally there is the basic operation: | |||
487 | Which returns a boolean indicating if bit "nr" is set in the bitmask | 480 | Which returns a boolean indicating if bit "nr" is set in the bitmask |
488 | pointed to by "addr". | 481 | pointed to by "addr". |
489 | 482 | ||
490 | If explicit memory barriers are required around clear_bit() (which | 483 | If explicit memory barriers are required around {set,clear}_bit() (which do |
491 | does not return a value, and thus does not need to provide memory | 484 | not return a value, and thus does not need to provide memory barrier |
492 | barrier semantics), two interfaces are provided: | 485 | semantics), two interfaces are provided: |
493 | 486 | ||
494 | void smp_mb__before_clear_bit(void); | 487 | void smp_mb__before_atomic(void); |
495 | void smp_mb__after_clear_bit(void); | 488 | void smp_mb__after_atomic(void); |
496 | 489 | ||
497 | They are used as follows, and are akin to their atomic_t operation | 490 | They are used as follows, and are akin to their atomic_t operation |
498 | brothers: | 491 | brothers: |
@@ -500,13 +493,13 @@ brothers: | |||
500 | /* All memory operations before this call will | 493 | /* All memory operations before this call will |
501 | * be globally visible before the clear_bit(). | 494 | * be globally visible before the clear_bit(). |
502 | */ | 495 | */ |
503 | smp_mb__before_clear_bit(); | 496 | smp_mb__before_atomic(); |
504 | clear_bit( ... ); | 497 | clear_bit( ... ); |
505 | 498 | ||
506 | /* The clear_bit() will be visible before all | 499 | /* The clear_bit() will be visible before all |
507 | * subsequent memory operations. | 500 | * subsequent memory operations. |
508 | */ | 501 | */ |
509 | smp_mb__after_clear_bit(); | 502 | smp_mb__after_atomic(); |
510 | 503 | ||
511 | There are two special bitops with lock barrier semantics (acquire/release, | 504 | There are two special bitops with lock barrier semantics (acquire/release, |
512 | same as spinlocks). These operate in the same way as their non-_lock/unlock | 505 | same as spinlocks). These operate in the same way as their non-_lock/unlock |
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index 556f951f8626..46412bded104 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt | |||
@@ -1583,20 +1583,21 @@ There are some more advanced barrier functions: | |||
1583 | insert anything more than a compiler barrier in a UP compilation. | 1583 | insert anything more than a compiler barrier in a UP compilation. |
1584 | 1584 | ||
1585 | 1585 | ||
1586 | (*) smp_mb__before_atomic_dec(); | 1586 | (*) smp_mb__before_atomic(); |
1587 | (*) smp_mb__after_atomic_dec(); | 1587 | (*) smp_mb__after_atomic(); |
1588 | (*) smp_mb__before_atomic_inc(); | ||
1589 | (*) smp_mb__after_atomic_inc(); | ||
1590 | 1588 | ||
1591 | These are for use with atomic add, subtract, increment and decrement | 1589 | These are for use with atomic (such as add, subtract, increment and |
1592 | functions that don't return a value, especially when used for reference | 1590 | decrement) functions that don't return a value, especially when used for |
1593 | counting. These functions do not imply memory barriers. | 1591 | reference counting. These functions do not imply memory barriers. |
1592 | |||
1593 | These are also used for atomic bitop functions that do not return a | ||
1594 | value (such as set_bit and clear_bit). | ||
1594 | 1595 | ||
1595 | As an example, consider a piece of code that marks an object as being dead | 1596 | As an example, consider a piece of code that marks an object as being dead |
1596 | and then decrements the object's reference count: | 1597 | and then decrements the object's reference count: |
1597 | 1598 | ||
1598 | obj->dead = 1; | 1599 | obj->dead = 1; |
1599 | smp_mb__before_atomic_dec(); | 1600 | smp_mb__before_atomic(); |
1600 | atomic_dec(&obj->ref_count); | 1601 | atomic_dec(&obj->ref_count); |
1601 | 1602 | ||
1602 | This makes sure that the death mark on the object is perceived to be set | 1603 | This makes sure that the death mark on the object is perceived to be set |
@@ -1606,27 +1607,6 @@ There are some more advanced barrier functions: | |||
1606 | operations" subsection for information on where to use these. | 1607 | operations" subsection for information on where to use these. |
1607 | 1608 | ||
1608 | 1609 | ||
1609 | (*) smp_mb__before_clear_bit(void); | ||
1610 | (*) smp_mb__after_clear_bit(void); | ||
1611 | |||
1612 | These are for use similar to the atomic inc/dec barriers. These are | ||
1613 | typically used for bitwise unlocking operations, so care must be taken as | ||
1614 | there are no implicit memory barriers here either. | ||
1615 | |||
1616 | Consider implementing an unlock operation of some nature by clearing a | ||
1617 | locking bit. The clear_bit() would then need to be barriered like this: | ||
1618 | |||
1619 | smp_mb__before_clear_bit(); | ||
1620 | clear_bit( ... ); | ||
1621 | |||
1622 | This prevents memory operations before the clear leaking to after it. See | ||
1623 | the subsection on "Locking Functions" with reference to RELEASE operation | ||
1624 | implications. | ||
1625 | |||
1626 | See Documentation/atomic_ops.txt for more information. See the "Atomic | ||
1627 | operations" subsection for information on where to use these. | ||
1628 | |||
1629 | |||
1630 | MMIO WRITE BARRIER | 1610 | MMIO WRITE BARRIER |
1631 | ------------------ | 1611 | ------------------ |
1632 | 1612 | ||
@@ -2283,11 +2263,11 @@ operations: | |||
2283 | change_bit(); | 2263 | change_bit(); |
2284 | 2264 | ||
2285 | With these the appropriate explicit memory barrier should be used if necessary | 2265 | With these the appropriate explicit memory barrier should be used if necessary |
2286 | (smp_mb__before_clear_bit() for instance). | 2266 | (smp_mb__before_atomic() for instance). |
2287 | 2267 | ||
2288 | 2268 | ||
2289 | The following also do _not_ imply memory barriers, and so may require explicit | 2269 | The following also do _not_ imply memory barriers, and so may require explicit |
2290 | memory barriers under some circumstances (smp_mb__before_atomic_dec() for | 2270 | memory barriers under some circumstances (smp_mb__before_atomic() for |
2291 | instance): | 2271 | instance): |
2292 | 2272 | ||
2293 | atomic_add(); | 2273 | atomic_add(); |