ioat: make channel allocation explicit
Add a parameter to each I/OAT library function that requires a channel instead of implicitly using the thread-local channel registration model. I/OAT channels are already reported by the spdk_ioat_probe() attach callback, so no infrastructure for channel allocation is necessary. Change-Id: I8731126fcaea9fe2bafc41a3f75c969a100ef8f0 Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
1dd7473078
commit
cf0871a57e
@ -42,7 +42,6 @@
|
|||||||
\section key_functions Key Functions
|
\section key_functions Key Functions
|
||||||
|
|
||||||
- spdk_ioat_probe() \copybrief spdk_ioat_probe()
|
- spdk_ioat_probe() \copybrief spdk_ioat_probe()
|
||||||
- spdk_ioat_register_thread() \copybrief spdk_ioat_register_thread()
|
|
||||||
- spdk_ioat_get_dma_capabilities() \copybrief spdk_ioat_get_dma_capabilities()
|
- spdk_ioat_get_dma_capabilities() \copybrief spdk_ioat_get_dma_capabilities()
|
||||||
- spdk_ioat_submit_copy() \copybrief spdk_ioat_submit_copy()
|
- spdk_ioat_submit_copy() \copybrief spdk_ioat_submit_copy()
|
||||||
- spdk_ioat_submit_fill() \copybrief spdk_ioat_submit_fill()
|
- spdk_ioat_submit_fill() \copybrief spdk_ioat_submit_fill()
|
||||||
|
@ -61,10 +61,12 @@ struct ioat_device {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static TAILQ_HEAD(, ioat_device) g_devices;
|
static TAILQ_HEAD(, ioat_device) g_devices;
|
||||||
|
static struct ioat_device *g_next_device;
|
||||||
|
|
||||||
static struct user_config g_user_config;
|
static struct user_config g_user_config;
|
||||||
|
|
||||||
struct thread_entry {
|
struct thread_entry {
|
||||||
|
struct spdk_ioat_chan *chan;
|
||||||
uint64_t xfer_completed;
|
uint64_t xfer_completed;
|
||||||
uint64_t xfer_failed;
|
uint64_t xfer_failed;
|
||||||
uint64_t current_queue_depth;
|
uint64_t current_queue_depth;
|
||||||
@ -244,7 +246,7 @@ static void
|
|||||||
drain_io(struct thread_entry *thread_entry)
|
drain_io(struct thread_entry *thread_entry)
|
||||||
{
|
{
|
||||||
while (thread_entry->current_queue_depth > 0) {
|
while (thread_entry->current_queue_depth > 0) {
|
||||||
spdk_ioat_process_events();
|
spdk_ioat_process_events(thread_entry->chan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +258,8 @@ submit_single_xfer(struct thread_entry *thread_entry, struct ioat_task *ioat_tas
|
|||||||
ioat_task->src = src;
|
ioat_task->src = src;
|
||||||
ioat_task->dst = dst;
|
ioat_task->dst = dst;
|
||||||
|
|
||||||
spdk_ioat_submit_copy(ioat_task, ioat_done, dst, src, g_user_config.xfer_size_bytes);
|
spdk_ioat_submit_copy(thread_entry->chan, ioat_task, ioat_done, dst, src,
|
||||||
|
g_user_config.xfer_size_bytes);
|
||||||
|
|
||||||
thread_entry->current_queue_depth++;
|
thread_entry->current_queue_depth++;
|
||||||
}
|
}
|
||||||
@ -283,6 +286,10 @@ work_fn(void *arg)
|
|||||||
uint64_t tsc_end;
|
uint64_t tsc_end;
|
||||||
struct thread_entry *t = (struct thread_entry *)arg;
|
struct thread_entry *t = (struct thread_entry *)arg;
|
||||||
|
|
||||||
|
if (!t->chan) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
t->lcore_id = rte_lcore_id();
|
t->lcore_id = rte_lcore_id();
|
||||||
|
|
||||||
snprintf(buf_pool_name, sizeof(buf_pool_name), "buf_pool_%d", rte_lcore_id());
|
snprintf(buf_pool_name, sizeof(buf_pool_name), "buf_pool_%d", rte_lcore_id());
|
||||||
@ -297,24 +304,17 @@ work_fn(void *arg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spdk_ioat_register_thread() != 0) {
|
|
||||||
fprintf(stderr, "lcore %u: No ioat channels found. Check that ioatdma driver is unloaded.\n",
|
|
||||||
rte_lcore_id());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tsc_end = rte_get_timer_cycles() + g_user_config.time_in_sec * rte_get_timer_hz();
|
tsc_end = rte_get_timer_cycles() + g_user_config.time_in_sec * rte_get_timer_hz();
|
||||||
|
|
||||||
// begin to submit transfers
|
// begin to submit transfers
|
||||||
submit_xfers(t, g_user_config.queue_depth);
|
submit_xfers(t, g_user_config.queue_depth);
|
||||||
while (rte_get_timer_cycles() < tsc_end) {
|
while (rte_get_timer_cycles() < tsc_end) {
|
||||||
spdk_ioat_process_events();
|
spdk_ioat_process_events(t->chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin to drain io
|
// begin to drain io
|
||||||
t->is_draining = true;
|
t->is_draining = true;
|
||||||
drain_io(t);
|
drain_io(t);
|
||||||
spdk_ioat_unregister_thread();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -383,6 +383,23 @@ dump_result(struct thread_entry *threads, int len)
|
|||||||
return total_failed ? 1 : 0;
|
return total_failed ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct spdk_ioat_chan *
|
||||||
|
get_next_chan(void)
|
||||||
|
{
|
||||||
|
struct spdk_ioat_chan *chan;
|
||||||
|
|
||||||
|
if (g_next_device == NULL) {
|
||||||
|
fprintf(stderr, "Not enough ioat channels found. Check that ioatdma driver is unloaded.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
chan = g_next_device->ioat;
|
||||||
|
|
||||||
|
g_next_device = TAILQ_NEXT(g_next_device, tailq);
|
||||||
|
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -400,10 +417,13 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
dump_user_config(&g_user_config);
|
dump_user_config(&g_user_config);
|
||||||
|
|
||||||
|
g_next_device = TAILQ_FIRST(&g_devices);
|
||||||
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
|
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
|
||||||
|
threads[lcore_id].chan = get_next_chan();
|
||||||
rte_eal_remote_launch(work_fn, &threads[lcore_id], lcore_id);
|
rte_eal_remote_launch(work_fn, &threads[lcore_id], lcore_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
threads[rte_get_master_lcore()].chan = get_next_chan();
|
||||||
if (work_fn(&threads[rte_get_master_lcore()]) != 0) {
|
if (work_fn(&threads[rte_get_master_lcore()]) != 0) {
|
||||||
rc = 1;
|
rc = 1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -66,10 +66,12 @@ struct ioat_device {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static TAILQ_HEAD(, ioat_device) g_devices;
|
static TAILQ_HEAD(, ioat_device) g_devices;
|
||||||
|
static struct ioat_device *g_next_device;
|
||||||
|
|
||||||
static struct user_config g_user_config;
|
static struct user_config g_user_config;
|
||||||
|
|
||||||
struct thread_entry {
|
struct thread_entry {
|
||||||
|
struct spdk_ioat_chan *chan;
|
||||||
uint64_t xfer_completed;
|
uint64_t xfer_completed;
|
||||||
uint64_t xfer_failed;
|
uint64_t xfer_failed;
|
||||||
uint64_t fill_completed;
|
uint64_t fill_completed;
|
||||||
@ -292,7 +294,7 @@ static void
|
|||||||
drain_xfers(struct thread_entry *thread_entry)
|
drain_xfers(struct thread_entry *thread_entry)
|
||||||
{
|
{
|
||||||
while (thread_entry->current_queue_depth > 0) {
|
while (thread_entry->current_queue_depth > 0) {
|
||||||
spdk_ioat_process_events();
|
spdk_ioat_process_events(thread_entry->chan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,10 +302,11 @@ static void
|
|||||||
submit_single_xfer(struct ioat_task *ioat_task)
|
submit_single_xfer(struct ioat_task *ioat_task)
|
||||||
{
|
{
|
||||||
if (ioat_task->type == IOAT_FILL_TYPE)
|
if (ioat_task->type == IOAT_FILL_TYPE)
|
||||||
spdk_ioat_submit_fill(ioat_task, ioat_done, ioat_task->dst, ioat_task->fill_pattern,
|
spdk_ioat_submit_fill(ioat_task->thread_entry->chan, ioat_task, ioat_done,
|
||||||
ioat_task->len);
|
ioat_task->dst, ioat_task->fill_pattern, ioat_task->len);
|
||||||
else
|
else
|
||||||
spdk_ioat_submit_copy(ioat_task, ioat_done, ioat_task->dst, ioat_task->src, ioat_task->len);
|
spdk_ioat_submit_copy(ioat_task->thread_entry->chan, ioat_task, ioat_done,
|
||||||
|
ioat_task->dst, ioat_task->src, ioat_task->len);
|
||||||
ioat_task->thread_entry->current_queue_depth++;
|
ioat_task->thread_entry->current_queue_depth++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,7 +319,7 @@ submit_xfers(struct thread_entry *thread_entry, uint64_t queue_depth)
|
|||||||
rte_mempool_get(thread_entry->data_pool, &(ioat_task->buffer));
|
rte_mempool_get(thread_entry->data_pool, &(ioat_task->buffer));
|
||||||
|
|
||||||
ioat_task->type = IOAT_COPY_TYPE;
|
ioat_task->type = IOAT_COPY_TYPE;
|
||||||
if (spdk_ioat_get_dma_capabilities() & SPDK_IOAT_ENGINE_FILL_SUPPORTED) {
|
if (spdk_ioat_get_dma_capabilities(thread_entry->chan) & SPDK_IOAT_ENGINE_FILL_SUPPORTED) {
|
||||||
if (queue_depth % 2)
|
if (queue_depth % 2)
|
||||||
ioat_task->type = IOAT_FILL_TYPE;
|
ioat_task->type = IOAT_FILL_TYPE;
|
||||||
}
|
}
|
||||||
@ -332,6 +335,10 @@ work_fn(void *arg)
|
|||||||
char buf_pool_name[20], task_pool_name[20];
|
char buf_pool_name[20], task_pool_name[20];
|
||||||
struct thread_entry *t = (struct thread_entry *)arg;
|
struct thread_entry *t = (struct thread_entry *)arg;
|
||||||
|
|
||||||
|
if (!t->chan) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
t->lcore_id = rte_lcore_id();
|
t->lcore_id = rte_lcore_id();
|
||||||
|
|
||||||
snprintf(buf_pool_name, sizeof(buf_pool_name), "buf_pool_%d", rte_lcore_id());
|
snprintf(buf_pool_name, sizeof(buf_pool_name), "buf_pool_%d", rte_lcore_id());
|
||||||
@ -347,24 +354,16 @@ work_fn(void *arg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spdk_ioat_register_thread() != 0) {
|
|
||||||
fprintf(stderr, "lcore %u: No ioat channels found. Check that ioatdma driver is unloaded.\n",
|
|
||||||
rte_lcore_id());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tsc_end = rte_get_timer_cycles() + g_user_config.time_in_sec * rte_get_timer_hz();
|
tsc_end = rte_get_timer_cycles() + g_user_config.time_in_sec * rte_get_timer_hz();
|
||||||
|
|
||||||
submit_xfers(t, g_user_config.queue_depth);
|
submit_xfers(t, g_user_config.queue_depth);
|
||||||
while (rte_get_timer_cycles() < tsc_end) {
|
while (rte_get_timer_cycles() < tsc_end) {
|
||||||
spdk_ioat_process_events();
|
spdk_ioat_process_events(t->chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
t->is_draining = true;
|
t->is_draining = true;
|
||||||
drain_xfers(t);
|
drain_xfers(t);
|
||||||
|
|
||||||
spdk_ioat_unregister_thread();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,6 +436,23 @@ dump_result(struct thread_entry *threads, int len)
|
|||||||
return total_failed ? 1 : 0;
|
return total_failed ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct spdk_ioat_chan *
|
||||||
|
get_next_chan(void)
|
||||||
|
{
|
||||||
|
struct spdk_ioat_chan *chan;
|
||||||
|
|
||||||
|
if (g_next_device == NULL) {
|
||||||
|
fprintf(stderr, "Not enough ioat channels found. Check that ioatdma driver is unloaded.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
chan = g_next_device->ioat;
|
||||||
|
|
||||||
|
g_next_device = TAILQ_NEXT(g_next_device, tailq);
|
||||||
|
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -454,10 +470,13 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
dump_user_config(&g_user_config);
|
dump_user_config(&g_user_config);
|
||||||
|
|
||||||
|
g_next_device = TAILQ_FIRST(&g_devices);
|
||||||
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
|
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
|
||||||
|
threads[lcore_id].chan = get_next_chan();
|
||||||
rte_eal_remote_launch(work_fn, &threads[lcore_id], lcore_id);
|
rte_eal_remote_launch(work_fn, &threads[lcore_id], lcore_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
threads[rte_get_master_lcore()].chan = get_next_chan();
|
||||||
if (work_fn(&threads[rte_get_master_lcore()]) != 0) {
|
if (work_fn(&threads[rte_get_master_lcore()]) != 0) {
|
||||||
rc = 1;
|
rc = 1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -91,50 +91,26 @@ int spdk_ioat_probe(void *cb_ctx, spdk_ioat_probe_cb probe_cb, spdk_ioat_attach_
|
|||||||
*/
|
*/
|
||||||
int spdk_ioat_detach(struct spdk_ioat_chan *ioat);
|
int spdk_ioat_detach(struct spdk_ioat_chan *ioat);
|
||||||
|
|
||||||
/**
|
|
||||||
* Request a DMA engine channel for the calling thread.
|
|
||||||
*
|
|
||||||
* Must be called before submitting any requests from a thread.
|
|
||||||
*
|
|
||||||
* The \ref spdk_ioat_unregister_thread() function can be called to release the channel.
|
|
||||||
*/
|
|
||||||
int spdk_ioat_register_thread(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregister the current thread's I/OAT channel.
|
|
||||||
*
|
|
||||||
* This function can be called after \ref spdk_ioat_register_thread() to release the thread's
|
|
||||||
* DMA engine channel for use by other threads.
|
|
||||||
*/
|
|
||||||
void spdk_ioat_unregister_thread(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit a DMA engine memory copy request.
|
* Submit a DMA engine memory copy request.
|
||||||
*
|
|
||||||
* Before submitting any requests on a thread, the thread must be registered
|
|
||||||
* using the \ref spdk_ioat_register_thread() function.
|
|
||||||
*/
|
*/
|
||||||
int64_t spdk_ioat_submit_copy(void *cb_arg, spdk_ioat_req_cb cb_fn,
|
int64_t spdk_ioat_submit_copy(struct spdk_ioat_chan *chan,
|
||||||
|
void *cb_arg, spdk_ioat_req_cb cb_fn,
|
||||||
void *dst, const void *src, uint64_t nbytes);
|
void *dst, const void *src, uint64_t nbytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit a DMA engine memory fill request.
|
* Submit a DMA engine memory fill request.
|
||||||
*
|
|
||||||
* Before submitting any requests on a thread, the thread must be registered
|
|
||||||
* using the \ref spdk_ioat_register_thread() function.
|
|
||||||
*/
|
*/
|
||||||
int64_t spdk_ioat_submit_fill(void *cb_arg, spdk_ioat_req_cb cb_fn,
|
int64_t spdk_ioat_submit_fill(struct spdk_ioat_chan *chan,
|
||||||
|
void *cb_arg, spdk_ioat_req_cb cb_fn,
|
||||||
void *dst, uint64_t fill_pattern, uint64_t nbytes);
|
void *dst, uint64_t fill_pattern, uint64_t nbytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for completed requests on the current thread.
|
* Check for completed requests on an I/OAT channel.
|
||||||
*
|
|
||||||
* Before submitting any requests on a thread, the thread must be registered
|
|
||||||
* using the \ref spdk_ioat_register_thread() function.
|
|
||||||
*
|
*
|
||||||
* \returns 0 on success or negative if something went wrong.
|
* \returns 0 on success or negative if something went wrong.
|
||||||
*/
|
*/
|
||||||
int spdk_ioat_process_events(void);
|
int spdk_ioat_process_events(struct spdk_ioat_chan *chan);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DMA engine capability flags
|
* DMA engine capability flags
|
||||||
@ -146,11 +122,8 @@ enum spdk_ioat_dma_capability_flags {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the DMA engine capabilities.
|
* Get the DMA engine capabilities.
|
||||||
*
|
|
||||||
* Before submitting any requests on a thread, the thread must be registered
|
|
||||||
* using the \ref spdk_ioat_register_thread() function.
|
|
||||||
*/
|
*/
|
||||||
uint32_t spdk_ioat_get_dma_capabilities(void);
|
uint32_t spdk_ioat_get_dma_capabilities(struct spdk_ioat_chan *chan);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -34,15 +34,6 @@
|
|||||||
#include "ioat_internal.h"
|
#include "ioat_internal.h"
|
||||||
#include "ioat_pci.h"
|
#include "ioat_pci.h"
|
||||||
|
|
||||||
/** List of channels that have been attached but are not yet assigned to a thread.
|
|
||||||
*
|
|
||||||
* Must hold g_ioat_driver.lock while manipulating this list.
|
|
||||||
*/
|
|
||||||
static SLIST_HEAD(, spdk_ioat_chan) ioat_free_channels;
|
|
||||||
|
|
||||||
/** IOAT channel assigned to this thread (or NULL if not assigned yet). */
|
|
||||||
static __thread struct spdk_ioat_chan *ioat_thread_channel;
|
|
||||||
|
|
||||||
struct ioat_driver {
|
struct ioat_driver {
|
||||||
ioat_mutex_t lock;
|
ioat_mutex_t lock;
|
||||||
TAILQ_HEAD(, spdk_ioat_chan) attached_chans;
|
TAILQ_HEAD(, spdk_ioat_chan) attached_chans;
|
||||||
@ -488,8 +479,6 @@ ioat_attach(void *device)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLIST_INSERT_HEAD(&ioat_free_channels, ioat, next);
|
|
||||||
|
|
||||||
return ioat;
|
return ioat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,7 +554,6 @@ spdk_ioat_detach(struct spdk_ioat_chan *ioat)
|
|||||||
* when calling ioat_detach().
|
* when calling ioat_detach().
|
||||||
*/
|
*/
|
||||||
ioat_mutex_lock(&driver->lock);
|
ioat_mutex_lock(&driver->lock);
|
||||||
SLIST_REMOVE(&ioat_free_channels, ioat, spdk_ioat_chan, next);
|
|
||||||
TAILQ_REMOVE(&driver->attached_chans, ioat, tailq);
|
TAILQ_REMOVE(&driver->attached_chans, ioat, tailq);
|
||||||
ioat_mutex_unlock(&driver->lock);
|
ioat_mutex_unlock(&driver->lock);
|
||||||
|
|
||||||
@ -575,55 +563,15 @@ spdk_ioat_detach(struct spdk_ioat_chan *ioat)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
spdk_ioat_register_thread(void)
|
|
||||||
{
|
|
||||||
struct ioat_driver *driver = &g_ioat_driver;
|
|
||||||
|
|
||||||
if (ioat_thread_channel) {
|
|
||||||
ioat_printf(NULL, "%s: thread already registered\n", __func__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ioat_mutex_lock(&driver->lock);
|
|
||||||
|
|
||||||
ioat_thread_channel = SLIST_FIRST(&ioat_free_channels);
|
|
||||||
if (ioat_thread_channel) {
|
|
||||||
SLIST_REMOVE_HEAD(&ioat_free_channels, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
ioat_mutex_unlock(&driver->lock);
|
|
||||||
|
|
||||||
return ioat_thread_channel ? 0 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
spdk_ioat_unregister_thread(void)
|
|
||||||
{
|
|
||||||
struct ioat_driver *driver = &g_ioat_driver;
|
|
||||||
|
|
||||||
if (!ioat_thread_channel) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ioat_mutex_lock(&driver->lock);
|
|
||||||
|
|
||||||
SLIST_INSERT_HEAD(&ioat_free_channels, ioat_thread_channel, next);
|
|
||||||
ioat_thread_channel = NULL;
|
|
||||||
|
|
||||||
ioat_mutex_unlock(&driver->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define min(a, b) (((a)<(b))?(a):(b))
|
#define min(a, b) (((a)<(b))?(a):(b))
|
||||||
|
|
||||||
#define _2MB_PAGE(ptr) ((ptr) & ~(0x200000 - 1))
|
#define _2MB_PAGE(ptr) ((ptr) & ~(0x200000 - 1))
|
||||||
#define _2MB_OFFSET(ptr) ((ptr) & (0x200000 - 1))
|
#define _2MB_OFFSET(ptr) ((ptr) & (0x200000 - 1))
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
spdk_ioat_submit_copy(void *cb_arg, spdk_ioat_req_cb cb_fn,
|
spdk_ioat_submit_copy(struct spdk_ioat_chan *ioat, void *cb_arg, spdk_ioat_req_cb cb_fn,
|
||||||
void *dst, const void *src, uint64_t nbytes)
|
void *dst, const void *src, uint64_t nbytes)
|
||||||
{
|
{
|
||||||
struct spdk_ioat_chan *ioat;
|
|
||||||
struct ioat_descriptor *last_desc;
|
struct ioat_descriptor *last_desc;
|
||||||
uint64_t remaining, op_size;
|
uint64_t remaining, op_size;
|
||||||
uint64_t vdst, vsrc;
|
uint64_t vdst, vsrc;
|
||||||
@ -631,7 +579,6 @@ spdk_ioat_submit_copy(void *cb_arg, spdk_ioat_req_cb cb_fn,
|
|||||||
uint64_t pdst_page, psrc_page;
|
uint64_t pdst_page, psrc_page;
|
||||||
uint32_t orig_head;
|
uint32_t orig_head;
|
||||||
|
|
||||||
ioat = ioat_thread_channel;
|
|
||||||
if (!ioat) {
|
if (!ioat) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -698,16 +645,14 @@ spdk_ioat_submit_copy(void *cb_arg, spdk_ioat_req_cb cb_fn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
spdk_ioat_submit_fill(void *cb_arg, spdk_ioat_req_cb cb_fn,
|
spdk_ioat_submit_fill(struct spdk_ioat_chan *ioat, void *cb_arg, spdk_ioat_req_cb cb_fn,
|
||||||
void *dst, uint64_t fill_pattern, uint64_t nbytes)
|
void *dst, uint64_t fill_pattern, uint64_t nbytes)
|
||||||
{
|
{
|
||||||
struct spdk_ioat_chan *ioat;
|
|
||||||
struct ioat_descriptor *last_desc = NULL;
|
struct ioat_descriptor *last_desc = NULL;
|
||||||
uint64_t remaining, op_size;
|
uint64_t remaining, op_size;
|
||||||
uint64_t vdst;
|
uint64_t vdst;
|
||||||
uint32_t orig_head;
|
uint32_t orig_head;
|
||||||
|
|
||||||
ioat = ioat_thread_channel;
|
|
||||||
if (!ioat) {
|
if (!ioat) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -756,11 +701,8 @@ spdk_ioat_submit_fill(void *cb_arg, spdk_ioat_req_cb cb_fn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
spdk_ioat_get_dma_capabilities(void)
|
spdk_ioat_get_dma_capabilities(struct spdk_ioat_chan *ioat)
|
||||||
{
|
{
|
||||||
struct spdk_ioat_chan *ioat;
|
|
||||||
|
|
||||||
ioat = ioat_thread_channel;
|
|
||||||
if (!ioat) {
|
if (!ioat) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -768,11 +710,7 @@ spdk_ioat_get_dma_capabilities(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_ioat_process_events(void)
|
spdk_ioat_process_events(struct spdk_ioat_chan *ioat)
|
||||||
{
|
{
|
||||||
if (!ioat_thread_channel) {
|
return ioat_process_channel_events(ioat);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ioat_process_channel_events(ioat_thread_channel);
|
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,6 @@ struct ioat_descriptor {
|
|||||||
|
|
||||||
/* One of these per allocated PCI device. */
|
/* One of these per allocated PCI device. */
|
||||||
struct spdk_ioat_chan {
|
struct spdk_ioat_chan {
|
||||||
SLIST_ENTRY(spdk_ioat_chan) next;
|
|
||||||
|
|
||||||
/* Opaque handle to upper layer */
|
/* Opaque handle to upper layer */
|
||||||
void *device;
|
void *device;
|
||||||
uint64_t max_xfer_size;
|
uint64_t max_xfer_size;
|
||||||
|
Loading…
Reference in New Issue
Block a user