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