=======================================================
Semantics and Behavior of Atomic and Bitmask Operations
=======================================================

:Author: David S. Miller

This document is intended to serve as a guide to Linux port
maintainers on how to implement atomic counter, bitops, and spinlock
interfaces properly.

Atomic Type And Operations
==========================

The atomic_t type should be defined as a signed integer and
the atomic_long_t type as a signed long integer.  Also, they should
be made opaque such that any kind of cast to a normal C integer type
will fail.  Something like the following should suffice::

	typedef struct { int counter; } atomic_t;
	typedef struct { long counter; } atomic_long_t;

Historically, counter has been declared volatile.  This is now discouraged.
See :ref:`Documentation/process/volatile-considered-harmful.rst
<volatile_considered_harmful>` for the complete rationale.

local_t is very similar to atomic_t. If the counter is per CPU and only
updated by one CPU, local_t is probably more appropriate. Please see
:ref:`Documentation/core-api/local_ops.rst <local_ops>` for the semantics of
local_t.

The first operations to implement for atomic_t's are the initializers and
plain reads. ::

	#define ATOMIC_INIT(i)		{ (i) }
	#define atomic_set(v, i)	((v)->counter = (i))

The first macro is used in definitions, such as::

	static atomic_t my_counter = ATOMIC_INIT(1);

The initializer is atomic in that the return values of the atomic operations
are guaranteed to be correct reflecting the initialized value if the
initializer is used before runtime.  If the initializer is used at runtime, a
proper implicit or explicit read memory barrier is needed before reading the
value with atomic_read from another thread.

As with all of the ``atomic_`` interfaces, replace the leading ``atomic_``
with ``atomic_long_`` to operate on atomic_long_t.

The second interface can be used at runtime, as in::

	struct foo { atomic_t counter; };
	...

	struct foo *k;

	k = kmalloc(sizeof(*k), GFP_KERNEL);
	if (!k)
		return -ENOMEM;
	atomic_set(&k->counter, 0);

The setting is atomic in that the return values of the atomic operations by
all threads are guaranteed to be correct reflecting either the value that has
been set with this operation or set with another operation.  A proper implicit
or explicit memory barrier is needed before the value set with the operation
is guaranteed to be readable with atomic_read from another thread.

Next, we have::

	#define atomic_read(v)	((v)->counter)

which simply reads the counter value currently visible to the calling thread.
The read is atomic in that the return value is guaranteed to be one of the
values initialized or modified with the interface operations if a proper
implicit or explicit memory barrier is used after possible runtime
initialization by any other thread and the value is modified only with the
interface operations.  atomic_read does not guarantee that the runtime
initialization by any other thread is visible yet, so the user of the
interface must take care of that with a proper implicit or explicit memory
barrier.

.. warning::

	``atomic_read()`` and ``atomic_set()`` DO NOT IMPLY BARRIERS!

	Some architectures may choose to use the volatile keyword, barriers, or
	inline assembly to guarantee some degree of immediacy for atomic_read()
	and atomic_set().  This is not uniformly guaranteed, and may change in
	the future, so all users of atomic_t should treat atomic_read() and
	atomic_set() as simple C statements that may be reordered or optimized
	away entirely by the compiler or processor, and explicitly invoke the
	appropriate compiler and/or memory barrier for each use case.  Failure
	to do so will result in code that may suddenly break when used with
	different architectures or compiler optimizations, or even changes in
	unrelated code which changes how the compiler optimizes the section
	accessing atomic_t variables.

Properly aligned pointers, longs, ints, and chars (and unsigned
equivalents) may be atomically loaded from and stored to in the same
sense as described for atomic_read() and atomic_set().  The READ_ONCE()
and WRITE_ONCE() macros should be used to prevent the compiler from using
optimizations that might otherwise optimize accesses out of existence on
the one hand, or that might create unsolicited accesses on the other.

For example consider the following code::

	while (a > 0)
		do_something();

If the compiler can prove that do_something() does not store to the
variable a, then the compiler is within its rights transforming this to
the following::

	if (a > 0)
		for (;;)
			do_something();

If you don't want the compiler to do this (and you probably don't), then
you should use something like the following::

	while (READ_ONCE(a) > 0)
		do_something();

