2 .\" Copyright (c) 2009 Hudson River Trading LLC
3 .\" Written by: John H. Baldwin <jhb@FreeBSD.org>
4 .\" All rights reserved.
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
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.
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
36 .Nm sglist_append_bio ,
37 .Nm sglist_append_ext_pgs,
38 .Nm sglist_append_mb_ext_pgs,
39 .Nm sglist_append_mbuf ,
40 .Nm sglist_append_phys ,
41 .Nm sglist_append_sglist ,
42 .Nm sglist_append_uio ,
43 .Nm sglist_append_user ,
44 .Nm sglist_append_vmpages ,
47 .Nm sglist_consume_uio ,
49 .Nm sglist_count_ext_pgs ,
50 .Nm sglist_count_mb_ext_pgs ,
51 .Nm sglist_count_vmpages ,
60 .Nd manage a scatter/gather list of physical memory addresses
65 .Fn sglist_alloc "int nsegs" "int mflags"
67 .Fn sglist_append "struct sglist *sg" "void *buf" "size_t len"
69 .Fn sglist_append_bio "struct sglist *sg" "struct bio *bp"
71 .Fn sglist_append_ext_pgs "struct sglist *sg" "struct mbuf_ext_pgs *ext_pgs" "size_t offset" "size_t len"
73 .Fn sglist_append_mb_ext_pgs "struct sglist *sg" "struct mbuf *m"
75 .Fn sglist_append_mbuf "struct sglist *sg" "struct mbuf *m"
77 .Fn sglist_append_phys "struct sglist *sg" "vm_paddr_t paddr" "size_t len"
79 .Fn sglist_append_sglist "struct sglist *sg" "struct sglist *source" "size_t offset" "size_t len"
81 .Fn sglist_append_uio "struct sglist *sg" "struct uio *uio"
83 .Fn sglist_append_user "struct sglist *sg" "void *buf" "size_t len" "struct thread *td"
85 .Fn sglist_append_vmpages "struct sglist *sg" "vm_page_t *m" "size_t pgoff" "size_t len"
87 .Fn sglist_build "void *buf" "size_t len" "int mflags"
89 .Fn sglist_clone "struct sglist *sg" "int mflags"
91 .Fn sglist_consume_uio "struct sglist *sg" "struct uio *uio" "size_t resid"
93 .Fn sglist_count "void *buf" "size_t len"
95 .Fn sglist_count_ext_pgs "struct mbuf_ext_pgs *ext_pgs" "size_t offset" "size_t len"
97 .Fn sglist_count_mb_ext_pgs "struct mbuf *m"
99 .Fn sglist_count_vmpages "vm_page_t *m" "size_t pgoff" "size_t len"
101 .Fn sglist_free "struct sglist *sg"
103 .Fn sglist_hold "struct sglist *sg"
105 .Fn sglist_init "struct sglist *sg" "int maxsegs" "struct sglist_seg *segs"
107 .Fn sglist_join "struct sglist *first" "struct sglist *second"
109 .Fn sglist_length "struct sglist *sg"
111 .Fn sglist_reset "struct sglist *sg"
113 .Fn sglist_slice "struct sglist *original" "struct sglist **slice" "size_t offset" "size_t length" "int mflags"
115 .Fn sglist_split "struct sglist *original" "struct sglist **head" "size_t length" "int mflags"
119 API manages physical address ranges.
120 Each list contains one or more elements.
121 Each element contains a starting physical address and a length.
122 Scatter/gather lists are read-only while they are shared.
123 If one wishes to alter an existing scatter/gather list and does not hold the
124 sole reference to the list,
125 then one should create a new list instead of modifying the existing list.
127 Each scatter/gather list object contains a reference count.
128 New lists are created with a single reference.
129 New references are obtained by calling
131 and are released by calling
133 .Ss Allocating and Initializing Lists
136 object consists of a header structure and a variable-length array of
137 scatter/gather list elements.
140 function allocates a new list that contains a header and
142 scatter/gather list elements.
145 argument can be set to either
152 function returns the number of scatter/gather list elements needed to describe
153 the physical address ranges mapped by a single kernel virtual address range.
154 The kernel virtual address range starts at
161 .Nm sglist_count_ext_pgs
162 function returns the number of scatter/gather list elements needed to describe
163 the unmapped external mbuf buffer
165 The ranges start at an offset of
167 relative to the start of the buffer and is
171 .Nm sglist_count_mb_ext_pgs
172 function returns the number of scatter/gather list elements needed to describe
173 the physical address ranges of a single unmapped mbuf
177 .Nm sglist_count_vmpages
178 function returns the number of scatter/gather list elements needed to describe
179 the physical address ranges of a buffer backed by an array of virtual memory
182 The buffer starts at an offset of
184 bytes relative to the first page and is
190 function allocates a new scatter/gather list object that describes the physical
191 address ranges mapped by a single kernel virtual address range.
192 The kernel virtual address range starts at
199 argument can be set to either
206 function returns a copy of an existing scatter/gather list object
210 argument can be set to either
214 This can be used to obtain a private copy of a scatter/gather list before
219 function initializes a scatter/gather list header.
220 The header is pointed to by
222 and is initialized to manage an array of
224 scatter/gather list elements pointed to by
226 This can be used to initialize a scatter/gather list header whose storage
229 In that case, the caller should not call
231 to release its own reference and is responsible for ensuring all other
232 references to the list are dropped before it releases the storage for
236 .Ss Constructing Scatter/Gather Lists
239 API provides several routines for building a scatter/gather list to describe
243 family of routines can be used to append the physical address ranges described
244 by an object to the end of a scatter/gather list.
245 All of these routines return 0 on success or an error on failure.
246 If a request to append an address range to a scatter/gather list fails,
247 the scatter/gather list will remain unchanged.
251 function appends the physical address ranges described by a single kernel
252 virtual address range to the scatter/gather list
254 The kernel virtual address range starts at
261 .Nm sglist_append_bio
262 function appends the physical address ranges described by a single bio
264 to the scatter/gather list
268 .Nm sglist_append_ext_pgs
269 function appends the physical address ranges described by the unmapped
272 to the scatter/gather list
274 The physical address ranges start at offset
283 .Nm sglist_append_mb_ext_pgs
284 function appends the physical address ranges described by the unmapped
287 to the scatter/gather list
290 .Nm sglist_append_mbuf ,
291 .Nm sglist_append_mb_ext_pgs
292 only adds ranges for a single mbuf,
293 not an entire mbuf chain.
296 .Nm sglist_append_mbuf
297 function appends the physical address ranges described by an entire mbuf
300 to the scatter/gather list
304 .Nm sglist_append_phys
305 function appends a single physical address range to the scatter/gather list
307 The physical address range starts at
314 .Nm sglist_append_sglist
315 function appends physical address ranges described by the scatter/gather list
317 to the scatter/gather list
319 The physical address ranges start at offset
328 .Nm sglist_append_uio
329 function appends the physical address ranges described by a
331 object to the scatter/gather list
333 Note that it is the caller's responsibility to ensure that the pages backing
334 the I/O request are wired for the lifetime of
336 Note also that this routine does not modify
340 .Nm sglist_append_user
341 function appends the physical address ranges described by a single user
342 virtual address range to the scatter/gather list
344 The user virtual address range is relative to the address space of the thread
351 Note that it is the caller's responsibility to ensure that the pages backing
352 the user buffer are wired for the lifetime of
356 .Nm sglist_append_vmpages
357 function appends the physical address ranges of a buffer backed by an array
358 of virtual memory pages
360 The buffer starts at an offset of
362 bytes relative to the first page and is
367 .Nm sglist_consume_uio
368 function is a variation of
369 .Nm sglist_append_uio .
371 .Nm sglist_append_uio ,
372 it appends the physical address ranges described by
374 to the scatter/gather list
377 .Nm sglist_append_uio ,
379 .Nm sglist_consume_uio
380 modifies the I/O request to indicate that the appended address ranges have
381 been processed similar to calling
383 This routine will only append ranges that describe up to
385 total bytes in length.
386 If the available segments in the scatter/gather list are exhausted before
391 structure will be updated to reflect the actual number of bytes processed,
393 .Nm sglist_consume_io
394 will return zero to indicate success.
395 In effect, this function will perform partial reads or writes.
396 The caller can compare the
400 before and after calling
401 .Nm sglist_consume_uio
402 to determine the actual number of bytes processed.
403 .Ss Manipulating Scatter/Gather Lists
406 function appends physical address ranges from the scatter/gather list
413 It returns zero on success or an error on failure.
417 function splits an existing scatter/gather list into two lists.
420 bytes described by the list
422 are moved to a new list
426 describes a total address range that is smaller than
429 then all of the address ranges will be moved to the new list at
433 will be an empty list.
434 The caller may supply an existing scatter/gather list in
436 If so, the list must be empty.
437 Otherwise, the caller may set
441 in which case a new scatter/gather list will be allocated.
450 list is modified by this call, it must be a private list with no other
454 function returns zero on success or an error on failure.
458 function generates a new scatter/gather list from a sub-range of an existing
461 The sub-range to extract is specified by the
466 The new scatter/gather list is stored in
472 the caller may either provide an empty scatter/gather list,
479 will allocate a new list subject to
486 and does not require it to be a private list.
489 function returns zero on success or an error on failure.
490 .Ss Miscellaneous Routines
493 function clears the scatter/gather list
495 so that it no longer maps any address ranges.
496 This can allow reuse of a single scatter/gather list object for multiple
501 function returns the total length of the physical address ranges described
502 by the scatter/gather list
510 functions return a new scatter/gather list on success or
516 family of functions and the
517 .Nm sglist_consume_uio ,
522 functions return zero on success or an error on failure.
527 functions return a count of scatter/gather list elements.
531 function returns a count of address space described by a scatter/gather list
536 functions return the following errors on failure:
539 The scatter/gather list has zero segments.
541 There are not enough available segments in the scatter/gather list to append
542 the specified physical address ranges.
546 .Nm sglist_consume_uio
547 function returns the following error on failure:
550 The scatter/gather list has zero segments.
555 function returns the following error on failure:
558 There are not enough available segments in the scatter/gather list
560 to append the physical address ranges from
566 function returns the following errors on failure:
571 scatter/gather list does not describe enough address space to cover the
574 The caller-supplied scatter/gather list in
578 An attempt to allocate a new scatter/gather list with
584 There are not enough available segments in the caller-supplied scatter/gather
587 to describe the requested physical address ranges.
592 function returns the following errors on failure:
597 scatter/gather list has more than one reference.
599 The caller-supplied scatter/gather list in
603 An attempt to allocate a new scatter/gather list with
609 There are not enough available segments in the caller-supplied scatter/gather
612 to describe the requested physical address ranges.
620 This API was first introduced in