aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wilcox <mawilcox@microsoft.com>2018-02-06 15:05:49 -0500
committerMatthew Wilcox <mawilcox@microsoft.com>2018-02-06 16:41:29 -0500
commitac665d9423474e64e64b34b0e2cea43601b50d7d (patch)
tree7e74505b3e71b90f303d52b3bf66bc65d609e48c
parent6ce711f2750031d12cec91384ac5cfa0a485b60a (diff)
idr: Add documentation
Move the idr kernel-doc to its own idr.rst file and add a few paragraphs about how to use it. Also add some more kernel-doc. Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
-rw-r--r--Documentation/core-api/idr.rst79
-rw-r--r--Documentation/core-api/index.rst1
-rw-r--r--Documentation/core-api/kernel-api.rst12
-rw-r--r--include/linux/idr.h16
4 files changed, 95 insertions, 13 deletions
diff --git a/Documentation/core-api/idr.rst b/Documentation/core-api/idr.rst
new file mode 100644
index 000000000000..9078a5c3ac95
--- /dev/null
+++ b/Documentation/core-api/idr.rst
@@ -0,0 +1,79 @@
1.. SPDX-License-Identifier: CC-BY-SA-4.0
2
3=============
4ID Allocation
5=============
6
7:Author: Matthew Wilcox
8
9Overview
10========
11
12A common problem to solve is allocating identifiers (IDs); generally
13small numbers which identify a thing. Examples include file descriptors,
14process IDs, packet identifiers in networking protocols, SCSI tags
15and device instance numbers. The IDR and the IDA provide a reasonable
16solution to the problem to avoid everybody inventing their own. The IDR
17provides the ability to map an ID to a pointer, while the IDA provides
18only ID allocation, and as a result is much more memory-efficient.
19
20IDR usage
21=========
22
23Start by initialising an IDR, either with :c:func:`DEFINE_IDR`
24for statically allocated IDRs or :c:func:`idr_init` for dynamically
25allocated IDRs.
26
27You can call :c:func:`idr_alloc` to allocate an unused ID. Look up
28the pointer you associated with the ID by calling :c:func:`idr_find`
29and free the ID by calling :c:func:`idr_remove`.
30
31If you need to change the pointer associated with an ID, you can call
32:c:func:`idr_replace`. One common reason to do this is to reserve an
33ID by passing a ``NULL`` pointer to the allocation function; initialise the
34object with the reserved ID and finally insert the initialised object
35into the IDR.
36
37Some users need to allocate IDs larger than ``INT_MAX``. So far all of
38these users have been content with a ``UINT_MAX`` limit, and they use
39:c:func:`idr_alloc_u32`. If you need IDs that will not fit in a u32,
40we will work with you to address your needs.
41
42If you need to allocate IDs sequentially, you can use
43:c:func:`idr_alloc_cyclic`. The IDR becomes less efficient when dealing
44with larger IDs, so using this function comes at a slight cost.
45
46To perform an action on all pointers used by the IDR, you can
47either use the callback-based :c:func:`idr_for_each` or the
48iterator-style :c:func:`idr_for_each_entry`. You may need to use
49:c:func:`idr_for_each_entry_continue` to continue an iteration. You can
50also use :c:func:`idr_get_next` if the iterator doesn't fit your needs.
51
52When you have finished using an IDR, you can call :c:func:`idr_destroy`
53to release the memory used by the IDR. This will not free the objects
54pointed to from the IDR; if you want to do that, use one of the iterators
55to do it.
56
57You can use :c:func:`idr_is_empty` to find out whether there are any
58IDs currently allocated.
59
60If you need to take a lock while allocating a new ID from the IDR,
61you may need to pass a restrictive set of GFP flags, which can lead
62to the IDR being unable to allocate memory. To work around this,
63you can call :c:func:`idr_preload` before taking the lock, and then
64:c:func:`idr_preload_end` after the allocation.
65
66.. kernel-doc:: include/linux/idr.h
67 :doc: idr sync
68
69IDA usage
70=========
71
72.. kernel-doc:: lib/idr.c
73 :doc: IDA description
74
75Functions and structures
76========================
77
78.. kernel-doc:: include/linux/idr.h
79.. kernel-doc:: lib/idr.c
diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst
index 1b1fd01990b5..c670a8031786 100644
--- a/Documentation/core-api/index.rst
+++ b/Documentation/core-api/index.rst
@@ -16,6 +16,7 @@ Core utilities
16 atomic_ops 16 atomic_ops
17 refcount-vs-atomic 17 refcount-vs-atomic
18 cpu_hotplug 18 cpu_hotplug
19 idr
19 local_ops 20 local_ops
20 workqueue 21 workqueue
21 genericirq 22 genericirq
diff --git a/Documentation/core-api/kernel-api.rst b/Documentation/core-api/kernel-api.rst
index e7fadf02c511..ff335f8aeb39 100644
--- a/Documentation/core-api/kernel-api.rst
+++ b/Documentation/core-api/kernel-api.rst
@@ -103,18 +103,6 @@ CRC Functions
103.. kernel-doc:: lib/crc-itu-t.c 103.. kernel-doc:: lib/crc-itu-t.c
104 :export: 104 :export:
105 105
106idr/ida Functions
107-----------------
108
109.. kernel-doc:: include/linux/idr.h
110 :doc: idr sync
111
112.. kernel-doc:: lib/idr.c
113 :doc: IDA description
114
115.. kernel-doc:: lib/idr.c
116 :export:
117
118Math Functions in Linux 106Math Functions in Linux
119======================= 107=======================
120 108
diff --git a/include/linux/idr.h b/include/linux/idr.h
index 86b38df6e121..7d6a6313f0ab 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -36,7 +36,6 @@ struct idr {
36 .idr_base = (base), \ 36 .idr_base = (base), \
37 .idr_next = 0, \ 37 .idr_next = 0, \
38} 38}
39#define DEFINE_IDR(name) struct idr name = IDR_INIT
40 39
41/** 40/**
42 * IDR_INIT() - Initialise an IDR. 41 * IDR_INIT() - Initialise an IDR.
@@ -46,6 +45,15 @@ struct idr {
46#define IDR_INIT IDR_INIT_BASE(0) 45#define IDR_INIT IDR_INIT_BASE(0)
47 46
48/** 47/**
48 * DEFINE_IDR() - Define a statically-allocated IDR
49 * @name: Name of IDR
50 *
51 * An IDR defined using this macro is ready for use with no additional
52 * initialisation required. It contains no IDs.
53 */
54#define DEFINE_IDR(name) struct idr name = IDR_INIT
55
56/**
49 * idr_get_cursor - Return the current position of the cyclic allocator 57 * idr_get_cursor - Return the current position of the cyclic allocator
50 * @idr: idr handle 58 * @idr: idr handle
51 * 59 *
@@ -130,6 +138,12 @@ static inline void idr_init(struct idr *idr)
130 idr_init_base(idr, 0); 138 idr_init_base(idr, 0);
131} 139}
132 140
141/**
142 * idr_is_empty() - Are there any IDs allocated?
143 * @idr: IDR handle.
144 *
145 * Return: %true if any IDs have been allocated from this IDR.
146 */
133static inline bool idr_is_empty(const struct idr *idr) 147static inline bool idr_is_empty(const struct idr *idr)
134{ 148{
135 return radix_tree_empty(&idr->idr_rt) && 149 return radix_tree_empty(&idr->idr_rt) &&