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