257 lines
9.8 KiB
C
257 lines
9.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
/*
|
|
* Copyright (c) 2025, Google LLC.
|
|
* Pasha Tatashin <pasha.tatashin@soleen.com>
|
|
*/
|
|
#ifndef _LINUX_LIST_PRIVATE_H
|
|
#define _LINUX_LIST_PRIVATE_H
|
|
|
|
/**
|
|
* DOC: Private List Primitives
|
|
*
|
|
* Provides a set of list primitives identical in function to those in
|
|
* ``<linux/list.h>``, but designed for cases where the embedded
|
|
* ``&struct list_head`` is private member.
|
|
*/
|
|
|
|
#include <linux/compiler.h>
|
|
#include <linux/list.h>
|
|
|
|
#define __list_private_offset(type, member) \
|
|
((size_t)(&ACCESS_PRIVATE(((type *)0), member)))
|
|
|
|
/**
|
|
* list_private_entry - get the struct for this entry
|
|
* @ptr: the &struct list_head pointer.
|
|
* @type: the type of the struct this is embedded in.
|
|
* @member: the identifier passed to ACCESS_PRIVATE.
|
|
*/
|
|
#define list_private_entry(ptr, type, member) ({ \
|
|
const struct list_head *__mptr = (ptr); \
|
|
(type *)((char *)__mptr - __list_private_offset(type, member)); \
|
|
})
|
|
|
|
/**
|
|
* list_private_first_entry - get the first element from a list
|
|
* @ptr: the list head to take the element from.
|
|
* @type: the type of the struct this is embedded in.
|
|
* @member: the identifier passed to ACCESS_PRIVATE.
|
|
*/
|
|
#define list_private_first_entry(ptr, type, member) \
|
|
list_private_entry((ptr)->next, type, member)
|
|
|
|
/**
|
|
* list_private_last_entry - get the last element from a list
|
|
* @ptr: the list head to take the element from.
|
|
* @type: the type of the struct this is embedded in.
|
|
* @member: the identifier passed to ACCESS_PRIVATE.
|
|
*/
|
|
#define list_private_last_entry(ptr, type, member) \
|
|
list_private_entry((ptr)->prev, type, member)
|
|
|
|
/**
|
|
* list_private_next_entry - get the next element in list
|
|
* @pos: the type * to cursor
|
|
* @member: the name of the list_head within the struct.
|
|
*/
|
|
#define list_private_next_entry(pos, member) \
|
|
list_private_entry(ACCESS_PRIVATE(pos, member).next, typeof(*(pos)), member)
|
|
|
|
/**
|
|
* list_private_next_entry_circular - get the next element in list
|
|
* @pos: the type * to cursor.
|
|
* @head: the list head to take the element from.
|
|
* @member: the name of the list_head within the struct.
|
|
*
|
|
* Wraparound if pos is the last element (return the first element).
|
|
* Note, that list is expected to be not empty.
|
|
*/
|
|
#define list_private_next_entry_circular(pos, head, member) \
|
|
(list_is_last(&ACCESS_PRIVATE(pos, member), head) ? \
|
|
list_private_first_entry(head, typeof(*(pos)), member) : \
|
|
list_private_next_entry(pos, member))
|
|
|
|
/**
|
|
* list_private_prev_entry - get the prev element in list
|
|
* @pos: the type * to cursor
|
|
* @member: the name of the list_head within the struct.
|
|
*/
|
|
#define list_private_prev_entry(pos, member) \
|
|
list_private_entry(ACCESS_PRIVATE(pos, member).prev, typeof(*(pos)), member)
|
|
|
|
/**
|
|
* list_private_prev_entry_circular - get the prev element in list
|
|
* @pos: the type * to cursor.
|
|
* @head: the list head to take the element from.
|
|
* @member: the name of the list_head within the struct.
|
|
*
|
|
* Wraparound if pos is the first element (return the last element).
|
|
* Note, that list is expected to be not empty.
|
|
*/
|
|
#define list_private_prev_entry_circular(pos, head, member) \
|
|
(list_is_first(&ACCESS_PRIVATE(pos, member), head) ? \
|
|
list_private_last_entry(head, typeof(*(pos)), member) : \
|
|
list_private_prev_entry(pos, member))
|
|
|
|
/**
|
|
* list_private_entry_is_head - test if the entry points to the head of the list
|
|
* @pos: the type * to cursor
|
|
* @head: the head for your list.
|
|
* @member: the name of the list_head within the struct.
|
|
*/
|
|
#define list_private_entry_is_head(pos, head, member) \
|
|
list_is_head(&ACCESS_PRIVATE(pos, member), (head))
|
|
|
|
/**
|
|
* list_private_for_each_entry - iterate over list of given type
|
|
* @pos: the type * to use as a loop cursor.
|
|
* @head: the head for your list.
|
|
* @member: the name of the list_head within the struct.
|
|
*/
|
|
#define list_private_for_each_entry(pos, head, member) \
|
|
for (pos = list_private_first_entry(head, typeof(*pos), member); \
|
|
!list_private_entry_is_head(pos, head, member); \
|
|
pos = list_private_next_entry(pos, member))
|
|
|
|
/**
|
|
* list_private_for_each_entry_reverse - iterate backwards over list of given type.
|
|
* @pos: the type * to use as a loop cursor.
|
|
* @head: the head for your list.
|
|
* @member: the name of the list_head within the struct.
|
|
*/
|
|
#define list_private_for_each_entry_reverse(pos, head, member) \
|
|
for (pos = list_private_last_entry(head, typeof(*pos), member); \
|
|
!list_private_entry_is_head(pos, head, member); \
|
|
pos = list_private_prev_entry(pos, member))
|
|
|
|
/**
|
|
* list_private_for_each_entry_continue - continue iteration over list of given type
|
|
* @pos: the type * to use as a loop cursor.
|
|
* @head: the head for your list.
|
|
* @member: the name of the list_head within the struct.
|
|
*
|
|
* Continue to iterate over list of given type, continuing after
|
|
* the current position.
|
|
*/
|
|
#define list_private_for_each_entry_continue(pos, head, member) \
|
|
for (pos = list_private_next_entry(pos, member); \
|
|
!list_private_entry_is_head(pos, head, member); \
|
|
pos = list_private_next_entry(pos, member))
|
|
|
|
/**
|
|
* list_private_for_each_entry_continue_reverse - iterate backwards from the given point
|
|
* @pos: the type * to use as a loop cursor.
|
|
* @head: the head for your list.
|
|
* @member: the name of the list_head within the struct.
|
|
*
|
|
* Start to iterate over list of given type backwards, continuing after
|
|
* the current position.
|
|
*/
|
|
#define list_private_for_each_entry_continue_reverse(pos, head, member) \
|
|
for (pos = list_private_prev_entry(pos, member); \
|
|
!list_private_entry_is_head(pos, head, member); \
|
|
pos = list_private_prev_entry(pos, member))
|
|
|
|
/**
|
|
* list_private_for_each_entry_from - iterate over list of given type from the current point
|
|
* @pos: the type * to use as a loop cursor.
|
|
* @head: the head for your list.
|
|
* @member: the name of the list_head within the struct.
|
|
*
|
|
* Iterate over list of given type, continuing from current position.
|
|
*/
|
|
#define list_private_for_each_entry_from(pos, head, member) \
|
|
for (; !list_private_entry_is_head(pos, head, member); \
|
|
pos = list_private_next_entry(pos, member))
|
|
|
|
/**
|
|
* list_private_for_each_entry_from_reverse - iterate backwards over list of given type
|
|
* from the current point
|
|
* @pos: the type * to use as a loop cursor.
|
|
* @head: the head for your list.
|
|
* @member: the name of the list_head within the struct.
|
|
*
|
|
* Iterate backwards over list of given type, continuing from current position.
|
|
*/
|
|
#define list_private_for_each_entry_from_reverse(pos, head, member) \
|
|
for (; !list_private_entry_is_head(pos, head, member); \
|
|
pos = list_private_prev_entry(pos, member))
|
|
|
|
/**
|
|
* list_private_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
|
* @pos: the type * to use as a loop cursor.
|
|
* @n: another type * to use as temporary storage
|
|
* @head: the head for your list.
|
|
* @member: the name of the list_head within the struct.
|
|
*/
|
|
#define list_private_for_each_entry_safe(pos, n, head, member) \
|
|
for (pos = list_private_first_entry(head, typeof(*pos), member), \
|
|
n = list_private_next_entry(pos, member); \
|
|
!list_private_entry_is_head(pos, head, member); \
|
|
pos = n, n = list_private_next_entry(n, member))
|
|
|
|
/**
|
|
* list_private_for_each_entry_safe_continue - continue list iteration safe against removal
|
|
* @pos: the type * to use as a loop cursor.
|
|
* @n: another type * to use as temporary storage
|
|
* @head: the head for your list.
|
|
* @member: the name of the list_head within the struct.
|
|
*
|
|
* Iterate over list of given type, continuing after current point,
|
|
* safe against removal of list entry.
|
|
*/
|
|
#define list_private_for_each_entry_safe_continue(pos, n, head, member) \
|
|
for (pos = list_private_next_entry(pos, member), \
|
|
n = list_private_next_entry(pos, member); \
|
|
!list_private_entry_is_head(pos, head, member); \
|
|
pos = n, n = list_private_next_entry(n, member))
|
|
|
|
/**
|
|
* list_private_for_each_entry_safe_from - iterate over list from current point safe against removal
|
|
* @pos: the type * to use as a loop cursor.
|
|
* @n: another type * to use as temporary storage
|
|
* @head: the head for your list.
|
|
* @member: the name of the list_head within the struct.
|
|
*
|
|
* Iterate over list of given type from current point, safe against
|
|
* removal of list entry.
|
|
*/
|
|
#define list_private_for_each_entry_safe_from(pos, n, head, member) \
|
|
for (n = list_private_next_entry(pos, member); \
|
|
!list_private_entry_is_head(pos, head, member); \
|
|
pos = n, n = list_private_next_entry(n, member))
|
|
|
|
/**
|
|
* list_private_for_each_entry_safe_reverse - iterate backwards over list safe against removal
|
|
* @pos: the type * to use as a loop cursor.
|
|
* @n: another type * to use as temporary storage
|
|
* @head: the head for your list.
|
|
* @member: the name of the list_head within the struct.
|
|
*
|
|
* Iterate backwards over list of given type, safe against removal
|
|
* of list entry.
|
|
*/
|
|
#define list_private_for_each_entry_safe_reverse(pos, n, head, member) \
|
|
for (pos = list_private_last_entry(head, typeof(*pos), member), \
|
|
n = list_private_prev_entry(pos, member); \
|
|
!list_private_entry_is_head(pos, head, member); \
|
|
pos = n, n = list_private_prev_entry(n, member))
|
|
|
|
/**
|
|
* list_private_safe_reset_next - reset a stale list_for_each_entry_safe loop
|
|
* @pos: the loop cursor used in the list_for_each_entry_safe loop
|
|
* @n: temporary storage used in list_for_each_entry_safe
|
|
* @member: the name of the list_head within the struct.
|
|
*
|
|
* list_safe_reset_next is not safe to use in general if the list may be
|
|
* modified concurrently (eg. the lock is dropped in the loop body). An
|
|
* exception to this is if the cursor element (pos) is pinned in the list,
|
|
* and list_safe_reset_next is called after re-taking the lock and before
|
|
* completing the current iteration of the loop body.
|
|
*/
|
|
#define list_private_safe_reset_next(pos, n, member) \
|
|
n = list_private_next_entry(pos, member)
|
|
|
|
#endif /* _LINUX_LIST_PRIVATE_H */
|