| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785 |
- .. SPDX-License-Identifier: GPL-2.0+
- =====================
- Linked Lists in Linux
- =====================
- :Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
- .. contents::
- Introduction
- ============
- Linked lists are one of the most basic data structures used in many programs.
- The Linux kernel implements several different flavours of linked lists. The
- purpose of this document is not to explain linked lists in general, but to show
- new kernel developers how to use the Linux kernel implementations of linked
- lists.
- Please note that while linked lists certainly are ubiquitous, they are rarely
- the best data structure to use in cases where a simple array doesn't already
- suffice. In particular, due to their poor data locality, linked lists are a bad
- choice in situations where performance may be of consideration. Familiarizing
- oneself with other in-kernel generic data structures, especially for concurrent
- accesses, is highly encouraged.
- Linux implementation of doubly linked lists
- ===========================================
- Linux's linked list implementations can be used by including the header file
- ``<linux/list.h>``.
- The doubly-linked list will likely be the most familiar to many readers. It's a
- list that can efficiently be traversed forwards and backwards.
- The Linux kernel's doubly-linked list is circular in nature. This means that to
- get from the head node to the tail, we can just travel one edge backwards.
- Similarly, to get from the tail node to the head, we can simply travel forwards
- "beyond" the tail and arrive back at the head.
- Declaring a node
- ----------------
- A node in a doubly-linked list is declared by adding a struct list_head
- member to the data structure you wish to be contained in the list:
- .. code-block:: c
- struct clown {
- unsigned long long shoe_size;
- const char *name;
- struct list_head node; /* the aforementioned member */
- };
- This may be an unfamiliar approach to some, as the classical explanation of a
- linked list is a list node data structure with pointers to the previous and next
- list node, as well the payload data. Linux chooses this approach because it
- allows for generic list modification code regardless of what data structure is
- contained within the list. Since the struct list_head member is not a pointer
- but part of the data structure proper, the container_of() pattern can be used by
- the list implementation to access the payload data regardless of its type, while
- staying oblivious to what said type actually is.
- Declaring and initializing a list
- ---------------------------------
- A doubly-linked list can then be declared as just another struct list_head,
- and initialized with the LIST_HEAD_INIT() macro during initial assignment, or
- with the INIT_LIST_HEAD() function later:
- .. code-block:: c
- struct clown_car {
- int tyre_pressure[4];
- struct list_head clowns; /* Looks like a node! */
- };
- /* ... Somewhere later in our driver ... */
- static int circus_init(struct circus_priv *circus)
- {
- struct clown_car other_car = {
- .tyre_pressure = {10, 12, 11, 9},
- .clowns = LIST_HEAD_INIT(other_car.clowns)
- };
- INIT_LIST_HEAD(&circus->car.clowns);
- return 0;
- }
- A further point of confusion to some may be that the list itself doesn't really
- have its own type. The concept of the entire linked list and a
- struct list_head member that points to other entries in the list are one and
- the same.
- Adding nodes to the list
- ------------------------
- Adding a node to the linked list is done through the list_add() macro.
- We'll return to our clown car example to illustrate how nodes get added to the
- list:
- .. code-block:: c
- static int circus_fill_car(struct circus_priv *circus)
- {
- struct clown_car *car = &circus->car;
- struct clown *grock;
- struct clown *dimitri;
- /* State 1 */
- grock = kzalloc(sizeof(*grock), GFP_KERNEL);
- if (!grock)
- return -ENOMEM;
- grock->name = "Grock";
- grock->shoe_size = 1000;
- /* Note that we're adding the "node" member */
- list_add(&grock->node, &car->clowns);
- /* State 2 */
- dimitri = kzalloc(sizeof(*dimitri), GFP_KERNEL);
- if (!dimitri)
- return -ENOMEM;
- dimitri->name = "Dimitri";
- dimitri->shoe_size = 50;
- list_add(&dimitri->node, &car->clowns);
- /* State 3 */
- return 0;
- }
- In State 1, our list of clowns is still empty::
- .------.
- v |
- .--------. |
- | clowns |--'
- '--------'
- This diagram shows the singular "clowns" node pointing at itself. In this
- diagram, and all following diagrams, only the forward edges are shown, to aid in
- clarity.
- In State 2, we've added Grock after the list head::
- .--------------------.
- v |
- .--------. .-------. |
- | clowns |---->| Grock |--'
- '--------' '-------'
- This diagram shows the "clowns" node pointing at a new node labeled "Grock".
- The Grock node is pointing back at the "clowns" node.
- In State 3, we've added Dimitri after the list head, resulting in the following::
- .------------------------------------.
- v |
- .--------. .---------. .-------. |
- | clowns |---->| Dimitri |---->| Grock |--'
- '--------' '---------' '-------'
- This diagram shows the "clowns" node pointing at a new node labeled "Dimitri",
- which then points at the node labeled "Grock". The "Grock" node still points
- back at the "clowns" node.
- If we wanted to have Dimitri inserted at the end of the list instead, we'd use
- list_add_tail(). Our code would then look like this:
- .. code-block:: c
- static int circus_fill_car(struct circus_priv *circus)
- {
- /* ... */
- list_add_tail(&dimitri->node, &car->clowns);
- /* State 3b */
- return 0;
- }
- This results in the following list::
- .------------------------------------.
- v |
- .--------. .-------. .---------. |
- | clowns |---->| Grock |---->| Dimitri |--'
- '--------' '-------' '---------'
- This diagram shows the "clowns" node pointing at the node labeled "Grock",
- which points at the new node labeled "Dimitri". The node labeled "Dimitri"
- points back at the "clowns" node.
- Traversing the list
- -------------------
- To iterate the list, we can loop through all nodes within the list with
- list_for_each().
- In our clown example, this results in the following somewhat awkward code:
- .. code-block:: c
- static unsigned long long circus_get_max_shoe_size(struct circus_priv *circus)
- {
- unsigned long long res = 0;
- struct clown *e;
- struct list_head *cur;
- list_for_each(cur, &circus->car.clowns) {
- e = list_entry(cur, struct clown, node);
- if (e->shoe_size > res)
- res = e->shoe_size;
- }
- return res;
- }
- The list_entry() macro internally uses the aforementioned container_of() to
- retrieve the data structure instance that ``node`` is a member of.
- Note how the additional list_entry() call is a little awkward here. It's only
- there because we're iterating through the ``node`` members, but we really want
- to iterate through the payload, i.e. the ``struct clown`` that contains each
- node's struct list_head. For this reason, there is a second macro:
- list_for_each_entry()
- Using it would change our code to something like this:
- .. code-block:: c
- static unsigned long long circus_get_max_shoe_size(struct circus_priv *circus)
- {
- unsigned long long res = 0;
- struct clown *e;
- list_for_each_entry(e, &circus->car.clowns, node) {
- if (e->shoe_size > res)
- res = e->shoe_size;
- }
- return res;
- }
- This eliminates the need for the list_entry() step, and our loop cursor is now
- of the type of our payload. The macro is given the member name that corresponds
- to the list's struct list_head within the clown data structure so that it can
- still walk the list.
- Removing nodes from the list
- ----------------------------
- The list_del() function can be used to remove entries from the list. It not only
- removes the given entry from the list, but poisons the entry's ``prev`` and
- ``next`` pointers, so that unintended use of the entry after removal does not
- go unnoticed.
- We can extend our previous example to remove one of the entries:
- .. code-block:: c
- static int circus_fill_car(struct circus_priv *circus)
- {
- /* ... */
- list_add(&dimitri->node, &car->clowns);
- /* State 3 */
- list_del(&dimitri->node);
- /* State 4 */
- return 0;
- }
- The result of this would be this::
- .--------------------.
- v |
- .--------. .-------. | .---------.
- | clowns |---->| Grock |--' | Dimitri |
- '--------' '-------' '---------'
- This diagram shows the "clowns" node pointing at the node labeled "Grock",
- which points back at the "clowns" node. Off to the side is a lone node labeled
- "Dimitri", which has no arrows pointing anywhere.
- Note how the Dimitri node does not point to itself; its pointers are
- intentionally set to a "poison" value that the list code refuses to traverse.
- If we wanted to reinitialize the removed node instead to make it point at itself
- again like an empty list head, we can use list_del_init() instead:
- .. code-block:: c
- static int circus_fill_car(struct circus_priv *circus)
- {
- /* ... */
- list_add(&dimitri->node, &car->clowns);
- /* State 3 */
- list_del_init(&dimitri->node);
- /* State 4b */
- return 0;
- }
- This results in the deleted node pointing to itself again::
- .--------------------. .-------.
- v | v |
- .--------. .-------. | .---------. |
- | clowns |---->| Grock |--' | Dimitri |--'
- '--------' '-------' '---------'
- This diagram shows the "clowns" node pointing at the node labeled "Grock",
- which points back at the "clowns" node. Off to the side is a lone node labeled
- "Dimitri", which points to itself.
- Traversing whilst removing nodes
- --------------------------------
- Deleting entries while we're traversing the list will cause problems if we use
- list_for_each() and list_for_each_entry(), as deleting the current entry would
- modify the ``next`` pointer of it, which means the traversal can't properly
- advance to the next list entry.
- There is a solution to this however: list_for_each_safe() and
- list_for_each_entry_safe(). These take an additional parameter of a pointer to
- a struct list_head to use as temporary storage for the next entry during
- iteration, solving the issue.
- An example of how to use it:
- .. code-block:: c
- static void circus_eject_insufficient_clowns(struct circus_priv *circus)
- {
- struct clown *e;
- struct clown *n; /* temporary storage for safe iteration */
- list_for_each_entry_safe(e, n, &circus->car.clowns, node) {
- if (e->shoe_size < 500)
- list_del(&e->node);
- }
- }
- Proper memory management (i.e. freeing the deleted node while making sure
- nothing still references it) in this case is left as an exercise to the reader.
- Cutting a list
- --------------
- There are two helper functions to cut lists with. Both take elements from the
- list ``head``, and replace the contents of the list ``list``.
- The first such function is list_cut_position(). It removes all list entries from
- ``head`` up to and including ``entry``, placing them in ``list`` instead.
- In this example, it's assumed we start with the following list::
- .----------------------------------------------------------------.
- v |
- .--------. .-------. .---------. .-----. .---------. |
- | clowns |---->| Grock |---->| Dimitri |---->| Pic |---->| Alfredo |--'
- '--------' '-------' '---------' '-----' '---------'
- With the following code, every clown up to and including "Pic" is moved from
- the "clowns" list head to a separate struct list_head initialized at local
- stack variable ``retirement``:
- .. code-block:: c
- static void circus_retire_clowns(struct circus_priv *circus)
- {
- struct list_head retirement = LIST_HEAD_INIT(retirement);
- struct clown *grock, *dimitri, *pic, *alfredo;
- struct clown_car *car = &circus->car;
- /* ... clown initialization, list adding ... */
- list_cut_position(&retirement, &car->clowns, &pic->node);
- /* State 1 */
- }
- The resulting ``car->clowns`` list would be this::
- .----------------------.
- v |
- .--------. .---------. |
- | clowns |---->| Alfredo |--'
- '--------' '---------'
- Meanwhile, the ``retirement`` list is transformed to the following::
- .--------------------------------------------------.
- v |
- .------------. .-------. .---------. .-----. |
- | retirement |---->| Grock |---->| Dimitri |---->| Pic |--'
- '------------' '-------' '---------' '-----'
- The second function, list_cut_before(), is much the same, except it cuts before
- the ``entry`` node, i.e. it removes all list entries from ``head`` up to but
- excluding ``entry``, placing them in ``list`` instead. This example assumes the
- same initial starting list as the previous example:
- .. code-block:: c
- static void circus_retire_clowns(struct circus_priv *circus)
- {
- struct list_head retirement = LIST_HEAD_INIT(retirement);
- struct clown *grock, *dimitri, *pic, *alfredo;
- struct clown_car *car = &circus->car;
- /* ... clown initialization, list adding ... */
- list_cut_before(&retirement, &car->clowns, &pic->node);
- /* State 1b */
- }
- The resulting ``car->clowns`` list would be this::
- .----------------------------------.
- v |
- .--------. .-----. .---------. |
- | clowns |---->| Pic |---->| Alfredo |--'
- '--------' '-----' '---------'
- Meanwhile, the ``retirement`` list is transformed to the following::
- .--------------------------------------.
- v |
- .------------. .-------. .---------. |
- | retirement |---->| Grock |---->| Dimitri |--'
- '------------' '-------' '---------'
- It should be noted that both functions will destroy links to any existing nodes
- in the destination ``struct list_head *list``.
- Moving entries and partial lists
- --------------------------------
- The list_move() and list_move_tail() functions can be used to move an entry
- from one list to another, to either the start or end respectively.
- In the following example, we'll assume we start with two lists ("clowns" and
- "sidewalk" in the following initial state "State 0"::
- .----------------------------------------------------------------.
- v |
- .--------. .-------. .---------. .-----. .---------. |
- | clowns |---->| Grock |---->| Dimitri |---->| Pic |---->| Alfredo |--'
- '--------' '-------' '---------' '-----' '---------'
- .-------------------.
- v |
- .----------. .-----. |
- | sidewalk |---->| Pio |--'
- '----------' '-----'
- We apply the following example code to the two lists:
- .. code-block:: c
- static void circus_clowns_exit_car(struct circus_priv *circus)
- {
- struct list_head sidewalk = LIST_HEAD_INIT(sidewalk);
- struct clown *grock, *dimitri, *pic, *alfredo, *pio;
- struct clown_car *car = &circus->car;
- /* ... clown initialization, list adding ... */
- /* State 0 */
- list_move(&pic->node, &sidewalk);
- /* State 1 */
- list_move_tail(&dimitri->node, &sidewalk);
- /* State 2 */
- }
- In State 1, we arrive at the following situation::
- .-----------------------------------------------------.
- | |
- v |
- .--------. .-------. .---------. .---------. |
- | clowns |---->| Grock |---->| Dimitri |---->| Alfredo |--'
- '--------' '-------' '---------' '---------'
- .-------------------------------.
- v |
- .----------. .-----. .-----. |
- | sidewalk |---->| Pic |---->| Pio |--'
- '----------' '-----' '-----'
- In State 2, after we've moved Dimitri to the tail of sidewalk, the situation
- changes as follows::
- .-------------------------------------.
- | |
- v |
- .--------. .-------. .---------. |
- | clowns |---->| Grock |---->| Alfredo |--'
- '--------' '-------' '---------'
- .-----------------------------------------------.
- v |
- .----------. .-----. .-----. .---------. |
- | sidewalk |---->| Pic |---->| Pio |---->| Dimitri |--'
- '----------' '-----' '-----' '---------'
- As long as the source and destination list head are part of the same list, we
- can also efficiently bulk move a segment of the list to the tail end of the
- list. We continue the previous example by adding a list_bulk_move_tail() after
- State 2, moving Pic and Pio to the tail end of the sidewalk list.
- .. code-block:: c
- static void circus_clowns_exit_car(struct circus_priv *circus)
- {
- struct list_head sidewalk = LIST_HEAD_INIT(sidewalk);
- struct clown *grock, *dimitri, *pic, *alfredo, *pio;
- struct clown_car *car = &circus->car;
- /* ... clown initialization, list adding ... */
- /* State 0 */
- list_move(&pic->node, &sidewalk);
- /* State 1 */
- list_move_tail(&dimitri->node, &sidewalk);
- /* State 2 */
- list_bulk_move_tail(&sidewalk, &pic->node, &pio->node);
- /* State 3 */
- }
- For the sake of brevity, only the altered "sidewalk" list at State 3 is depicted
- in the following diagram::
- .-----------------------------------------------.
- v |
- .----------. .---------. .-----. .-----. |
- | sidewalk |---->| Dimitri |---->| Pic |---->| Pio |--'
- '----------' '---------' '-----' '-----'
- Do note that list_bulk_move_tail() does not do any checking as to whether all
- three supplied ``struct list_head *`` parameters really do belong to the same
- list. If you use it outside the constraints the documentation gives, then the
- result is a matter between you and the implementation.
- Rotating entries
- ----------------
- A common write operation on lists, especially when using them as queues, is
- to rotate it. A list rotation means entries at the front are sent to the back.
- For rotation, Linux provides us with two functions: list_rotate_left() and
- list_rotate_to_front(). The former can be pictured like a bicycle chain, taking
- the entry after the supplied ``struct list_head *`` and moving it to the tail,
- which in essence means the entire list, due to its circular nature, rotates by
- one position.
- The latter, list_rotate_to_front(), takes the same concept one step further:
- instead of advancing the list by one entry, it advances it *until* the specified
- entry is the new front.
- In the following example, our starting state, State 0, is the following::
- .-----------------------------------------------------------------.
- v |
- .--------. .-------. .---------. .-----. .---------. .-----. |
- | clowns |-->| Grock |-->| Dimitri |-->| Pic |-->| Alfredo |-->| Pio |-'
- '--------' '-------' '---------' '-----' '---------' '-----'
- The example code being used to demonstrate list rotations is the following:
- .. code-block:: c
- static void circus_clowns_rotate(struct circus_priv *circus)
- {
- struct clown *grock, *dimitri, *pic, *alfredo, *pio;
- struct clown_car *car = &circus->car;
- /* ... clown initialization, list adding ... */
- /* State 0 */
- list_rotate_left(&car->clowns);
- /* State 1 */
- list_rotate_to_front(&alfredo->node, &car->clowns);
- /* State 2 */
- }
- In State 1, we arrive at the following situation::
- .-----------------------------------------------------------------.
- v |
- .--------. .---------. .-----. .---------. .-----. .-------. |
- | clowns |-->| Dimitri |-->| Pic |-->| Alfredo |-->| Pio |-->| Grock |-'
- '--------' '---------' '-----' '---------' '-----' '-------'
- Next, after the list_rotate_to_front() call, we arrive in the following
- State 2::
- .-----------------------------------------------------------------.
- v |
- .--------. .---------. .-----. .-------. .---------. .-----. |
- | clowns |-->| Alfredo |-->| Pio |-->| Grock |-->| Dimitri |-->| Pic |-'
- '--------' '---------' '-----' '-------' '---------' '-----'
- As is hopefully evident from the diagrams, the entries in front of "Alfredo"
- were cycled to the tail end of the list.
- Swapping entries
- ----------------
- Another common operation is that two entries need to be swapped with each other.
- For this, Linux provides us with list_swap().
- In the following example, we have a list with three entries, and swap two of
- them. This is our starting state in "State 0"::
- .-----------------------------------------.
- v |
- .--------. .-------. .---------. .-----. |
- | clowns |-->| Grock |-->| Dimitri |-->| Pic |-'
- '--------' '-------' '---------' '-----'
- .. code-block:: c
- static void circus_clowns_swap(struct circus_priv *circus)
- {
- struct clown *grock, *dimitri, *pic;
- struct clown_car *car = &circus->car;
- /* ... clown initialization, list adding ... */
- /* State 0 */
- list_swap(&dimitri->node, &pic->node);
- /* State 1 */
- }
- The resulting list at State 1 is the following::
- .-----------------------------------------.
- v |
- .--------. .-------. .-----. .---------. |
- | clowns |-->| Grock |-->| Pic |-->| Dimitri |-'
- '--------' '-------' '-----' '---------'
- As is evident by comparing the diagrams, the "Pic" and "Dimitri" nodes have
- traded places.
- Splicing two lists together
- ---------------------------
- Say we have two lists, in the following example one represented by a list head
- we call "knie" and one we call "stey". In a hypothetical circus acquisition,
- the two list of clowns should be spliced together. The following is our
- situation in "State 0"::
- .-----------------------------------------.
- | |
- v |
- .------. .-------. .---------. .-----. |
- | knie |-->| Grock |-->| Dimitri |-->| Pic |--'
- '------' '-------' '---------' '-----'
- .-----------------------------.
- v |
- .------. .---------. .-----. |
- | stey |-->| Alfredo |-->| Pio |--'
- '------' '---------' '-----'
- The function to splice these two lists together is list_splice(). Our example
- code is as follows:
- .. code-block:: c
- static void circus_clowns_splice(void)
- {
- struct clown *grock, *dimitri, *pic, *alfredo, *pio;
- struct list_head knie = LIST_HEAD_INIT(knie);
- struct list_head stey = LIST_HEAD_INIT(stey);
- /* ... Clown allocation and initialization here ... */
- list_add_tail(&grock->node, &knie);
- list_add_tail(&dimitri->node, &knie);
- list_add_tail(&pic->node, &knie);
- list_add_tail(&alfredo->node, &stey);
- list_add_tail(&pio->node, &stey);
- /* State 0 */
- list_splice(&stey, &dimitri->node);
- /* State 1 */
- }
- The list_splice() call here adds all the entries in ``stey`` to the list
- ``dimitri``'s ``node`` list_head is in, after the ``node`` of ``dimitri``. A
- somewhat surprising diagram of the resulting "State 1" follows::
- .-----------------------------------------------------------------.
- | |
- v |
- .------. .-------. .---------. .---------. .-----. .-----. |
- | knie |-->| Grock |-->| Dimitri |-->| Alfredo |-->| Pio |-->| Pic |--'
- '------' '-------' '---------' '---------' '-----' '-----'
- ^
- .-------------------------------'
- |
- .------. |
- | stey |--'
- '------'
- Traversing the ``stey`` list no longer results in correct behavior. A call of
- list_for_each() on ``stey`` results in an infinite loop, as it never returns
- back to the ``stey`` list head.
- This is because list_splice() did not reinitialize the list_head it took
- entries from, leaving its pointer pointing into what is now a different list.
- If we want to avoid this situation, list_splice_init() can be used. It does the
- same thing as list_splice(), except reinitalizes the donor list_head after the
- transplant.
- Concurrency considerations
- --------------------------
- Concurrent access and modification of a list needs to be protected with a lock
- in most cases. Alternatively and preferably, one may use the RCU primitives for
- lists in read-mostly use-cases, where read accesses to the list are common but
- modifications to the list less so. See Documentation/RCU/listRCU.rst for more
- details.
- Further reading
- ---------------
- * `How does the kernel implements Linked Lists? - KernelNewbies <https://kernelnewbies.org/FAQ/LinkedLists>`_
- Full List API
- =============
- .. kernel-doc:: include/linux/list.h
- :internal:
- Private List API
- ================
- .. kernel-doc:: include/linux/list_private.h
- :doc: Private List Primitives
- .. kernel-doc:: include/linux/list_private.h
- :internal:
|