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