0eec091280f6367907abd7860b920e8988db57a7
[dragonfly.git] / share / man / man9 / sglist.9
1 .\"
2 .\" Copyright (c) 2009 Advanced Computing Technologies LLC
3 .\" Written by: John H. Baldwin <jhb@FreeBSD.org>
4 .\" All rights reserved.
5 .\"
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
8 .\" are met:
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\"    notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\"    notice, this list of conditions and the following disclaimer in the
13 .\"    documentation and/or other materials provided with the distribution.
14 .\"
15 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 .\" SUCH DAMAGE.
26 .\"
27 .\" $FreeBSD: src/share/man/man9/sglist.9,v 1.4 2010/07/31 10:01:15 joel Exp $
28 .\"
29 .Dd December 8, 2012
30 .Dt SGLIST 9
31 .Os
32 .Sh NAME
33 .Nm sglist ,
34 .Nm sglist_alloc ,
35 .Nm sglist_append ,
36 .Nm sglist_append_mbuf ,
37 .Nm sglist_append_phys ,
38 .Nm sglist_append_uio ,
39 .Nm sglist_append_user ,
40 .Nm sglist_build ,
41 .Nm sglist_clone ,
42 .Nm sglist_consume_uio ,
43 .Nm sglist_count ,
44 .Nm sglist_free ,
45 .Nm sglist_hold ,
46 .Nm sglist_init ,
47 .Nm sglist_join ,
48 .Nm sglist_length ,
49 .Nm sglist_reset ,
50 .Nm sglist_slice ,
51 .Nm sglist_split
52 .Nd manage a scatter/gather list of physical memory addresses
53 .Sh SYNOPSIS
54 .In sys/types.h
55 .In sys/sglist.h
56 .Ft struct sglist *
57 .Fn sglist_alloc "int nsegs" "int mflags"
58 .Ft int
59 .Fn sglist_append "struct sglist *sg" "void *buf" "size_t len"
60 .Ft int
61 .Fn sglist_append_mbuf "struct sglist *sg" "struct mbuf *m"
62 .Ft int
63 .Fn sglist_append_phys "struct sglist *sg" "vm_paddr_t paddr" "size_t len"
64 .Ft int
65 .Fn sglist_append_uio "struct sglist *sg" "struct uio *uio"
66 .Ft int
67 .Fn sglist_append_user "struct sglist *sg" "void *buf" "size_t len" "struct thread *td"
68 .Ft struct sglist *
69 .Fn sglist_build "void *buf" "size_t len" "int mflags"
70 .Ft struct sglist *
71 .Fn sglist_clone "struct sglist *sg" "int mflags"
72 .Ft int
73 .Fn sglist_consume_uio "struct sglist *sg" "struct uio *uio" "size_t resid"
74 .Ft int
75 .Fn sglist_count "void *buf" "size_t len"
76 .Ft void
77 .Fn sglist_free "struct sglist *sg"
78 .Ft struct sglist *
79 .Fn sglist_hold "struct sglist *sg"
80 .Ft void
81 .Fn sglist_init "struct sglist *sg" "int maxsegs" "struct sglist_seg *segs"
82 .Ft int
83 .Fn sglist_join "struct sglist *first" "struct sglist *second"
84 .Ft size_t
85 .Fn sglist_length "struct sglist *sg"
86 .Ft void
87 .Fn sglist_reset "struct sglist *sg"
88 .Ft int
89 .Fn sglist_slice "struct sglist *original" "struct sglist **slice" "size_t offset" "size_t length" "int mflags"
90 .Ft int
91 .Fn sglist_split "struct sglist *original" "struct sglist **head" "size_t length" "int mflags"
92 .Sh DESCRIPTION
93 The
94 .Nm
95 API manages physical address ranges.
96 Each list contains one or more elements.
97 Each element contains a starting physical address and a length.
98 Scatter/gather lists are read-only while they are shared.
99 If one wishes to alter an existing scatter/gather list and does not hold the
100 sole reference to the list,
101 then one should create a new list instead of modifying the existing list.
102 .Pp
103 Each scatter/gather list object contains a reference count.
104 New lists are created with a single reference.
105 New references are obtained by calling
106 .Nm sglist_hold
107 and are released by calling
108 .Nm sglist_free .
109 .Ss Allocating and Initializing Lists
110 Each
111 .Nm
112 object consists of a header structure and a variable-length array of
113 scatter/gather list elements.
114 The
115 .Nm sglist_alloc
116 function allocates a new list that contains a header and
117 .Fa nsegs
118 scatter/gather list elements.
119 The
120 .Fa mflags
121 argument can be set to either
122 .Dv M_NOWAIT
123 or
124 .Dv M_WAITOK .
125 .Pp
126 The
127 .Nm sglist_count
128 function returns the number of scatter/gather list elements needed to describe
129 the physical address ranges mapped by a single kernel virtual address range.
130 The kernel virtual address range starts at
131 .Fa buf
132 and is
133 .Fa len
134 bytes long.
135 .Pp
136 The
137 .Nm sglist_build
138 function allocates a new scatter/gather list object that describes the physical
139 address ranges mapped by a single kernel virtual address range.
140 The kernel virtual address range starts at
141 .Fa buf
142 and is
143 .Fa len
144 bytes long.
145 The
146 .Fa mflags
147 argument can be set to either
148 .Dv M_NOWAIT
149 or
150 .Dv M_WAITOK .
151 .Pp
152 The
153 .Nm sglist_clone
154 function returns a copy of an existing scatter/gather list object
155 .Fa sg .
156 The
157 .Fa mflags
158 argument can be set to either
159 .Dv M_NOWAIT
160 or
161 .Dv M_WAITOK .
162 This can be used to obtain a private copy of a scatter/gather list before
163 modifying it.
164 .Pp
165 The
166 .Nm sglist_init
167 function initializes a scatter/gather list header.
168 The header is pointed to by
169 .Fa sg
170 and is initialized to manage an array of
171 .Fa maxsegs
172 scatter/gather list elements pointed to by
173 .Fa segs .
174 This can be used to initialize a scatter/gather list header whose storage
175 is not provided by
176 .Nm sglist_alloc .
177 In that case, the caller should not call
178 .Nm sglist_free
179 to release its own reference and is responsible for ensuring all other
180 references to the list are dropped before it releases the storage for
181 .Fa sg
182 and
183 .Fa segs .
184 .Ss Constructing Scatter/Gather Lists
185 The
186 .Nm
187 API provides several routines for building a scatter/gather list to describe
188 one or more objects.
189 Specifically, the
190 .Nm sglist_append
191 family of routines can be used to append the physical address ranges described
192 by an object to the end of a scatter/gather list.
193 All of these routines return 0 on success or an error on failure.
194 If a request to append an address range to a scatter/gather list fails,
195 the scatter/gather list will remain unchanged.
196 .Pp
197 The
198 .Nm sglist_append
199 function appends the physical address ranges described by a single kernel
200 virtual address range to the scatter/gather list
201 .Fa sg .
202 The kernel virtual address range starts at
203 .Fa buf
204 and is
205 .Fa len
206 bytes long.
207 .Pp
208 The
209 .Nm sglist_append_mbuf
210 function appends the physical address ranges described by an entire mbuf
211 chain
212 .Fa m
213 to the scatter/gather list
214 .Fa sg .
215 .Pp
216 The
217 .Nm sglist_append_phys
218 function appends a single physical address range to the scatter/gather list
219 .Fa sg .
220 The physical address range starts at
221 .Fa paddr
222 and is
223 .Fa len
224 bytes long.
225 .Pp
226 The
227 .Nm sglist_append_uio
228 function appends the physical address ranges described by a
229 .Xr uio 9
230 object to the scatter/gather list
231 .Fa sg .
232 Note that it is the caller's responsibility to ensure that the pages backing
233 the I/O request are wired for the lifetime of
234 .Fa sg .
235 Note also that this routine does not modify
236 .Fa uio .
237 .Pp
238 The
239 .Nm sglist_append_user
240 function appends the physical address ranges described by a single user
241 virtual address range to the scatter/gather list
242 .Fa sg .
243 The user virtual address range is relative to the address space of the thread
244 .Fa td .
245 It starts at
246 .Fa buf
247 and is
248 .Fa len
249 bytes long.
250 Note that it is the caller's responsibility to ensure that the pages backing
251 the user buffer are wired for the lifetime of
252 .Fa sg .
253 .Pp
254 The
255 .Nm sglist_consume_uio
256 function is a variation of
257 .Nm sglist_append_uio .
258 As with
259 .Nm sglist_append_uio ,
260 it appends the physical address ranges described by
261 .Fa uio
262 to the scatter/gather list
263 .Fa sg .
264 Unlike
265 .Nm sglist_append_uio ,
266 however,
267 .Nm sglist_consume_uio
268 modifies the I/O request to indicate that the appended address ranges have
269 been processed similar to calling
270 .Xr uiomove 9 .
271 This routine will only append ranges that describe up to
272 .Fa resid
273 total bytes in length.
274 If the available segments in the scatter/gather list are exhausted before
275 .Fa resid
276 bytes are processed,
277 then the
278 .Fa uio
279 structure will be updated to reflect the actual number of bytes processed,
280 and
281 .Nm sglist_consume_io
282 will return zero to indicate success.
283 In effect, this function will perform partial reads or writes.
284 The caller can compare the
285 .Fa uio_resid
286 member of
287 .Fa uio
288 before and after calling
289 .Nm sglist_consume_uio
290 to determine the actual number of bytes processed.
291 .Ss Manipulating Scatter/Gather Lists
292 The
293 .Nm sglist_join
294 function appends physical address ranges from the scatter/gather list
295 .Fa second
296 onto
297 .Fa first
298 and then resets
299 .Fa second
300 to an empty list.
301 It returns zero on success or an error on failure.
302 .Pp
303 The
304 .Nm sglist_split
305 function splits an existing scatter/gather list into two lists.
306 The first
307 .Fa length
308 bytes described by the list
309 .Fa original
310 are moved to a new list
311 .Fa *head .
312 If
313 .Fa original
314 describes a total address range that is smaller than
315 .Fa length
316 bytes,
317 then all of the address ranges will be moved to the new list at
318 .Fa *head
319 and
320 .Fa original
321 will be an empty list.
322 The caller may supply an existing scatter/gather list in
323 .Fa *head .
324 If so, the list must be empty.
325 Otherwise, the caller may set
326 .Fa *head
327 to
328 .Dv NULL
329 in which case a new scatter/gather list will be allocated.
330 In that case,
331 .Fa mflags
332 may be set to either
333 .Dv M_NOWAIT
334 or
335 .Dv M_WAITOK .
336 Note that since the
337 .Fa original
338 list is modified by this call, it must be a private list with no other
339 references.
340 The
341 .Nm sglist_split
342 function returns zero on success or an error on failure.
343 .Pp
344 The
345 .Nm sglist_slice
346 function generates a new scatter/gather list from a sub-range of an existing
347 scatter/gather list
348 .Fa original .
349 The sub-range to extract is specified by the
350 .Fa offset
351 and
352 .Fa length
353 parameters.
354 The new scatter/gather list is stored in
355 .Fa *slice .
356 As with
357 .Fa head
358 for
359 .Nm sglist_join ,
360 the caller may either provide an empty scatter/gather list,
361 or it may set
362 .Fa *slice
363 to
364 .Dv NULL
365 in which case
366 .Nm sglist_slice
367 will allocate a new list subject to
368 .Fa mflags .
369 Unlike
370 .Nm sglist_split ,
371 .Nm sglist_slice
372 does not modify
373 .Fa original
374 and does not require it to be a private list.
375 The
376 .Nm sglist_split
377 function returns zero on success or an error on failure.
378 .Ss Miscellaneous Routines
379 The
380 .Nm sglist_reset
381 function clears the scatter/gather list
382 .Fa sg
383 so that it no longer maps any address ranges.
384 This can allow reuse of a single scatter/gather list object for multiple
385 requests.
386 .Pp
387 The
388 .Nm sglist_length
389 function returns the total length of the physical address ranges described
390 by the scatter/gather list
391 .Fa sg .
392 .Sh RETURN VALUES
393 The
394 .Nm sglist_alloc ,
395 .Nm sglist_build ,
396 and
397 .Nm sglist_clone
398 functions return a new scatter/gather list on success or
399 .Dv NULL
400 on failure.
401 .Pp
402 The
403 .Nm sglist_append
404 family of functions and the
405 .Nm sglist_consume_uio ,
406 .Nm sglist_join ,
407 .Nm sglist_slice ,
408 and
409 .Nm sglist_split
410 functions return zero on success or an error on failure.
411 .Pp
412 The
413 .Nm sglist_count
414 function returns a count of scatter/gather list elements.
415 .Pp
416 The
417 .Nm sglist_length
418 function returns a count of address space described by a scatter/gather list
419 in bytes.
420 .Sh ERRORS
421 The
422 .Nm sglist_append
423 functions return the following errors on failure:
424 .Bl -tag -width Er
425 .It Bq Er EINVAL
426 The scatter/gather list has zero segments.
427 .It Bq Er EFBIG
428 There are not enough available segments in the scatter/gather list to append
429 the specified physical address ranges.
430 .El
431 .Pp
432 The
433 .Nm sglist_consume_uio
434 function returns the following error on failure:
435 .Bl -tag -width Er
436 .It Bq Er EINVAL
437 The scatter/gather list has zero segments.
438 .El
439 .Pp
440 The
441 .Nm sglist_join
442 function returns the following error on failure:
443 .Bl -tag -width Er
444 .It Bq Er EFBIG
445 There are not enough available segments in the scatter/gather list
446 .Fa first
447 to append the physical address ranges from
448 .Fa second .
449 .El
450 .Pp
451 The
452 .Nm sglist_slice
453 function returns the following errors on failure:
454 .Bl -tag -width Er
455 .It Bq Er EINVAL
456 The
457 .Fa original
458 scatter/gather list does not describe enough address space to cover the
459 requested sub-range.
460 .It Bq Er EINVAL
461 The caller-supplied scatter/gather list in
462 .Fa *slice
463 is not empty.
464 .It Bq Er ENOMEM
465 An attempt to allocate a new scatter/gather list with
466 .Dv M_NOWAIT
467 set in
468 .Fa mflags
469 failed.
470 .It Bq Er EFBIG
471 There are not enough available segments in the caller-supplied scatter/gather
472 list in
473 .Fa *slice
474 to describe the requested physical address ranges.
475 .El
476 .Pp
477 The
478 .Nm sglist_split
479 function returns the following errors on failure:
480 .Bl -tag -width Er
481 .It Bq Er EDOOFUS
482 The
483 .Fa original
484 scatter/gather list has more than one reference.
485 .It Bq Er EINVAL
486 The caller-supplied scatter/gather list in
487 .Fa *head
488 is not empty.
489 .It Bq Er ENOMEM
490 An attempt to allocate a new scatter/gather list with
491 .Dv M_NOWAIT
492 set in
493 .Fa mflags
494 failed.
495 .It Bq Er EFBIG
496 There are not enough available segments in the caller-supplied scatter/gather
497 list in
498 .Fa *head
499 to describe the requested physical address ranges.
500 .El
501 .Sh SEE ALSO
502 .Xr kmalloc 9 ,
503 .Xr mbuf 9 ,
504 .Xr uio 9
505 .Sh HISTORY
506 This API was first introduced in
507 .Fx 8.0 .