Alternatively, you could place a barrier() call in the loop.

For another example, consider the following code::

	tmp_a = a;
	do_something_with(tmp_a);
	do_something_else_with(tmp_a);

If the compiler can prove that do_something_with() does not store to the
variable a, then the compiler is within its rights to manufacture an
additional load as follows::

	tmp_a = a;
	do_something_with(tmp_a);
	tmp_a = a;
	do_something_else_with(tmp_a);

This could fatally confuse your code if it expected the same value
to be passed to do_something_with() and do_something_else_with().

The compiler would be likely to manufacture this additional load if
do_something_with() was an inline function that made very heavy use
of registers: reloading from variable a could save a flush to the
stack and later reload.  To prevent the compiler from attacking your
code in this manner, write the following::

	tmp_a = READ_ONCE(a);
	do_something_with(tmp_a);
	do_something_else_with(tmp_a);

For a final example, consider the following code, assuming that the
variable a is set at boot time before the second CPU is brought online
and never changed later, so that memory barriers are not needed::

	if (a)
		b = 9;
	else
		b = 42;

The compiler is within its rights to manufacture an additional store
by transforming the above code into the following::

	b = 42;
	if (a)
		b = 9;

This could come as a fatal surprise to other code running concurrently
that expected b to never have the value 42 if a was zero.  To prevent
the compiler from doing this, write something like::

	if (a)
		WRITE_ONCE(b, 9);
	else
		WRITE_ONCE(b, 42);

Don't even -think- about doing this without proper use of memory barriers,
locks, or atomic operations if variable a can change at runtime!

.. warning::

	``READ_ONCE()`` OR ``WRITE_ONCE()`` DO NOT IMPLY A BARRIER!

Now, we move onto the atomic operation interfaces typically implemented with
the help of assembly code. ::

	void atomic_add(int i, atomic_t *v);
	void atomic_sub(int i, atomic_t *v);
	void atomic_inc(atomic_t *v);
	void atomic_dec(atomic_t *v);

These four routines add and subtract integral values to/from the given
atomic_t value.  The first two routines pass explicit integers by
which to make the adjustment, whereas the latter two use an implicit
adjustment value of "1".

One very important aspect of these two routines is that they DO NOT
require any explicit memory barriers.  They need only perform the
atomic_t counter update in an SMP safe manner.

Next, we have::

	int atomic_inc_return(atomic_t *v);
	int atomic_dec_return(atomic_t *v);

These routines add 1 and subtract 1, respectively, from the given
atomic_t and return the new counter value after the operation is
performed.

Unlike the above routines, it is required that these primitives
include explicit memory barriers that are performed before and after
the operation.  It must be done such that all memory operations before
and after the atomic operation calls are strongly ordered with respect
to the atomic operation itself.

For example, it should behave as if a smp_mb() call existed both
before and after the atomic operation.

If the atomic instructions used in an implementation provide explicit
memory barrier semantics which satisfy the above requirements, that is
fine as well.

Let's move on::

	int atomic_add_return(int i, atomic_t *v);
	int atomic_sub_return(int i, atomic_t *v);

These behave just like atomic_{inc,dec}_return() except that an
explicit counter adjustment is given instead of the implicit "1".
This means that like atomic_{inc,dec}_return(), the memory barrier
semantics are required.

Next::

	int atomic_inc_and_test(atomic_t *v);
	int atomic_dec_and_test(atomic_t *v);

These two routines increment and decrement by 1, respectively, the
given atomic counter.  They return a boolean indicating whether the
resulting counter value was zero or not.

Again, these primitives provide explicit memory barrier semantics around
the atomic operation::

	int atomic_sub_and_test(int i, atomic_t *v);

This is identical to atomic_dec_and_test() except that an explicit
decrement is given instead of the implicit "1".  This primitive must
provide explicit memory barrier semantics around the operation::

	int atomic_add_negative(int i, atomic_t *v);

The given increment is added to the given atomic counter value.  A boolean
is return which indicates whether the resulting counter value is negative.
This primitive must provide explicit memory barrier semantics around
the operation.

Then::

	int atomic_xchg(atomic_t *v, int new);

