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