~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/core-api/folio_queue.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 .. SPDX-License-Identifier: GPL-2.0+
  2 
  3 ===========
  4 Folio Queue
  5 ===========
  6 
  7 :Author: David Howells <dhowells@redhat.com>
  8 
  9 .. Contents:
 10 
 11  * Overview
 12  * Initialisation
 13  * Adding and removing folios
 14  * Querying information about a folio
 15  * Querying information about a folio_queue
 16  * Folio queue iteration
 17  * Folio marks
 18  * Lockless simultaneous production/consumption issues
 19 
 20 
 21 Overview
 22 ========
 23 
 24 The folio_queue struct forms a single segment in a segmented list of folios
 25 that can be used to form an I/O buffer.  As such, the list can be iterated over
 26 using the ITER_FOLIOQ iov_iter type.
 27 
 28 The publicly accessible members of the structure are::
 29 
 30         struct folio_queue {
 31                 struct folio_queue *next;
 32                 struct folio_queue *prev;
 33                 ...
 34         };
 35 
 36 A pair of pointers are provided, ``next`` and ``prev``, that point to the
 37 segments on either side of the segment being accessed.  Whilst this is a
 38 doubly-linked list, it is intentionally not a circular list; the outward
 39 sibling pointers in terminal segments should be NULL.
 40 
 41 Each segment in the list also stores:
 42 
 43  * an ordered sequence of folio pointers,
 44  * the size of each folio and
 45  * three 1-bit marks per folio,
 46 
 47 but hese should not be accessed directly as the underlying data structure may
 48 change, but rather the access functions outlined below should be used.
 49 
 50 The facility can be made accessible by::
 51 
 52         #include <linux/folio_queue.h>
 53 
 54 and to use the iterator::
 55 
 56         #include <linux/uio.h>
 57 
 58 
 59 Initialisation
 60 ==============
 61 
 62 A segment should be initialised by calling::
 63 
 64         void folioq_init(struct folio_queue *folioq);
 65 
 66 with a pointer to the segment to be initialised.  Note that this will not
 67 necessarily initialise all the folio pointers, so care must be taken to check
 68 the number of folios added.
 69 
 70 
 71 Adding and removing folios
 72 ==========================
 73 
 74 Folios can be set in the next unused slot in a segment struct by calling one
 75 of::
 76 
 77         unsigned int folioq_append(struct folio_queue *folioq,
 78                                    struct folio *folio);
 79 
 80         unsigned int folioq_append_mark(struct folio_queue *folioq,
 81                                         struct folio *folio);
 82 
 83 Both functions update the stored folio count, store the folio and note its
 84 size.  The second function also sets the first mark for the folio added.  Both
 85 functions return the number of the slot used.  [!] Note that no attempt is made
 86 to check that the capacity wasn't overrun and the list will not be extended
 87 automatically.
 88 
 89 A folio can be excised by calling::
 90 
 91         void folioq_clear(struct folio_queue *folioq, unsigned int slot);
 92 
 93 This clears the slot in the array and also clears all the marks for that folio,
 94 but doesn't change the folio count - so future accesses of that slot must check
 95 if the slot is occupied.
 96 
 97 
 98 Querying information about a folio
 99 ==================================
100 
101 Information about the folio in a particular slot may be queried by the
102 following function::
103 
104         struct folio *folioq_folio(const struct folio_queue *folioq,
105                                    unsigned int slot);
106 
107 If a folio has not yet been set in that slot, this may yield an undefined
108 pointer.  The size of the folio in a slot may be queried with either of::
109 
110         unsigned int folioq_folio_order(const struct folio_queue *folioq,
111                                         unsigned int slot);
112 
113         size_t folioq_folio_size(const struct folio_queue *folioq,
114                                  unsigned int slot);
115 
116 The first function returns the size as an order and the second as a number of
117 bytes.
118 
119 
120 Querying information about a folio_queue
121 ========================================
122 
123 Information may be retrieved about a particular segment with the following
124 functions::
125 
126         unsigned int folioq_nr_slots(const struct folio_queue *folioq);
127 
128         unsigned int folioq_count(struct folio_queue *folioq);
129 
130         bool folioq_full(struct folio_queue *folioq);
131 
132 The first function returns the maximum capacity of a segment.  It must not be
133 assumed that this won't vary between segments.  The second returns the number
134 of folios added to a segments and the third is a shorthand to indicate if the
135 segment has been filled to capacity.
136 
137 Not that the count and fullness are not affected by clearing folios from the
138 segment.  These are more about indicating how many slots in the array have been
139 initialised, and it assumed that slots won't get reused, but rather the segment
140 will get discarded as the queue is consumed.
141 
142 
143 Folio marks
144 ===========
145 
146 Folios within a queue can also have marks assigned to them.  These marks can be
147 used to note information such as if a folio needs folio_put() calling upon it.
148 There are three marks available to be set for each folio.
149 
150 The marks can be set by::
151 
152         void folioq_mark(struct folio_queue *folioq, unsigned int slot);
153         void folioq_mark2(struct folio_queue *folioq, unsigned int slot);
154         void folioq_mark3(struct folio_queue *folioq, unsigned int slot);
155 
156 Cleared by::
157 
158         void folioq_unmark(struct folio_queue *folioq, unsigned int slot);
159         void folioq_unmark2(struct folio_queue *folioq, unsigned int slot);
160         void folioq_unmark3(struct folio_queue *folioq, unsigned int slot);
161 
162 And the marks can be queried by::
163 
164         bool folioq_is_marked(const struct folio_queue *folioq, unsigned int slot);
165         bool folioq_is_marked2(const struct folio_queue *folioq, unsigned int slot);
166         bool folioq_is_marked3(const struct folio_queue *folioq, unsigned int slot);
167 
168 The marks can be used for any purpose and are not interpreted by this API.
169 
170 
171 Folio queue iteration
172 =====================
173 
174 A list of segments may be iterated over using the I/O iterator facility using
175 an ``iov_iter`` iterator of ``ITER_FOLIOQ`` type.  The iterator may be
176 initialised with::
177 
178         void iov_iter_folio_queue(struct iov_iter *i, unsigned int direction,
179                                   const struct folio_queue *folioq,
180                                   unsigned int first_slot, unsigned int offset,
181                                   size_t count);
182 
183 This may be told to start at a particular segment, slot and offset within a
184 queue.  The iov iterator functions will follow the next pointers when advancing
185 and prev pointers when reverting when needed.
186 
187 
188 Lockless simultaneous production/consumption issues
189 ===================================================
190 
191 If properly managed, the list can be extended by the producer at the head end
192 and shortened by the consumer at the tail end simultaneously without the need
193 to take locks.  The ITER_FOLIOQ iterator inserts appropriate barriers to aid
194 with this.
195 
196 Care must be taken when simultaneously producing and consuming a list.  If the
197 last segment is reached and the folios it refers to are entirely consumed by
198 the IOV iterators, an iov_iter struct will be left pointing to the last segment
199 with a slot number equal to the capacity of that segment.  The iterator will
200 try to continue on from this if there's another segment available when it is
201 used again, but care must be taken lest the segment got removed and freed by
202 the consumer before the iterator was advanced.
203 
204 It is recommended that the queue always contain at least one segment, even if
205 that segment has never been filled or is entirely spent.  This prevents the
206 head and tail pointers from collapsing.
207 
208 
209 API Function Reference
210 ======================
211 
212 .. kernel-doc:: include/linux/folio_queue.h

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php