Manual page for hardware-assisted data mover interface.
This commit is contained in:
parent
321a514c93
commit
d09e51c588
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.117 2002/07/20 03:58:26 thorpej Exp $
|
||||
# $NetBSD: Makefile,v 1.118 2002/08/02 00:41:53 thorpej Exp $
|
||||
|
||||
# Makefile for section 9 (kernel function and variable) manual pages.
|
||||
|
||||
|
@ -28,6 +28,16 @@ MAN= access.9 altq.9 arc4random.9 arp.9 audio.9 autoconf.9 \
|
|||
vattr.9 vfs.9 vfsops.9 vme.9 vnode.9 vnodeops.9 vnsubr.9 \
|
||||
usbdi.9 uvm.9 wdc.9 wscons.9 wsdisplay.9 wsfont.9 wskbd.9 wsmouse.9
|
||||
|
||||
MAN+= dmover.9
|
||||
MLINKS+=dmover.9 dmover_backend_register.9 \
|
||||
dmover.9 dmover_backend_unregister.9 \
|
||||
dmover.9 dmover_session_create.9 \
|
||||
dmover.9 dmover_session_destroy.9 \
|
||||
dmover.9 dmover_request_alloc.9 \
|
||||
dmover.9 dmover_request_free.9 \
|
||||
dmover.9 dmover_process.9 \
|
||||
dmover.9 dmover_done.9
|
||||
|
||||
MLINKS+=arp.9 arp_ifinit.9 arp.9 arpresolve.9 arp.9 arpintr.9
|
||||
MLINKS+=access.9 kernacc.9 access.9 useracc.9
|
||||
MLINKS+=autoconf.9 config_search.9 \
|
||||
|
|
|
@ -0,0 +1,557 @@
|
|||
.\" $NetBSD: dmover.9,v 1.1 2002/08/02 00:41:53 thorpej Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002 Wasabi Systems, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Written by Jason R. Thorpe for Wasabi Systems, Inc.
|
||||
.\"
|
||||
.\" 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 following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed for the NetBSD Project by
|
||||
.\" Wasabi Systems, Inc.
|
||||
.\" 4. The name of Wasabi Systems, Inc. may not be used to endorse
|
||||
.\" or promote products derived from this software without specific prior
|
||||
.\" written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd July 15, 2002
|
||||
.Dt DMOVER 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm dmover_backend_register ,
|
||||
.Nm dmover_backend_unregister ,
|
||||
.Nm dmover_session_create ,
|
||||
.Nm dmover_session_destroy ,
|
||||
.Nm dmover_request_alloc ,
|
||||
.Nm dmover_request_free ,
|
||||
.Nm dmover_process ,
|
||||
.Nm dmover_done
|
||||
.Nd hardware-assisted data mover interface
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include \*[Lt]dev/dmover/dmovervar.h\*[Gt]
|
||||
.Pp
|
||||
Client interface routines:
|
||||
.Pp
|
||||
.Ft int
|
||||
.Fn "dmover_session_create" "const char *, struct dmover_session **"
|
||||
.Ft void
|
||||
.Fn "dmover_session_destroy" "struct dmover_session *"
|
||||
.Ft "struct dmover_request *"
|
||||
.Fn "dmover_request_alloc" "struct dmover_session *" "dmover_buffer *"
|
||||
.Ft void
|
||||
.Fn "dmover_request_free" "struct dmover_request *"
|
||||
.Ft void
|
||||
.Fn "dmover_process" "struct dmover_request *"
|
||||
.Pp
|
||||
Back-end interface routines:
|
||||
.Pp
|
||||
.Ft void
|
||||
.Fn "dmover_backend_register" "struct dmover_backend *"
|
||||
.Ft void
|
||||
.Fn "dmover_backend_unregister" "struct dmover_backend *"
|
||||
.Ft void
|
||||
.Fn "dmover_done" "struct dmover_request *"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm dmover
|
||||
facility provides an interface to hardware-assisted data movers. This
|
||||
can be used to copy data from one location in memory to another, clear
|
||||
a region of memory, fill a region of memory with a pattern, and perform
|
||||
simple operations on multiple regions of memory, such as an XOR, without
|
||||
intervention by the CPU.
|
||||
.Pp
|
||||
The drivers for hardware-assisted data movers present themselves to
|
||||
.Nm dmover
|
||||
by registering their capabilities. When a client wishes to use a
|
||||
.Nm dmover
|
||||
function, it creates a session for that function, which identifies back-ends
|
||||
capable of performing that function. The client then enqueues requests
|
||||
on that session, which the back-ends process asynchronously. The client
|
||||
may choose to block until the request is completed, or may have a call-back
|
||||
invoked once the request has been completed.
|
||||
.Pp
|
||||
When a client creates a session, the
|
||||
.Nm dmover
|
||||
facility identifies back-ends which are capable of handling the requested
|
||||
function. When a request is scheduled for processing, the
|
||||
.Nm dmover
|
||||
scheduler will indentify the best back-end to process the request from
|
||||
the list of candidate back-ends, in an effort to provide load balancing,
|
||||
while considering the relative performance of each back-end.
|
||||
.Pp
|
||||
A
|
||||
.Nm dmover
|
||||
function always has one output region. A function may have zero or more
|
||||
input regions, or may use an immediate value as an input. For functions
|
||||
which use input regions, the lenghts of each input region and the output
|
||||
region must be the same. All
|
||||
.Nm dmover
|
||||
functions with the same name will have the same number of and type inputs.
|
||||
If a back-end attempts to register a function which violates this invariant,
|
||||
behavior is undefined.
|
||||
.Pp
|
||||
The
|
||||
.Nm dmover
|
||||
facility supports several types of buffer descriptors. For functions
|
||||
which use input regions, each input buffer descriptor and the output buffer
|
||||
descriptor must be of the same type. This restriction may be removed in
|
||||
a future revision of the interface.
|
||||
.Pp
|
||||
The
|
||||
.Nm dmover
|
||||
facility may need to interrupt request processing and restart it.
|
||||
Clients of the
|
||||
.Nm dmover
|
||||
facility should take care to avoid unwanted side-effects should this occur.
|
||||
In particular, for functions which use input regions, no input region may
|
||||
overlap with the output region.
|
||||
.Ss DATA STRUCTURES
|
||||
The
|
||||
.Nm dmover
|
||||
facility shares several data structures between the client and
|
||||
back-end in order to describe sessions and requests.
|
||||
.Bd -literal -offset indent
|
||||
typedef enum {
|
||||
DMOVER_BUF_LINEAR,
|
||||
DMOVER_BUF_UIO
|
||||
} dmover_buffer_type;
|
||||
|
||||
typedef struct {
|
||||
void *l_addr;
|
||||
size_t l_len;
|
||||
} dmover_buf_linear;
|
||||
|
||||
typedef union {
|
||||
dmover_buf_linear dmbuf_linear;
|
||||
struct uio *dmbuf_uio;
|
||||
} dmover_buffer;
|
||||
.Ed
|
||||
.Pp
|
||||
Together, these data types are used to describe buffer data structures
|
||||
which the
|
||||
.Nm dmover
|
||||
facility understands. Additional buffer types may be added in future
|
||||
revisions of the
|
||||
.Nm dmover
|
||||
interface.
|
||||
.Pp
|
||||
The
|
||||
.Fa dmover_assignment
|
||||
structure contains the information about the back-end to which a
|
||||
request is currently assigned. It contains the following public members:
|
||||
.Bl -tag -width "XXXX"
|
||||
.It struct dmover_backend *das_backend
|
||||
This is a pointer to the back-end.
|
||||
.It const struct dmover_algdesc *das_algdesc
|
||||
This is a pointer to the algorithm description provided by
|
||||
the back-end for the request's function.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fa dmover_session
|
||||
structure contains the following public members:
|
||||
.Bl -tag -width "XXXX"
|
||||
.It void *dses_cookie
|
||||
This is a pointer to client private data.
|
||||
.It int dses_ninputs
|
||||
This is the number of inputs used by the selected function.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fa dmover_request
|
||||
structure contains the following public members:
|
||||
.Bl -tag -width "XXXX"
|
||||
.It TAILQ_ENTRY(dmover_request) dreq_dmbq
|
||||
Linkage on the back-end's queue of pending requests.
|
||||
.It struct dmover_session *dreq_session
|
||||
Pointer to the session with which this request is associated. This
|
||||
is intended for use by the back-end.
|
||||
.It struct dmover_assignment *dreq_assignment
|
||||
Pointer to the
|
||||
.Fa dmover_assignment
|
||||
structure which describes the back-end to which the request is
|
||||
currently assigned. The back-end is assigned when the request
|
||||
is scheduled with
|
||||
.Fn dmover_process .
|
||||
.It void (*dreq_callback)(struct dmover_request *)
|
||||
This is a pointer to an optional call-back function provided by the
|
||||
client. If provided, the call-back is invoked when the request is
|
||||
complete. This field must be NULL if
|
||||
.Em DMOVER_REQ_WAIT
|
||||
is set in
|
||||
.Em dreq_flags .
|
||||
.It void *dreq_cookie
|
||||
This is a pointer to client private data specific to the request.
|
||||
.It void *dreq_dmbcookie
|
||||
This is a pointer to back-end private data, for use while the back-end
|
||||
is actively processing a request.
|
||||
.It __volatile int dreq_flags
|
||||
The following flags are defined:
|
||||
.Bl -tag -width "DMOVER_REQ_RUNNINGXX"
|
||||
.It DMOVER_REQ_DONE
|
||||
The request has been completed. If not using a call-back, the client
|
||||
may poll this bit to determine if a request has been processed.
|
||||
.It DMOVER_REQ_ERROR
|
||||
An error has occurred while processing the request.
|
||||
.It DMOVER_REQ_RUNNING
|
||||
The request is currently being executed by the back-end. Once a
|
||||
command is running, it cannot be cancelled, and must run to completion.
|
||||
.It DMOVER_REQ_WAIT
|
||||
If set by the client,
|
||||
.Fn dmover_process
|
||||
will wait for the request to complete using
|
||||
.Xr tsleep 9 .
|
||||
This flag may only be used if the caller has a valid thread context.
|
||||
If this flag is set, a callback may not be used.
|
||||
.El
|
||||
.It int dreq_error
|
||||
If the
|
||||
.Em DMOVER_REQ_ERROR
|
||||
bit is set, this contains the
|
||||
.Xr errno 2
|
||||
value indicating the error that occurred during processing.
|
||||
.It dmover_buffer_type dreq_outbuf_type
|
||||
The type of the output buffer.
|
||||
.It dmover_buffer dreq_outbuf
|
||||
The output buffer.
|
||||
.It uint8_t dreq_immediate[8]
|
||||
This is the input for algorithms which use an immediate value. Values
|
||||
smaller than 8 bytes should use the least-significant bytes first. For
|
||||
example, a 32-bit integer would occupy bytes 0, 1, 2, and 3.
|
||||
.It dmover_buffer_type dreq_inbuf_type
|
||||
The type of the input buffer. This is only used if the
|
||||
.Nm dmover
|
||||
function has one or more inputs.
|
||||
.It dmover_buffer *dreq_inbuf
|
||||
A pointer to an array of input buffers. This is only used if the
|
||||
.Nm dmover
|
||||
function has one or more inputs. The number of inputs, and thus the
|
||||
number of valid elements in the array, is specified by the algorithm
|
||||
description for the session.
|
||||
.El
|
||||
.Ss CLIENT INTERFACE
|
||||
The following functions are provided to the client:
|
||||
.Bl -tag -width "XXXX"
|
||||
.It int Fn dmover_session_create "const char *function" \
|
||||
"struct dmover_session **sessionp"
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_session_create
|
||||
function creates a data mover session for the specified data movement
|
||||
function
|
||||
.Fa function .
|
||||
A handle to the new session is returned in
|
||||
.Fa *sessionp .
|
||||
.Pp
|
||||
The following are valid data movement function names:
|
||||
.Bl -tag -width "fill8xx"
|
||||
.It Dq zero
|
||||
Fill a memory region with zeros. This algorithm has an input count of 0.
|
||||
.It Dq fill8
|
||||
Fill a memory region with an 8-bit pattern. This algorithm has an input
|
||||
count of 0. The pattern is provided in the
|
||||
.Em dreq_imm8
|
||||
member of the
|
||||
.Fa dmover_request
|
||||
structure.
|
||||
.It Dq copy
|
||||
Copy a memory region from one location to another. This algorithm has an
|
||||
input count of 1.
|
||||
.El
|
||||
.Pp
|
||||
Users of the
|
||||
.Nm dmover
|
||||
facility are encouraged to use the following aliases for the well-known
|
||||
function names, as doing so saves space and reduces the chance of programming
|
||||
errors:
|
||||
.Bl -tag -width "DMOVER_FUNC_FILL32xx"
|
||||
.It DMOVER_FUNC_ZERO
|
||||
.Dq zero
|
||||
.Pq Va dmover_funcname_zero
|
||||
.It DMOVER_FUNC_FILL8
|
||||
.Dq fill8
|
||||
.Pq Va dmover_funcname_fill8
|
||||
.It DMOVER_FUNC_COPY
|
||||
.Dq copy
|
||||
.Pq Va dmover_funcname_copy
|
||||
.El
|
||||
.It void Fn dmover_session_destroy "struct dmover_session *session"
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_session_destroy
|
||||
function tears down a data mover session and releases all resources
|
||||
associated with it.
|
||||
.It struct dmover_request * Fn dmover_request_alloc \
|
||||
"struct dmover_session *session" "dmover_buffer *inbuf"
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_request_alloc
|
||||
function allocates a
|
||||
.Nm dmover
|
||||
request structure and associates it with the specified session.
|
||||
If the
|
||||
.Fa inbuf
|
||||
argument is non-NULL,
|
||||
.Fa inbuf
|
||||
is used as the array of input buffer descriptors in the request.
|
||||
Otherwise, if
|
||||
.Fa inbuf
|
||||
is NULL and the
|
||||
.Nm dmover
|
||||
function requires input buffers, the input buffer descriptors will be
|
||||
allocated automatically using
|
||||
.Xr malloc 9 .
|
||||
.Pp
|
||||
If the request structure or input buffer descriptors cannot be allocated,
|
||||
.Fn dmover_request_alloc
|
||||
return NULL to indicate failure.
|
||||
.It void Fn dmover_request_free "struct dmover_request *req"
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_request_free
|
||||
function frees a
|
||||
.Nm dmover
|
||||
request structure. If the
|
||||
.Nm dmover
|
||||
function requires input buffers, and the input buffer descriptors
|
||||
assiciated with
|
||||
.Fa req
|
||||
were allocated by
|
||||
.Fn dmover_request_alloc ,
|
||||
then the input buffer descriptors will also be freed.
|
||||
.It void Fn dmover_process "struct dmover_request *req"
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_process
|
||||
function submits the
|
||||
.Nm dmover
|
||||
request
|
||||
.Fa req
|
||||
for processing. The call-back specified by the request is
|
||||
invoked when processing is complete.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_session_create
|
||||
and
|
||||
.Fn dmover_session_destroy
|
||||
functions must not be called from interrupt context.
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_request_alloc ,
|
||||
.Fn dmover_request_free ,
|
||||
and
|
||||
.Fn dmover_process
|
||||
functions may be called from interrupt handlers at levels
|
||||
.Em IPL_BIO ,
|
||||
.Em IPL_SOFTCLOCK ,
|
||||
and
|
||||
.Em IPL_SOFTNET ,
|
||||
or in non-interrupt context.
|
||||
.Pp
|
||||
The request completion call-back is called from a software interrupt
|
||||
handler at
|
||||
.Em IPL_SOFTCLOCK .
|
||||
.Ss BACK-END INTERFACE
|
||||
A back-end describes the
|
||||
.Nm dmover
|
||||
functions it can perform using an array of
|
||||
.Fa dmover_algdesc
|
||||
structures:
|
||||
.Bd -literal -offset indent
|
||||
struct dmover_algdesc {
|
||||
const char *dad_name; /* algorithm name */
|
||||
void *dad_data; /* opaque algorithm description */
|
||||
int dad_ninputs; /* number of inputs */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Em dad_name
|
||||
member points to a valid
|
||||
.Nm dmover
|
||||
function name which the client may specify. The
|
||||
.Em dad_data
|
||||
member points to a back-end-specific description of the algorithm.
|
||||
.Pp
|
||||
A back-end presents itself to the
|
||||
.Nm dmover
|
||||
facility using the
|
||||
.Fa dmover_backend
|
||||
structure. The back-end must initialize the following members
|
||||
of the structure:
|
||||
.Bl -tag -width "XXXX"
|
||||
.It const char *dmb_name
|
||||
This is the name of the back-end.
|
||||
.It u_int dmb_speed
|
||||
This is an estimate of the number of kilobytes/sec. that the
|
||||
back-end can process.
|
||||
.It void *dmb_cookie
|
||||
This is a pointer to back-end private data.
|
||||
.It const struct dmover_algdesc *dmb_algdescs
|
||||
This points to an array of
|
||||
.Fa dmover_algdesc
|
||||
structures which describe the functions the data mover can perform.
|
||||
.It int dmb_nalgdescs
|
||||
This is the number of elements in the
|
||||
.Em dmb_algdescs
|
||||
array.
|
||||
.It void (*dmb_process)(struct dmover_backend *)
|
||||
This is the entry point to the back-end used to process requests.
|
||||
.El
|
||||
.Pp
|
||||
When invoked by the
|
||||
.Nm dmover
|
||||
facility, the back-end's
|
||||
.Fn (*dmb_process)
|
||||
function should examine the pending request queue in it's
|
||||
.Fa dmover_backend
|
||||
structure:
|
||||
.Bl -tag -width "XXXX"
|
||||
.It TAILQ_HEAD(, dmover_request) dmb_pendreqs
|
||||
This is the queue of pending requests.
|
||||
.It int dmb_npendreqs
|
||||
This is the number of requests in the
|
||||
.Em dmb_pendreqs
|
||||
queue.
|
||||
.El
|
||||
.Pp
|
||||
If an error occurs when processing the request, the
|
||||
.Em DMOVER_REQ_ERROR
|
||||
bit must be set in the
|
||||
.Em dreq_flags
|
||||
member of the request, and the
|
||||
.Em dreq_error
|
||||
member set to an
|
||||
.Xr errno 2
|
||||
value to indicate the error.
|
||||
.Pp
|
||||
When the back-end has finished processing the request, it must call
|
||||
the
|
||||
.Fn dmover_done
|
||||
function. This function eventually invokes the client's call-back
|
||||
routine.
|
||||
.Pp
|
||||
If a hardware-assisted data mover uses interrupts, the interrupt handlers
|
||||
should be registered at IPL_BIO.
|
||||
.Pp
|
||||
The following functions are provided to the back-ends:
|
||||
.Bl -tag -width "XXXX"
|
||||
.It void Fn dmover_backend_register "struct dmover_backend *backend"
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_backend_register
|
||||
function registers the back-end
|
||||
.Fa backend
|
||||
with the
|
||||
.Nm dmover
|
||||
facility.
|
||||
.It void Fn dmover_backend_unregister "struct dmover_backend *backend"
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_backend_unregister
|
||||
function removes the back-end
|
||||
.Fa backend
|
||||
from the
|
||||
.Nm dmover
|
||||
facility. The back-end must already be registered.
|
||||
.It void Fn dmover_done "struct dmover_request *req"
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_done
|
||||
function is called by the back-end when it has finished processing
|
||||
a request, whether the request completed successfully or not.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_backend_register
|
||||
and
|
||||
.Fn dmover_backend_unregister
|
||||
functions must not be called from interrupt context.
|
||||
.Pp
|
||||
The
|
||||
.Fn dmover_done
|
||||
function may be called at
|
||||
.Em IPL_BIO ,
|
||||
.Em IPL_SOFTCLOCK ,
|
||||
.Em IPL_SOFTNET ,
|
||||
or in non-interrupt context.
|
||||
.Ss EXAMPLE USAGE
|
||||
The following is an example of a client using
|
||||
.Nm dmover
|
||||
to zero-fill a region of memory. In this example, the CPU will be
|
||||
able to context switch to another thread and perform work while the
|
||||
hardware-assisted data mover clears the specified block of memory.
|
||||
.Bd -literal
|
||||
int
|
||||
hw_bzero(void *buf, size_t len)
|
||||
{
|
||||
struct dmover_session *dses;
|
||||
struct dmover_request *dreq;
|
||||
int error;
|
||||
|
||||
error = dmover_session_create(DMOVER_FUNC_ZERO, &dses);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
dreq = dmover_request_alloc(dses, NULL);
|
||||
if (dreq == NULL) {
|
||||
dmover_session_destroy(dses);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
dreq->dreq_flags = DMOVER_REQ_WAIT;
|
||||
dreq->dreq_callback = NULL;
|
||||
dreq->dreq_outbuf.dreq_outbuf_type = DMOVER_BUF_LINEAR;
|
||||
dreq->dreq_outbuf.dreq_outbuf_linear = buf;
|
||||
dreq->dreq_outbuf.dreq_outbuf_len = len;
|
||||
|
||||
dmover_process(dreq);
|
||||
|
||||
error = (dreq->dreq_flags & DMOVER_REQ_ERROR) ?
|
||||
dreq->dreq_error : 0;
|
||||
|
||||
dmover_request_free(dreq, NULL);
|
||||
dmover_session_destroy(dses);
|
||||
|
||||
return (error);
|
||||
}
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr dmoverio 4 ,
|
||||
.Xr queue 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm dmover
|
||||
facility first appeared in
|
||||
.Nx 2.0 .
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm dmover
|
||||
facility was designed and implemented by
|
||||
.An Jason R. Thorpe
|
||||
.Aq thorpej@wasabisystems.com
|
||||
and contributed by Wasabi Systems, Inc.
|
||||
.Sh BUGS
|
||||
The mechanism by which a back-end should advertise its performance to
|
||||
the request scheduler is not well-defined. Therefore, the load-balancing
|
||||
mechanism within the request scheduler is also not well-defined.
|
Loading…
Reference in New Issue