Commit d78973c3 authored by Joel Fernandes's avatar Joel Fernandes Committed by Paul E. McKenney

llist: Clarify comments about when locking is needed

llist.h comments are confusing about when locking is needed versus when it
isn't. Clarify these comments by being more descriptive about why locking is
needed for llist_del_first.

Cc: Ingo Molnar <mingo@kernel.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
Acked-by: default avatarHuang Ying <ying.huang@intel.com>
Acked-by: default avatarMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: default avatarJoel Fernandes <joelaf@google.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: default avatarJosh Triplett <josh@joshtriplett.org>
parent 9831ce3b
...@@ -3,28 +3,33 @@ ...@@ -3,28 +3,33 @@
/* /*
* Lock-less NULL terminated single linked list * Lock-less NULL terminated single linked list
* *
* If there are multiple producers and multiple consumers, llist_add * Cases where locking is not needed:
* can be used in producers and llist_del_all can be used in * If there are multiple producers and multiple consumers, llist_add can be
* consumers. They can work simultaneously without lock. But * used in producers and llist_del_all can be used in consumers simultaneously
* llist_del_first can not be used here. Because llist_del_first * without locking. Also a single consumer can use llist_del_first while
* depends on list->first->next does not changed if list->first is not * multiple producers simultaneously use llist_add, without any locking.
* changed during its operation, but llist_del_first, llist_add, *
* llist_add (or llist_del_all, llist_add, llist_add) sequence in * Cases where locking is needed:
* another consumer may violate that. * If we have multiple consumers with llist_del_first used in one consumer, and
* * llist_del_first or llist_del_all used in other consumers, then a lock is
* If there are multiple producers and one consumer, llist_add can be * needed. This is because llist_del_first depends on list->first->next not
* used in producers and llist_del_all or llist_del_first can be used * changing, but without lock protection, there's no way to be sure about that
* in the consumer. * if a preemption happens in the middle of the delete operation and on being
* * preempted back, the list->first is the same as before causing the cmpxchg in
* This can be summarized as follow: * llist_del_first to succeed. For example, while a llist_del_first operation
* is in progress in one consumer, then a llist_del_first, llist_add,
* llist_add (or llist_del_all, llist_add, llist_add) sequence in another
* consumer may cause violations.
*
* This can be summarized as follows:
* *
* | add | del_first | del_all * | add | del_first | del_all
* add | - | - | - * add | - | - | -
* del_first | | L | L * del_first | | L | L
* del_all | | | - * del_all | | | -
* *
* Where "-" stands for no lock is needed, while "L" stands for lock * Where, a particular row's operation can happen concurrently with a column's
* is needed. * operation, with "-" being no lock needed, while "L" being lock is needed.
* *
* The list entries deleted via llist_del_all can be traversed with * The list entries deleted via llist_del_all can be traversed with
* traversing function such as llist_for_each etc. But the list * traversing function such as llist_for_each etc. But the list
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment