123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- /* SPDX-License-Identifier: GPL-2.0+ */
- #ifndef _LINUX_XARRAY_H
- #define _LINUX_XARRAY_H
- /*
- * eXtensible Arrays
- * Copyright (c) 2017 Microsoft Corporation
- * Author: Matthew Wilcox <willy@infradead.org>
- *
- * See Documentation/core-api/xarray.rst for how to use the XArray.
- */
- #include <linux/bug.h>
- #include <linux/spinlock.h>
- #include <linux/types.h>
- /*
- * The bottom two bits of the entry determine how the XArray interprets
- * the contents:
- *
- * 00: Pointer entry
- * 10: Internal entry
- * x1: Value entry or tagged pointer
- *
- * Attempting to store internal entries in the XArray is a bug.
- */
- #define BITS_PER_XA_VALUE (BITS_PER_LONG - 1)
- /**
- * xa_mk_value() - Create an XArray entry from an integer.
- * @v: Value to store in XArray.
- *
- * Context: Any context.
- * Return: An entry suitable for storing in the XArray.
- */
- static inline void *xa_mk_value(unsigned long v)
- {
- WARN_ON((long)v < 0);
- return (void *)((v << 1) | 1);
- }
- /**
- * xa_to_value() - Get value stored in an XArray entry.
- * @entry: XArray entry.
- *
- * Context: Any context.
- * Return: The value stored in the XArray entry.
- */
- static inline unsigned long xa_to_value(const void *entry)
- {
- return (unsigned long)entry >> 1;
- }
- /**
- * xa_is_value() - Determine if an entry is a value.
- * @entry: XArray entry.
- *
- * Context: Any context.
- * Return: True if the entry is a value, false if it is a pointer.
- */
- static inline bool xa_is_value(const void *entry)
- {
- return (unsigned long)entry & 1;
- }
- /**
- * xa_tag_pointer() - Create an XArray entry for a tagged pointer.
- * @p: Plain pointer.
- * @tag: Tag value (0, 1 or 3).
- *
- * If the user of the XArray prefers, they can tag their pointers instead
- * of storing value entries. Three tags are available (0, 1 and 3).
- * These are distinct from the xa_mark_t as they are not replicated up
- * through the array and cannot be searched for.
- *
- * Context: Any context.
- * Return: An XArray entry.
- */
- static inline void *xa_tag_pointer(void *p, unsigned long tag)
- {
- return (void *)((unsigned long)p | tag);
- }
- /**
- * xa_untag_pointer() - Turn an XArray entry into a plain pointer.
- * @entry: XArray entry.
- *
- * If you have stored a tagged pointer in the XArray, call this function
- * to get the untagged version of the pointer.
- *
- * Context: Any context.
- * Return: A pointer.
- */
- static inline void *xa_untag_pointer(void *entry)
- {
- return (void *)((unsigned long)entry & ~3UL);
- }
- /**
- * xa_pointer_tag() - Get the tag stored in an XArray entry.
- * @entry: XArray entry.
- *
- * If you have stored a tagged pointer in the XArray, call this function
- * to get the tag of that pointer.
- *
- * Context: Any context.
- * Return: A tag.
- */
- static inline unsigned int xa_pointer_tag(void *entry)
- {
- return (unsigned long)entry & 3UL;
- }
- #define xa_trylock(xa) spin_trylock(&(xa)->xa_lock)
- #define xa_lock(xa) spin_lock(&(xa)->xa_lock)
- #define xa_unlock(xa) spin_unlock(&(xa)->xa_lock)
- #define xa_lock_bh(xa) spin_lock_bh(&(xa)->xa_lock)
- #define xa_unlock_bh(xa) spin_unlock_bh(&(xa)->xa_lock)
- #define xa_lock_irq(xa) spin_lock_irq(&(xa)->xa_lock)
- #define xa_unlock_irq(xa) spin_unlock_irq(&(xa)->xa_lock)
- #define xa_lock_irqsave(xa, flags) \
- spin_lock_irqsave(&(xa)->xa_lock, flags)
- #define xa_unlock_irqrestore(xa, flags) \
- spin_unlock_irqrestore(&(xa)->xa_lock, flags)
- #endif /* _LINUX_XARRAY_H */
|