examples/nvme/hotplug: simplify buffer management

We don't need to allocate/free tasks on every I/O; we can just
allocate the tasks and buffers once in the initial submit_io() loop.

This also removes the remaining direct DPDK calls from the hotplug
example.

Change-Id: Ie8774b289e650b3fa64614f2da0efbefd013a610
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/376864
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Daniel Verkamp 2017-09-01 16:55:15 -07:00 committed by Jim Harris
parent 7fc4405c5d
commit 455525f5a0

View File

@ -33,9 +33,6 @@
#include "spdk/stdinc.h" #include "spdk/stdinc.h"
#include <rte_config.h>
#include <rte_mempool.h>
#include "spdk/nvme.h" #include "spdk/nvme.h"
#include "spdk/queue.h" #include "spdk/queue.h"
@ -61,8 +58,6 @@ struct perf_task {
void *buf; void *buf;
}; };
static struct rte_mempool *task_pool;
static TAILQ_HEAD(, dev_ctx) g_devs = TAILQ_HEAD_INITIALIZER(g_devs); static TAILQ_HEAD(, dev_ctx) g_devs = TAILQ_HEAD_INITIALIZER(g_devs);
static uint64_t g_tsc_rate; static uint64_t g_tsc_rate;
@ -144,33 +139,42 @@ unregister_dev(struct dev_ctx *dev)
free(dev); free(dev);
} }
static void task_ctor(struct rte_mempool *mp, void *arg, void *__task, unsigned id) static struct perf_task *
alloc_task(struct dev_ctx *dev)
{ {
struct perf_task *task = __task; struct perf_task *task;
task = calloc(1, sizeof(*task));
if (task == NULL) {
return NULL;
}
task->buf = spdk_dma_zmalloc(g_io_size_bytes, 0x200, NULL); task->buf = spdk_dma_zmalloc(g_io_size_bytes, 0x200, NULL);
if (task->buf == NULL) { if (task->buf == NULL) {
fprintf(stderr, "task->buf rte_malloc failed\n"); return NULL;
exit(1);
} }
memset(task->buf, id % 8, g_io_size_bytes);
task->dev = dev;
return task;
}
static void
free_task(struct perf_task *task)
{
spdk_dma_free(task->buf);
free(task);
} }
static void io_complete(void *ctx, const struct spdk_nvme_cpl *completion); static void io_complete(void *ctx, const struct spdk_nvme_cpl *completion);
static void static void
submit_single_io(struct dev_ctx *dev) submit_single_io(struct perf_task *task)
{ {
struct perf_task *task = NULL; struct dev_ctx *dev = task->dev;
uint64_t offset_in_ios; uint64_t offset_in_ios;
int rc; int rc;
if (rte_mempool_get(task_pool, (void **)&task) != 0) {
fprintf(stderr, "task_pool rte_mempool_get failed\n");
exit(1);
}
task->dev = dev;
offset_in_ios = dev->offset_in_ios++; offset_in_ios = dev->offset_in_ios++;
if (dev->offset_in_ios == dev->size_in_ios) { if (dev->offset_in_ios == dev->size_in_ios) {
dev->offset_in_ios = 0; dev->offset_in_ios = 0;
@ -182,7 +186,7 @@ submit_single_io(struct dev_ctx *dev)
if (rc != 0) { if (rc != 0) {
fprintf(stderr, "starting I/O failed\n"); fprintf(stderr, "starting I/O failed\n");
rte_mempool_put(task_pool, task); free_task(task);
} else { } else {
dev->current_queue_depth++; dev->current_queue_depth++;
} }
@ -197,8 +201,6 @@ task_complete(struct perf_task *task)
dev->current_queue_depth--; dev->current_queue_depth--;
dev->io_completed++; dev->io_completed++;
rte_mempool_put(task_pool, task);
/* /*
* is_draining indicates when time has expired for the test run * is_draining indicates when time has expired for the test run
* and we are just waiting for the previously submitted I/O * and we are just waiting for the previously submitted I/O
@ -206,7 +208,9 @@ task_complete(struct perf_task *task)
* the one just completed. * the one just completed.
*/ */
if (!dev->is_draining && !dev->is_removed) { if (!dev->is_draining && !dev->is_removed) {
submit_single_io(dev); submit_single_io(task);
} else {
free_task(task);
} }
} }
@ -225,8 +229,16 @@ check_io(struct dev_ctx *dev)
static void static void
submit_io(struct dev_ctx *dev, int queue_depth) submit_io(struct dev_ctx *dev, int queue_depth)
{ {
struct perf_task *task;
while (queue_depth-- > 0) { while (queue_depth-- > 0) {
submit_single_io(dev); task = alloc_task(dev);
if (task == NULL) {
fprintf(stderr, "task allocation failed\n");
exit(1);
}
submit_single_io(task);
} }
} }
@ -449,11 +461,6 @@ int main(int argc, char **argv)
} }
spdk_env_init(&opts); spdk_env_init(&opts);
task_pool = rte_mempool_create("task_pool", 8192,
sizeof(struct perf_task),
64, 0, NULL, NULL, task_ctor, NULL,
SOCKET_ID_ANY, 0);
g_tsc_rate = spdk_get_ticks_hz(); g_tsc_rate = spdk_get_ticks_hz();
/* Detect the controllers that are plugged in at startup. */ /* Detect the controllers that are plugged in at startup. */