This performs an atomic exchange operation on the atomic variable v, setting
the given new value.  It returns the old value that the atomic variable v had
just before the operation.

atomic_xchg must provide explicit memory barriers around the operation. ::

	int atomic_cmpxchg(atomic_t *v, int old, int new);

This performs an atomic compare exchange operation on the atomic value v,
with the given old and new values. Like all atomic_xxx operations,
atomic_cmpxchg will only satisfy its atomicity semantics as long as all
other accesses of \*v are performed through atomic_xxx operations.

atomic_cmpxchg must provide explicit memory barriers around the operation,
although if the comparison fails then no memory ordering guarantees are
required.

The semantics for atomic_cmpxchg are the same as those defined for 'cas'
below.

Finally::

	int atomic_add_unless(atomic_t *v, int a, int u);

If the atomic value v is not equal to u, this function adds a to v, and
returns non zero. If v is equal to u then it returns zero. This is done as
an atomic operation.

atomic_add_unless must provide explicit memory barriers around the
operation unless it fails (returns 0).

atomic_inc_not_zero, equivalent to atomic_add_unless(v, 1, 0)


If a caller requires memory barrier semantics around an atomic_t
operation which does not return a value, a set of interfaces are
defined which accomplish this::

	void smp_mb__before_atomic(void);
	void smp_mb__after_atomic(void);

Preceding a non-value-returning read-modify-write atomic operation with
smp_mb__before_atomic() and following it with smp_mb__after_atomic()
provides the same full ordering that is provided by value-returning
read-modify-write atomic operations.

For example, smp_mb__before_atomic() can be used like so::

	obj->dead = 1;
	smp_mb__before_atomic();
	atomic_dec(&obj->ref_count);

It makes sure that all memory operations preceding the atomic_dec()
call are strongly ordered with respect to the atomic counter
operation.  In the above example, it guarantees that the assignment of
"1" to obj->dead will be globally visible to other cpus before the
atomic counter decrement.

Without the explicit smp_mb__before_atomic() call, the
implementation could legally allow the atomic counter update visible
to other cpus before the "obj->dead = 1;" assignment.

A missing memory barrier in the cases where they are required by the
atomic_t implementation above can have disastrous results.  Here is
an example, which follows a pattern occurring frequently in the Linux
kernel.  It is the use of atomic counters to implement reference
counting, and it works such that once the counter falls to zero it can
be guaranteed that no other entity can be accessing the object::

	static void obj_list_add(struct obj *obj, struct list_head *head)
	{
		obj->active = 1;
		list_add(&obj->list, head);
	}

	static void obj_list_del(struct obj *obj)
	{
		list_del(&obj->list);
		obj->active = 0;
	}

	static void obj_destroy(struct obj *obj)
	{
		BUG_ON(obj->active);
		kfree(obj);
	}

	struct obj *obj_list_peek(struct list_head *head)
	{
		if (!list_empty(head)) {
			struct obj *obj;

			obj = list_entry(head->next, struct obj, list);
			atomic_inc(&obj->refcnt);
			return obj;
		}
		return NULL;
	}

	void obj_poke(void)
	{
		struct obj *obj;

		spin_lock(&global_list_lock);
		obj = obj_list_peek(&global_list);
		spin_unlock(&global_list_lock);

		if (obj) {
			obj->ops->poke(obj);
			if (atomic_dec_and_test(&obj->refcnt))
				obj_destroy(obj);
		}
	}

	void obj_timeout(struct obj *obj)
	{
		spin_lock(&global_list_lock);
		obj_list_del(obj);
		spin_unlock(&global_list_lock);

		if (atomic_dec_and_test(&obj->refcnt))
			obj_destroy(obj);
	}

.. note::

	This is a simplification of the ARP queue management in the generic
	neighbour discover code of the networking.  Olaf Kirch found a bug wrt.
	memory barriers in kfree_skb() that exposed the atomic_t memory barrier
	requirements quite clearly.

Given the above scheme, it must be the case that the obj->active
update done by the obj list deletion be visible to other processors
before the atomic counter decrement is performed.

