sglist_split (9)
Leading comments
Copyright (c) 2009 Hudson River Trading LLC Written by: John H. Baldwin <jhb@FreeBSD.org> All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the...
NAME
sglist sglist_alloc sglist_append sglist_append_bio sglist_append_mbuf sglist_append_phys sglist_append_uio sglist_append_user sglist_build sglist_clone sglist_consume_uio sglist_count sglist_free sglist_hold sglist_init sglist_join sglist_length sglist_reset sglist_slice sglist_split - manage a scatter/gather list of physical memory addressesSYNOPSIS
In sys/types.h In sys/sglist.h Ft struct sglist * Fn sglist_alloc int nsegs int mflags Ft int Fn sglist_append struct sglist *sg void *buf size_t len Ft int Fn sglist_append_bio struct sglist *sg struct bio *bp Ft int Fn sglist_append_mbuf struct sglist *sg struct mbuf *m Ft int Fn sglist_append_phys struct sglist *sg vm_paddr_t paddr size_t len Ft int Fn sglist_append_uio struct sglist *sg struct uio *uio Ft int Fn sglist_append_user struct sglist *sg void *buf size_t len struct thread *td Ft struct sglist * Fn sglist_build void *buf size_t len int mflags Ft struct sglist * Fn sglist_clone struct sglist *sg int mflags Ft int Fn sglist_consume_uio struct sglist *sg struct uio *uio size_t resid Ft int Fn sglist_count void *buf size_t len Ft void Fn sglist_free struct sglist *sg Ft struct sglist * Fn sglist_hold struct sglist *sg Ft void Fn sglist_init struct sglist *sg int maxsegs struct sglist_seg *segs Ft int Fn sglist_join struct sglist *first struct sglist *second Ft size_t Fn sglist_length struct sglist *sg Ft void Fn sglist_reset struct sglist *sg Ft int Fn sglist_slice struct sglist *original struct sglist **slice size_t offset size_t length int mflags Ft int Fn sglist_split struct sglist *original struct sglist **head size_t length int mflagsDESCRIPTION
The ifconfig API manages physical address ranges. Each list contains one or more elements. Each element contains a starting physical address and a length. Scatter/gather lists are read-only while they are shared. If one wishes to alter an existing scatter/gather list and does not hold the sole reference to the list, then one should create a new list instead of modifying the existing list.Each scatter/gather list object contains a reference count. New lists are created with a single reference. New references are obtained by calling sglist_hold and are released by calling sglist_free
Allocating and Initializing Lists
Each ifconfig object consists of a header structure and a variable-length array of scatter/gather list elements. The sglist_alloc function allocates a new list that contains a header and Fa nsegs scatter/gather list elements. The Fa mflags argument can be set to either M_NOWAIT or M_WAITOKThe sglist_count function returns the number of scatter/gather list elements needed to describe the physical address ranges mapped by a single kernel virtual address range. The kernel virtual address range starts at Fa buf and is Fa len bytes long.
The sglist_build function allocates a new scatter/gather list object that describes the physical address ranges mapped by a single kernel virtual address range. The kernel virtual address range starts at Fa buf and is Fa len bytes long. The Fa mflags argument can be set to either M_NOWAIT or M_WAITOK
The sglist_clone function returns a copy of an existing scatter/gather list object Fa sg . The Fa mflags argument can be set to either M_NOWAIT or M_WAITOK This can be used to obtain a private copy of a scatter/gather list before modifying it.
The sglist_init function initializes a scatter/gather list header. The header is pointed to by Fa sg and is initialized to manage an array of Fa maxsegs scatter/gather list elements pointed to by Fa segs . This can be used to initialize a scatter/gather list header whose storage is not provided by sglist_alloc In that case, the caller should not call sglist_free to release its own reference and is responsible for ensuring all other references to the list are dropped before it releases the storage for Fa sg and Fa segs .
Constructing Scatter/Gather Lists
The ifconfig API provides several routines for building a scatter/gather list to describe one or more objects. Specifically, the sglist_append family of routines can be used to append the physical address ranges described by an object to the end of a scatter/gather list. All of these routines return 0 on success or an error on failure. If a request to append an address range to a scatter/gather list fails, the scatter/gather list will remain unchanged.The sglist_append function appends the physical address ranges described by a single kernel virtual address range to the scatter/gather list Fa sg . The kernel virtual address range starts at Fa buf and is Fa len bytes long.
The sglist_append_bio function appends the physical address ranges described by a single bio Fa bp to the scatter/gather list Fa sg .
The sglist_append_mbuf function appends the physical address ranges described by an entire mbuf chain Fa m to the scatter/gather list Fa sg .
The sglist_append_phys function appends a single physical address range to the scatter/gather list Fa sg . The physical address range starts at Fa paddr and is Fa len bytes long.
The sglist_append_uio function appends the physical address ranges described by a uio(9) object to the scatter/gather list Fa sg . Note that it is the caller's responsibility to ensure that the pages backing the I/O request are wired for the lifetime of Fa sg . Note also that this routine does not modify Fa uio .
The sglist_append_user function appends the physical address ranges described by a single user virtual address range to the scatter/gather list Fa sg . The user virtual address range is relative to the address space of the thread Fa td . It starts at Fa buf and is Fa len bytes long. Note that it is the caller's responsibility to ensure that the pages backing the user buffer are wired for the lifetime of Fa sg .
The sglist_consume_uio function is a variation of sglist_append_uio As with sglist_append_uio it appends the physical address ranges described by Fa uio to the scatter/gather list Fa sg . Unlike sglist_append_uio however, sglist_consume_uio modifies the I/O request to indicate that the appended address ranges have been processed similar to calling uiomove(9). This routine will only append ranges that describe up to Fa resid total bytes in length. If the available segments in the scatter/gather list are exhausted before Fa resid bytes are processed, then the Fa uio structure will be updated to reflect the actual number of bytes processed, and sglist_consume_io will return zero to indicate success. In effect, this function will perform partial reads or writes. The caller can compare the Fa uio_resid member of Fa uio before and after calling sglist_consume_uio to determine the actual number of bytes processed.
Manipulating Scatter/Gather Lists
The sglist_join function appends physical address ranges from the scatter/gather list Fa second onto Fa first and then resets Fa second to an empty list. It returns zero on success or an error on failure.The sglist_split function splits an existing scatter/gather list into two lists. The first Fa length bytes described by the list Fa original are moved to a new list Fa *head . If Fa original describes a total address range that is smaller than Fa length bytes, then all of the address ranges will be moved to the new list at Fa *head and Fa original will be an empty list. The caller may supply an existing scatter/gather list in Fa *head . If so, the list must be empty. Otherwise, the caller may set Fa *head to NULL in which case a new scatter/gather list will be allocated. In that case, Fa mflags may be set to either M_NOWAIT or M_WAITOK Note that since the Fa original list is modified by this call, it must be a private list with no other references. The sglist_split function returns zero on success or an error on failure.
The sglist_slice function generates a new scatter/gather list from a sub-range of an existing scatter/gather list Fa original . The sub-range to extract is specified by the Fa offset and Fa length parameters. The new scatter/gather list is stored in Fa *slice . As with Fa head for sglist_join the caller may either provide an empty scatter/gather list, or it may set Fa *slice to NULL in which case sglist_slice will allocate a new list subject to Fa mflags . Unlike sglist_split sglist_slice does not modify Fa original and does not require it to be a private list. The sglist_split function returns zero on success or an error on failure.
Miscellaneous Routines
The sglist_reset function clears the scatter/gather list Fa sg so that it no longer maps any address ranges. This can allow reuse of a single scatter/gather list object for multiple requests.The sglist_length function returns the total length of the physical address ranges described by the scatter/gather list Fa sg .
RETURN VALUES
The sglist_alloc sglist_build and sglist_clone functions return a new scatter/gather list on success or NULL on failure.The sglist_append family of functions and the sglist_consume_uio sglist_join sglist_slice and sglist_split functions return zero on success or an error on failure.
The sglist_count function returns a count of scatter/gather list elements.
The sglist_length function returns a count of address space described by a scatter/gather list in bytes.
ERRORS
The sglist_append functions return the following errors on failure:- Bq Er EINVAL
- The scatter/gather list has zero segments.
- Bq Er EFBIG
- There are not enough available segments in the scatter/gather list to append the specified physical address ranges.
The sglist_consume_uio function returns the following error on failure:
- Bq Er EINVAL
- The scatter/gather list has zero segments.
The sglist_join function returns the following error on failure:
- Bq Er EFBIG
- There are not enough available segments in the scatter/gather list Fa first to append the physical address ranges from Fa second .
The sglist_slice function returns the following errors on failure:
- Bq Er EINVAL
- The Fa original scatter/gather list does not describe enough address space to cover the requested sub-range.
- Bq Er EINVAL
- The caller-supplied scatter/gather list in Fa *slice is not empty.
- Bq Er ENOMEM
- An attempt to allocate a new scatter/gather list with M_NOWAIT set in Fa mflags failed.
- Bq Er EFBIG
- There are not enough available segments in the caller-supplied scatter/gather list in Fa *slice to describe the requested physical address ranges.
The sglist_split function returns the following errors on failure:
- Bq Er EDOOFUS
- The Fa original scatter/gather list has more than one reference.
- Bq Er EINVAL
- The caller-supplied scatter/gather list in Fa *head is not empty.
- Bq Er ENOMEM
- An attempt to allocate a new scatter/gather list with M_NOWAIT set in Fa mflags failed.
- Bq Er EFBIG
- There are not enough available segments in the caller-supplied scatter/gather list in Fa *head to describe the requested physical address ranges.