table of contents
| SGLIST(9) | Kernel Developer's Manual | SGLIST(9) | 
NAME¶
sglist,
    sglist_alloc, sglist_append,
    sglist_append_bio,
    sglist_append_mbuf,
    sglist_append_phys,
    sglist_append_uio,
    sglist_append_user,
    sglist_append_vmpages,
    sglist_build, sglist_clone,
    sglist_consume_uio,
    sglist_count,
    sglist_count_vmpages,
    sglist_free, sglist_hold,
    sglist_init, sglist_join,
    sglist_length, sglist_reset,
    sglist_slice, sglist_split
    — manage a scatter/gather list of physical memory
    addresses
SYNOPSIS¶
#include
    <sys/types.h>
  
  #include <sys/sglist.h>
struct sglist *
  
  sglist_alloc(int
    nsegs, int
  mflags);
int
  
  sglist_append(struct
    sglist *sg, void
    *buf, size_t
  len);
int
  
  sglist_append_bio(struct
    sglist *sg, struct bio
    *bp);
int
  
  sglist_append_mbuf(struct
    sglist *sg, struct mbuf
    *m);
int
  
  sglist_append_phys(struct
    sglist *sg, vm_paddr_t
    paddr, size_t
  len);
int
  
  sglist_append_uio(struct
    sglist *sg, struct uio
    *uio);
int
  
  sglist_append_user(struct
    sglist *sg, void
    *buf, size_t len,
    struct thread *td);
int
  
  sglist_append_vmpages(struct
    sglist *sg, vm_page_t
    *m, size_t pgoff,
    size_t len);
struct sglist *
  
  sglist_build(void
    *buf, size_t len,
    int mflags);
struct sglist *
  
  sglist_clone(struct
    sglist *sg, int
    mflags);
int
  
  sglist_consume_uio(struct
    sglist *sg, struct uio
    *uio, size_t
    resid);
int
  
  sglist_count(void
    *buf, size_t
  len);
int
  
  sglist_count_vmpages(vm_page_t
    *m, size_t pgoff,
    size_t len);
void
  
  sglist_free(struct
    sglist *sg);
struct sglist *
  
  sglist_hold(struct
    sglist *sg);
void
  
  sglist_init(struct
    sglist *sg, int
    maxsegs, struct
    sglist_seg *segs);
int
  
  sglist_join(struct
    sglist *first, struct
    sglist *second);
size_t
  
  sglist_length(struct
    sglist *sg);
void
  
  sglist_reset(struct
    sglist *sg);
int
  
  sglist_slice(struct
    sglist *original, struct
    sglist **slice, size_t
    offset, size_t
    length, int
    mflags);
int
  
  sglist_split(struct
    sglist *original, struct
    sglist **head, size_t
    length, int
    mflags);
DESCRIPTION¶
The sglist 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 sglist 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 nsegs scatter/gather list
    elements. The mflags argument can be set to either
    M_NOWAIT or M_WAITOK.
The 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 buf and is
    len bytes long.
The sglist_count_vmpages function returns
    the number of scatter/gather list elements needed to describe the physical
    address ranges of a buffer backed by an array of virtual memory pages
    m. The buffer starts at an offset of
    pgoff bytes relative to the first page and is
    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 buf and is len bytes
    long. The 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 sg. The
    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
    sg and is initialized to manage an array of
    maxsegs scatter/gather list elements pointed to by
    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 sg and
    segs.
Constructing Scatter/Gather Lists¶
The sglist 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 sg. The kernel virtual
    address range starts at buf and is
    len bytes long.
The sglist_append_bio function appends the
    physical address ranges described by a single bio bp
    to the scatter/gather list sg.
The sglist_append_mbuf function appends
    the physical address ranges described by an entire mbuf chain
    m to the scatter/gather list
  sg.
The sglist_append_phys function appends a
    single physical address range to the scatter/gather list
    sg. The physical address range starts at
    paddr and is len bytes long.
The sglist_append_uio function appends the
    physical address ranges described by a uio(9) object to
    the scatter/gather list 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 sg. Note also that this
    routine does not modify uio.
The sglist_append_user function appends
    the physical address ranges described by a single user virtual address range
    to the scatter/gather list sg. The user virtual
    address range is relative to the address space of the thread
    td. It starts at buf and is
    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 sg.
The sglist_append_vmpages function appends
    the physical address ranges of a buffer backed by an array of virtual memory
    pages m. The buffer starts at an offset of
    pgoff bytes relative to the first page and is
    len bytes long.
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 uio to the scatter/gather list
    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 resid total bytes in length. If
    the available segments in the scatter/gather list are exhausted before
    resid bytes are processed, then the
    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
    uio_resid member of 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 second
    onto first and then resets
    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
    length bytes described by the list
    original are moved to a new list
    *head. If original describes a
    total address range that is smaller than length bytes,
    then all of the address ranges will be moved to the new list at
    *head and original will be an
    empty list. The caller may supply an existing scatter/gather list in
    *head. If so, the list must be empty. Otherwise, the
    caller may set *head to NULL
    in which case a new scatter/gather list will be allocated. In that case,
    mflags may be set to either
    M_NOWAIT or M_WAITOK. Note
    that since the 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
    original. The sub-range to extract is specified by the
    offset and length parameters.
    The new scatter/gather list is stored in *slice. As
    with head for sglist_join, the
    caller may either provide an empty scatter/gather list, or it may set
    *slice to NULL in which case
    sglist_slice will allocate a new list subject to
    mflags. Unlike sglist_split,
    sglist_slice does not modify
    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 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 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 and
    sglist_count_vmpages functions return 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:
- [
EINVAL] - The scatter/gather list has zero segments.
 - [
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:
- [
EINVAL] - The scatter/gather list has zero segments.
 
The sglist_join function returns the
    following error on failure:
- [
EFBIG] - There are not enough available segments in the scatter/gather list first to append the physical address ranges from second.
 
The sglist_slice function returns the
    following errors on failure:
- [
EINVAL] - The original scatter/gather list does not describe enough address space to cover the requested sub-range.
 - [
EINVAL] - The caller-supplied scatter/gather list in *slice is not empty.
 - [
ENOMEM] - An attempt to allocate a new scatter/gather list with
      
M_NOWAITset in mflags failed. - [
EFBIG] - There are not enough available segments in the caller-supplied scatter/gather list in *slice to describe the requested physical address ranges.
 
The sglist_split function returns the
    following errors on failure:
- [
EDOOFUS] - The original scatter/gather list has more than one reference.
 - [
EINVAL] - The caller-supplied scatter/gather list in *head is not empty.
 - [
ENOMEM] - An attempt to allocate a new scatter/gather list with
      
M_NOWAITset in mflags failed. - [
EFBIG] - There are not enough available segments in the caller-supplied scatter/gather list in *head to describe the requested physical address ranges.
 
SEE ALSO¶
HISTORY¶
This API was first introduced in FreeBSD 8.0.
| January 12, 2014 | Debian |