linux/include
Huang Ying f49f23abf3 lib, Add lock-less NULL terminated single list
Cmpxchg is used to implement adding new entry to the list, deleting
all entries from the list, deleting first entry of the list and some
other operations.

Because this is a single list, so the tail can not be accessed in O(1).

If there are multiple producers and multiple consumers, llist_add can
be used in producers and llist_del_all can be used in consumers.  They
can work simultaneously without lock.  But llist_del_first can not be
used here.  Because llist_del_first depends on list->first->next does
not changed if list->first is not changed during its operation, but
llist_del_first, llist_add, llist_add (or llist_del_all, llist_add,
llist_add) sequence in another consumer may violate that.

If there are multiple producers and one consumer, llist_add can be
used in producers and llist_del_all or llist_del_first can be used in
the consumer.

This can be summarized as follow:

           |   add    | del_first |  del_all
 add       |    -     |     -     |     -
 del_first |          |     L     |     L
 del_all   |          |           |     -

Where "-" stands for no lock is needed, while "L" stands for lock is
needed.

The list entries deleted via llist_del_all can be traversed with
traversing function such as llist_for_each etc.  But the list entries
can not be traversed safely before deleted from the list.  The order
of deleted entries is from the newest to the oldest added one.  If you
want to traverse from the oldest to the newest, you must reverse the
order by yourself before traversing.

The basic atomic operation of this list is cmpxchg on long.  On
architectures that don't have NMI-safe cmpxchg implementation, the
list can NOT be used in NMI handler.  So code uses the list in NMI
handler should depend on CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG.

Signed-off-by: Huang Ying <ying.huang@intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
2011-08-03 11:15:56 -04:00
..
acpi ACPI, APEI, GHES, Support disable GHES at boot time 2011-07-13 23:36:34 -04:00
asm-generic Merge branches 'gpio/merge' and 'spi/merge' of git://git.secretlab.ca/git/linux-2.6 2011-06-17 10:36:32 -07:00
crypto
drm drm/radeon: workaround a hw bug on some radeon chipsets with all-0 EDIDs. 2011-06-16 16:30:54 +10:00
keys
linux lib, Add lock-less NULL terminated single list 2011-08-03 11:15:56 -04:00
math-emu
media [media] tuner-core/v4l2-subdev: document that the type field has to be filled in 2011-07-07 15:04:23 -03:00
mtd
net ipv6: Don't put artificial limit on routing table size. 2011-07-01 17:30:43 -07:00
pcmcia
rdma Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband 2011-05-26 12:13:57 -07:00
rxrpc
scsi [SCSI] libsas: Add option for SATA soft reset 2011-05-26 22:49:33 -05:00
sound ALSA: sb16 - Fix build errors on MIPS and others with 13bit ioctl size 2011-06-30 15:33:57 +02:00
target [SCSI] target: Convert REPORT_LUNs to use int_to_scsilun 2011-05-24 13:02:42 -04:00
trace Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4 2011-06-21 10:22:35 -07:00
video Merge branches 'common/fbdev' and 'common/fbdev-meram' of master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6 2011-05-24 15:49:57 +09:00
xen Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/djm/tmem 2011-05-26 10:50:56 -07:00
Kbuild