Commit 46deb744 authored by Paul E. McKenney's avatar Paul E. McKenney

rcu: Add and update docbook header comments in list.h

[ paulmck: Fix typo found by kbuild test robot. ]
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent 860c8802
...@@ -23,6 +23,13 @@ ...@@ -23,6 +23,13 @@
#define LIST_HEAD(name) \ #define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name) struct list_head name = LIST_HEAD_INIT(name)
/**
* INIT_LIST_HEAD - Initialize a list_head structure
* @list: list_head structure to be initialized.
*
* Initializes the list_head to point to itself. If it is a list header,
* the result is an empty list.
*/
static inline void INIT_LIST_HEAD(struct list_head *list) static inline void INIT_LIST_HEAD(struct list_head *list)
{ {
WRITE_ONCE(list->next, list); WRITE_ONCE(list->next, list);
...@@ -120,12 +127,6 @@ static inline void __list_del_clearprev(struct list_head *entry) ...@@ -120,12 +127,6 @@ static inline void __list_del_clearprev(struct list_head *entry)
entry->prev = NULL; entry->prev = NULL;
} }
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void __list_del_entry(struct list_head *entry) static inline void __list_del_entry(struct list_head *entry)
{ {
if (!__list_del_entry_valid(entry)) if (!__list_del_entry_valid(entry))
...@@ -134,6 +135,12 @@ static inline void __list_del_entry(struct list_head *entry) ...@@ -134,6 +135,12 @@ static inline void __list_del_entry(struct list_head *entry)
__list_del(entry->prev, entry->next); __list_del(entry->prev, entry->next);
} }
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry) static inline void list_del(struct list_head *entry)
{ {
__list_del_entry(entry); __list_del_entry(entry);
...@@ -157,8 +164,15 @@ static inline void list_replace(struct list_head *old, ...@@ -157,8 +164,15 @@ static inline void list_replace(struct list_head *old,
new->prev->next = new; new->prev->next = new;
} }
/**
* list_replace_init - replace old entry by new one and initialize the old one
* @old : the element to be replaced
* @new : the new element to insert
*
* If @old was empty, it will be overwritten.
*/
static inline void list_replace_init(struct list_head *old, static inline void list_replace_init(struct list_head *old,
struct list_head *new) struct list_head *new)
{ {
list_replace(old, new); list_replace(old, new);
INIT_LIST_HEAD(old); INIT_LIST_HEAD(old);
...@@ -744,21 +758,36 @@ static inline void INIT_HLIST_NODE(struct hlist_node *h) ...@@ -744,21 +758,36 @@ static inline void INIT_HLIST_NODE(struct hlist_node *h)
h->pprev = NULL; h->pprev = NULL;
} }
/**
* hlist_unhashed - Has node been removed from list and reinitialized?
* @h: Node to be checked
*
* Not that not all removal functions will leave a node in unhashed
* state. For example, hlist_nulls_del_init_rcu() does leave the
* node in unhashed state, but hlist_nulls_del() does not.
*/
static inline int hlist_unhashed(const struct hlist_node *h) static inline int hlist_unhashed(const struct hlist_node *h)
{ {
return !h->pprev; return !h->pprev;
} }
/* This variant of hlist_unhashed() must be used in lockless contexts /**
* to avoid potential load-tearing. * hlist_unhashed_lockless - Version of hlist_unhashed for lockless use
* The READ_ONCE() is paired with the various WRITE_ONCE() in hlist * @h: Node to be checked
* helpers that are defined below. *
* This variant of hlist_unhashed() must be used in lockless contexts
* to avoid potential load-tearing. The READ_ONCE() is paired with the
* various WRITE_ONCE() in hlist helpers that are defined below.
*/ */
static inline int hlist_unhashed_lockless(const struct hlist_node *h) static inline int hlist_unhashed_lockless(const struct hlist_node *h)
{ {
return !READ_ONCE(h->pprev); return !READ_ONCE(h->pprev);
} }
/**
* hlist_empty - Is the specified hlist_head structure an empty hlist?
* @h: Structure to check.
*/
static inline int hlist_empty(const struct hlist_head *h) static inline int hlist_empty(const struct hlist_head *h)
{ {
return !READ_ONCE(h->first); return !READ_ONCE(h->first);
...@@ -774,6 +803,13 @@ static inline void __hlist_del(struct hlist_node *n) ...@@ -774,6 +803,13 @@ static inline void __hlist_del(struct hlist_node *n)
WRITE_ONCE(next->pprev, pprev); WRITE_ONCE(next->pprev, pprev);
} }
/**
* hlist_del - Delete the specified hlist_node from its list
* @n: Node to delete.
*
* Note that this function leaves the node in hashed state. Use
* hlist_del_init() or similar instead to unhash @n.
*/
static inline void hlist_del(struct hlist_node *n) static inline void hlist_del(struct hlist_node *n)
{ {
__hlist_del(n); __hlist_del(n);
...@@ -781,6 +817,12 @@ static inline void hlist_del(struct hlist_node *n) ...@@ -781,6 +817,12 @@ static inline void hlist_del(struct hlist_node *n)
n->pprev = LIST_POISON2; n->pprev = LIST_POISON2;
} }
/**
* hlist_del_init - Delete the specified hlist_node from its list and initialize
* @n: Node to delete.
*
* Note that this function leaves the node in unhashed state.
*/
static inline void hlist_del_init(struct hlist_node *n) static inline void hlist_del_init(struct hlist_node *n)
{ {
if (!hlist_unhashed(n)) { if (!hlist_unhashed(n)) {
...@@ -789,6 +831,14 @@ static inline void hlist_del_init(struct hlist_node *n) ...@@ -789,6 +831,14 @@ static inline void hlist_del_init(struct hlist_node *n)
} }
} }
/**
* hlist_add_head - add a new entry at the beginning of the hlist
* @n: new entry to be added
* @h: hlist head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{ {
struct hlist_node *first = h->first; struct hlist_node *first = h->first;
...@@ -799,9 +849,13 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) ...@@ -799,9 +849,13 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
WRITE_ONCE(n->pprev, &h->first); WRITE_ONCE(n->pprev, &h->first);
} }
/* next must be != NULL */ /**
* hlist_add_before - add a new entry before the one specified
* @n: new entry to be added
* @next: hlist node to add it before, which must be non-NULL
*/
static inline void hlist_add_before(struct hlist_node *n, static inline void hlist_add_before(struct hlist_node *n,
struct hlist_node *next) struct hlist_node *next)
{ {
WRITE_ONCE(n->pprev, next->pprev); WRITE_ONCE(n->pprev, next->pprev);
WRITE_ONCE(n->next, next); WRITE_ONCE(n->next, next);
...@@ -809,6 +863,11 @@ static inline void hlist_add_before(struct hlist_node *n, ...@@ -809,6 +863,11 @@ static inline void hlist_add_before(struct hlist_node *n,
WRITE_ONCE(*(n->pprev), n); WRITE_ONCE(*(n->pprev), n);
} }
/**
* hlist_add_behing - add a new entry after the one specified
* @n: new entry to be added
* @prev: hlist node to add it after, which must be non-NULL
*/
static inline void hlist_add_behind(struct hlist_node *n, static inline void hlist_add_behind(struct hlist_node *n,
struct hlist_node *prev) struct hlist_node *prev)
{ {
...@@ -820,20 +879,35 @@ static inline void hlist_add_behind(struct hlist_node *n, ...@@ -820,20 +879,35 @@ static inline void hlist_add_behind(struct hlist_node *n,
WRITE_ONCE(n->next->pprev, &n->next); WRITE_ONCE(n->next->pprev, &n->next);
} }
/* after that we'll appear to be on some hlist and hlist_del will work */ /**
* hlist_add_fake - create a fake hlist consisting of a single headless node
* @n: Node to make a fake list out of
*
* This makes @n appear to be its own predecessor on a headless hlist.
* The point of this is to allow things like hlist_del() to work correctly
* in cases where there is no list.
*/
static inline void hlist_add_fake(struct hlist_node *n) static inline void hlist_add_fake(struct hlist_node *n)
{ {
n->pprev = &n->next; n->pprev = &n->next;
} }
/**
* hlist_fake: Is this node a fake hlist?
* @h: Node to check for being a self-referential fake hlist.
*/
static inline bool hlist_fake(struct hlist_node *h) static inline bool hlist_fake(struct hlist_node *h)
{ {
return h->pprev == &h->next; return h->pprev == &h->next;
} }
/* /**
* hlist_is_singular_node - is node the only element of the specified hlist?
* @n: Node to check for singularity.
* @h: Header for potentially singular list.
*
* Check whether the node is the only node of the head without * Check whether the node is the only node of the head without
* accessing head: * accessing head, thus avoiding unnecessary cache misses.
*/ */
static inline bool static inline bool
hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h) hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h)
...@@ -841,7 +915,11 @@ hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h) ...@@ -841,7 +915,11 @@ hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h)
return !n->next && n->pprev == &h->first; return !n->next && n->pprev == &h->first;
} }
/* /**
* hlist_move_list - Move an hlist
* @old: hlist_head for old list.
* @new: hlist_head for new list.
*
* Move a list from one list head to another. Fixup the pprev * Move a list from one list head to another. Fixup the pprev
* reference of the first entry if it exists. * reference of the first entry if it exists.
*/ */
......
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