Otherwise, the counter could fall to zero, yet obj->active would still
be set, thus triggering the assertion in obj_destroy().  The error
sequence looks like this::

	cpu 0				cpu 1
	obj_poke()			obj_timeout()
	obj = obj_list_peek();
	... gains ref to obj, refcnt=2
					obj_list_del(obj);
					obj->active = 0 ...
					... visibility delayed ...
					atomic_dec_and_test()
					... refcnt drops to 1 ...
	atomic_dec_and_test()
	... refcount drops to 0 ...
	obj_destroy()
	BUG() triggers since obj->active
	still seen as one
					obj->active update visibility occurs

With the memory barrier semantics required of the atomic_t operations
which return values, the above sequence of memory visibility can never
happen.  Specifically, in the above case the atomic_dec_and_test()
counter decrement would not become globally visible until the
obj->active update does.

As a historical note, 32-bit Sparc used to only allow usage of
24-bits of its atomic_t type.  This was because it used 8 bits
as a spinlock for SMP safety.  Sparc32 lacked a "compare and swap"
type instruction.  However, 32-bit Sparc has since been moved over
to a "hash table of spinlocks" scheme, that allows the full 32-bit
counter to be realized.  Essentially, an array of spinlocks are
indexed into based upon the address of the atomic_t being operated
on, and that lock protects the atomic operation.  Parisc uses the
same scheme.

Another note is that the atomic_t operations returning values are
extremely slow on an old 386.


Atomic Bitmask
==============

We will now cover the atomic bitmask operations.  You will find that
their SMP and memory barrier semantics are similar in shape and scope
to the atomic_t ops above.

Native atomic bit operations are defined to operate on objects aligned
to the size of an "unsigned long" C data type, and are least of that
size.  The endianness of the bits within each "unsigned long" are the
native endianness of the cpu. ::

	void set_bit(unsigned long nr, volatile unsigned long *addr);
	void clear_bit(unsigned long nr, volatile unsigned long *addr);
	void change_bit(unsigned long nr, volatile unsigned long *addr);

These routines set, clear, and change, respectively, the bit number
indicated by "nr" on the bit mask pointed to by "ADDR".

They must execute atomically, yet there are no implicit memory barrier
semantics required of these interfaces. ::

	int test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
	int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
	int test_and_change_bit(unsigned long nr, volatile unsigned long *addr);

Like the above, except that these routines return a boolean which
indicates whether the changed bit was set _BEFORE_ the atomic bit
operation.


.. warning::
        It is incredibly important that the value be a boolean, ie. "0" or "1".
        Do not try to be fancy and save a few instructions by declaring the
        above to return "long" and just returning something like "old_val &
        mask" because that will not work.

For one thing, this return value gets truncated to int in many code
paths using these interfaces, so on 64-bit if the bit is set in the
upper 32-bits then testers will never see that.

One great example of where this problem crops up are the thread_info
flag operations.  Routines such as test_and_set_ti_thread_flag() chop
the return value into an int.  There are other places where things
like this occur as well.

These routines, like the atomic_t counter operations returning values,
must provide explicit memory barrier semantics around their execution.
All memory operations before the atomic bit operation call must be
made visible globally before the atomic bit operation is made visible.
Likewise, the atomic bit operation must be visible globally before any
subsequent memory operation is made visible.  For example::

	obj->dead = 1;
	if (test_and_set_bit(0, &obj->flags))
		/* ... */;
	obj->killed = 1;

The implementation of test_and_set_bit() must guarantee that
"obj->dead = 1;" is visible to cpus before the atomic memory operation
done by test_and_set_bit() becomes visible.  Likewise, the atomic
memory operation done by test_and_set_bit() must become visible before
"obj->killed = 1;" is visible.

Finally there is the basic operation::

	int test_bit(unsigned long nr, __const__ volatile unsigned long *addr);

Which returns a boolean indicating if bit "nr" is set in the bitmask
pointed to by "addr".

If explicit memory barriers are required around {set,clear}_bit() (which do
not return a value, and thus does not need to provide memory barrier
semantics), two interfaces are provided::

	void smp_mb__before_atomic(void);
	void smp_mb__after_atomic(void);

They are used as follows, and are akin to their atomic_t operation
brothers::

	/* All memory operations before this call will
	 * be globally visible before the clear_bit().
	 */
	smp_mb__before_atomic();
	clear_bit( ... );

	/* The clear_bit() will be visible before all
	 * subsequent memory operations.
	 */
	 smp_mb__after_atomic();

There are two special bitops with lock barrier semantics (acquire/release,
same as spinlocks). These operate in the same way as their non-_lock/unlock
postfixed variants, except that they are to provide acquire/release semantics,
respectively. This means they can be used for bit_spin_trylock and
bit_spin_unlock type operations without specifying any more barriers. ::

	int test_and_set_bit_lock(unsigned long nr, unsigned long *addr);
	void clear_bit_unlock(unsigned long nr, unsigned long *addr);
	void __clear_bit_unlock(unsigned long nr, unsigned long *addr);

The __clear_bit_unlock version is non-atomic, however it still implements
unlock barrier semantics. This can be useful if the lock itself is protecting
the other bits in the word.

Finally, there are non-atomic versions of the bitmask operations
provided.  They are used in contexts where some other higher-level SMP
locking scheme is being used to protect the bitmask, and thus less
expensive non-atomic operations may be used in the implementation.
They have names similar to the above bitmask operation interfaces,
except that two underscores are prefixed to the interface name. ::

	void __set_bit(unsigned long nr, volatile unsigned long *addr);
	void __clear_bit(unsigned long nr, volatile unsigned long *addr);
	void __change_bit(unsigned long nr, volatile unsigned long *addr);
	int __test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
	int __test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
	int __test_and_change_bit(unsigned long nr, volatile unsigned long *addr);

These non-atomic variants also do not require any special memory
barrier semantics.

The routines xchg() and cmpxchg() must provide the same exact
memory-barrier semantics as the atomic and bit operations returning
values.

.. note::

	If someone wants to use xchg(), cmpxchg() and their variants,
	linux/atomic.h should be included rather than asm/cmpxchg.h, unless the
	code is in arch/* and can take care of itself.

Spinlocks and rwlocks have memory barrier expectations as well.
The rule to follow is simple:

1) When acquiring a lock, the implementation must make it globally
   visible before any subsequent memory operation.

2) When releasing a lock, the implementation must make it such that
   all previous memory operations are globally visible before the
   lock release.

Which finally brings us to _atomic_dec_and_lock().  There is an
architecture-neutral version implemented in lib/dec_and_lock.c,
but most platforms will wish to optimize this in assembler. ::

	int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);

Atomically decrement the given counter, and if will drop to zero
atomically acquire the given spinlock and perform the decrement
of the counter to zero.  If it does not drop to zero, do nothing
with the spinlock.

It is actually pretty simple to get the memory barrier correct.
Simply satisfy the spinlock grab requirements, which is make
sure the spinlock operation is globally visible before any
subsequent memory operation.

We can demonstrate this operation more clearly if we define
an abstract atomic operation::

	long cas(long *mem, long old, long new);

"cas" stands for "compare and swap".  It atomically:

1) Compares "old" with the value currently at "mem".
2) If they are equal, "new" is written to "mem".
3) Regardless, the current value at "mem" is returned.

As an example usage, here is what an atomic counter update
might look like::

	void example_atomic_inc(long *counter)
	{
		long old, new, ret;

		while (1) {
			old = *counter;
			new = old + 1;

			ret = cas(counter, old, new);
			if (ret == old)
				break;
		}
	}

Let's use cas() in order to build a pseudo-C atomic_dec_and_lock()::

	int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
	{
		long old, new, ret;
		int went_to_zero;

		went_to_zero = 0;
		while (1) {
			old = atomic_read(atomic);
			new = old - 1;
			if (new == 0) {
				went_to_zero = 1;
				spin_lock(lock);
			}
			ret = cas(atomic, old, new);
			if (ret == old)
				break;
			if (went_to_zero) {
				spin_unlock(lock);
				went_to_zero = 0;
			}
		}

		return went_to_zero;
	}

Now, as far as memory barriers go, as long as spin_lock()
strictly orders all subsequent memory operations (including
the cas()) with respect to itself, things will be fine.

Said another way, _atomic_dec_and_lock() must guarantee that
a counter dropping to zero is never made visible before the
spinlock being acquired.

.. note::

	Note that this also means that for the case where the counter is not
	dropping to zero, there are no memory ordering requirements.
