env: Move DPDK intialization into the env library.

Change-Id: Ie3a324f1523ffa0ddb0bd6a24a9a3cd0acbf64b0
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Ben Walker 2017-01-12 11:25:17 -07:00 committed by Daniel Verkamp
parent 25270f1d7c
commit 18d26e42a3
27 changed files with 480 additions and 550 deletions

View File

@ -372,9 +372,8 @@ This is the main file.
\msc
c_runtime [label="C Runtime"], dpdk [label="DPDK"], nvmf [label="NVMf target"];
c_runtime [label="C Runtime"], nvmf [label="NVMf target"];
c_runtime=>nvmf [label="main()"];
nvmf=> [label="rte_eal_init()"];
nvmf=>nvmf [label="spdk_app_init()"];
nvmf=>nvmf [label="spdk_event_allocate()"];
nvmf=>nvmf [label="spdk_app_start()"];

View File

@ -398,22 +398,12 @@ work_fn(void *arg)
static int
init(void)
{
char *core_mask_conf;
struct spdk_env_opts opts;
core_mask_conf = spdk_sprintf_alloc("-c %s", g_user_config.core_mask);
if (!core_mask_conf) {
return 1;
}
char *ealargs[] = {"perf", core_mask_conf, "-n 4"};
if (rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), ealargs) < 0) {
free(core_mask_conf);
fprintf(stderr, "Could not init eal\n");
return 1;
}
free(core_mask_conf);
spdk_env_opts_init(&opts);
opts.name = "perf";
opts.core_mask = g_user_config.core_mask;
spdk_env_init(&opts);
return 0;
}

View File

@ -379,21 +379,12 @@ init_src_buffer(void)
static int
init(void)
{
char *core_mask_conf;
struct spdk_env_opts opts;
core_mask_conf = spdk_sprintf_alloc("-c %s", g_user_config.core_mask);
if (!core_mask_conf) {
return 1;
}
char *ealargs[] = {"verify", core_mask_conf, "-n 4"};
if (rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), ealargs) < 0) {
free(core_mask_conf);
fprintf(stderr, "Could not init eal\n");
return 1;
}
free(core_mask_conf);
spdk_env_opts_init(&opts);
opts.name = "verify";
opts.core_mask = g_user_config.core_mask;
spdk_env_init(&opts);
if (init_src_buffer() != 0) {
fprintf(stderr, "Could not init src buffer\n");

View File

@ -133,6 +133,7 @@ static struct arb_context g_arbitration = {
.arbitration_config = 0,
.io_size_bytes = 131072,
.max_completions = 0,
/* Default 4 cores for urgent/high/medium/low */
.core_mask = "0xf",
.workload_type = "randrw",
};
@ -1080,18 +1081,6 @@ set_arb_feature(struct spdk_nvme_ctrlr *ctrlr)
return 0;
}
static char *ealargs[] = {
"arb",
"-c 0xf", /* This must be the second parameter. It is overwritten by index in main(). */
"-n 4",
"--proc-type=auto",
#ifdef __linux__
"--base-virtaddr=0x1000000000",
"", /* May be replaced by --file-prefix */
#endif
};
int
main(int argc, char **argv)
{
@ -1099,45 +1088,18 @@ main(int argc, char **argv)
struct worker_thread *worker;
char task_pool_name[30];
uint32_t task_count;
size_t argcount;
char *core_mask = NULL;
char *file_prefix = NULL;
struct spdk_env_opts opts;
rc = parse_args(argc, argv);
if (rc != 0) {
return rc;
}
/* Default 4 cores for (urgent / high / medium / low) 4 kinds of queues respectively */
ealargs[1] = core_mask = spdk_sprintf_alloc("-c %s", g_arbitration.core_mask);
if (ealargs[1] == NULL) {
perror("ealargs spdk_sprintf_alloc");
return 1;
}
argcount = (sizeof(ealargs) / sizeof(ealargs[0])) - 1;
#ifdef __linux__
if (g_arbitration.shm_id >= 0) {
ealargs[5] = file_prefix = spdk_sprintf_alloc("--file-prefix=spdk%d",
g_arbitration.shm_id);
argcount++;
}
#endif
rc = rte_eal_init(argcount, ealargs);
free(core_mask);
if (file_prefix) {
free(file_prefix);
}
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
return 1;
}
spdk_env_opts_init(&opts);
opts.name = "arb";
opts.core_mask = g_arbitration.core_mask;
opts.shm_id = g_arbitration.shm_id;
spdk_env_init(&opts);
g_arbitration.tsc_rate = spdk_get_ticks_hz();

View File

@ -37,9 +37,6 @@
#include <assert.h>
#include <pthread.h>
#include "rte_config.h"
#include "rte_eal.h"
#include "spdk/nvme.h"
#include "spdk/env.h"
#include "spdk/string.h"
@ -175,19 +172,13 @@ attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
}
}
static char *ealargs[] = {
"fio",
"-n 4",
"--proc-type=auto",
};
/* Called once at initialization. This is responsible for gathering the size of
* each "file", which in our case are in the form
* "05:00.0/0" (PCI bus:device.function/NVMe NSID) */
static int spdk_fio_setup(struct thread_data *td)
{
int rc;
struct spdk_fio_thread *fio_thread;
struct spdk_env_opts opts;
fio_thread = calloc(1, sizeof(*fio_thread));
assert(fio_thread != NULL);
@ -198,11 +189,9 @@ static int spdk_fio_setup(struct thread_data *td)
fio_thread->iocq = calloc(td->o.iodepth + 1, sizeof(struct io_u *));
assert(fio_thread->iocq != NULL);
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), ealargs);
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
return 1;
}
spdk_env_opts_init(&opts);
opts.name = "fio";
spdk_env_init(&opts);
/* Enumerate all of the controllers */
if (spdk_nvme_probe(NULL, td, probe_cb, attach_cb, NULL) != 0) {

View File

@ -36,9 +36,6 @@
#include <string.h>
#include <unistd.h>
#include <rte_config.h>
#include <rte_eal.h>
#include "spdk/nvme.h"
#include "spdk/env.h"
@ -304,32 +301,20 @@ cleanup(void)
}
}
static char *ealargs[] = {
"hello_world",
"-c 0x1",
"-n 4",
"--proc-type=auto",
};
int main(int argc, char **argv)
{
int rc;
struct spdk_env_opts opts;
/*
* By default, the SPDK NVMe driver uses DPDK for huge page-based
* memory management and NVMe request buffer pools. Huge pages can
* be either 2MB or 1GB in size (instead of 4KB) and are pinned in
* memory. Pinned memory is important to ensure DMA operations
* never target swapped out memory.
* SPDK relies on an abstraction around the local environment
* named env that handles memory allocation and PCI device operations.
* This library must be initialized first.
*
* So first we must initialize DPDK. "-c 0x1" indicates to only use
* core 0.
*/
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), ealargs);
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
return 1;
}
spdk_env_opts_init(&opts);
opts.name = "hello_world";
spdk_env_init(&opts);
printf("Initializing NVMe Controllers\n");

View File

@ -81,6 +81,7 @@ static int g_expected_insert_times = -1;
static int g_expected_removal_times = -1;
static int g_insert_times;
static int g_removal_times;
static int g_shm_id = -1;
static void
task_complete(struct perf_task *task);
@ -376,7 +377,8 @@ static void usage(char *program_name)
{
printf("%s options", program_name);
printf("\n");
printf("\t[-i expected hot insert times]\n");
printf("\t[-i shm id (optional)]\n");
printf("\t[-n expected hot insert times]\n");
printf("\t[-r expected hot removal times]\n");
printf("\t[-t time in seconds]\n");
}
@ -389,9 +391,12 @@ parse_args(int argc, char **argv)
/* default value*/
g_time_in_sec = 0;
while ((op = getopt(argc, argv, "i:r:t:")) != -1) {
while ((op = getopt(argc, argv, "i:n:r:t:")) != -1) {
switch (op) {
case 'i':
g_shm_id = atoi(optarg);
break;
case 'n':
g_expected_insert_times = atoi(optarg);
break;
case 'r':
@ -430,26 +435,23 @@ register_controllers(void)
return 0;
}
static char *ealargs[] = {
"hotplug",
"-c 0x1",
"-n 4",
};
int main(int argc, char **argv)
{
int rc;
struct spdk_env_opts opts;
rc = parse_args(argc, argv);
if (rc != 0) {
return rc;
}
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), ealargs);
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
return 1;
spdk_env_opts_init(&opts);
opts.name = "hotplug";
opts.core_mask = "0x1";
if (g_shm_id > -1) {
opts.shm_id = g_shm_id;
}
spdk_env_init(&opts);
task_pool = rte_mempool_create("task_pool", 8192,
sizeof(struct perf_task),

View File

@ -950,31 +950,21 @@ attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
spdk_nvme_detach(ctrlr);
}
static const char *ealargs[] = {
"identify",
"-c 0x1",
"-n 4",
"-m 512",
"--proc-type=auto",
};
int main(int argc, char **argv)
{
int rc;
struct spdk_env_opts opts;
spdk_env_opts_init(&opts);
opts.name = "identify";
opts.core_mask = "0x1";
spdk_env_init(&opts);
rc = parse_args(argc, argv);
if (rc != 0) {
return rc;
}
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]),
(char **)(void *)(uintptr_t)ealargs);
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
exit(1);
}
rc = 0;
if (spdk_nvme_probe(&g_trid, NULL, probe_cb, attach_cb, NULL) != 0) {
fprintf(stderr, "spdk_nvme_probe() failed\n");

View File

@ -138,13 +138,6 @@ attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
}
}
static const char *ealargs[] = {
"nvme_manage",
"-c 0x1",
"-n 4",
"--proc-type=auto",
};
static void usage(void)
{
printf("NVMe Management Options");
@ -843,15 +836,13 @@ update_firmware_image(void)
int main(int argc, char **argv)
{
int rc, i;
int i;
struct spdk_env_opts opts;
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]),
(char **)(void *)(uintptr_t)ealargs);
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
exit(1);
}
spdk_env_opts_init(&opts);
opts.name = "nvme_manage";
opts.core_mask = "0x1";
spdk_env_init(&opts);
if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) {
fprintf(stderr, "spdk_nvme_probe() failed\n");
@ -917,5 +908,5 @@ int main(int argc, char **argv)
spdk_nvme_detach(dev->ctrlr);
}
return rc;
return 0;
}

View File

@ -1193,71 +1193,30 @@ associate_workers_with_ns(void)
return 0;
}
static char *ealargs[] = {
"perf",
"-c 0x1", /* This must be the second parameter. It is overwritten by index in main(). */
"-n 4",
"-m 512", /* This can be overwritten by index in main(). */
"--proc-type=auto",
#ifdef __linux__
"--base-virtaddr=0x1000000000",
"", /* May be replaced by --file-prefix */
#endif
};
int main(int argc, char **argv)
{
int rc;
struct worker_thread *worker;
char task_pool_name[30];
uint32_t task_count;
size_t argcount;
char *core_mask = NULL;
char *mem_size = NULL;
char *file_prefix = NULL;
struct spdk_env_opts opts;
rc = parse_args(argc, argv);
if (rc != 0) {
return rc;
}
ealargs[1] = core_mask = spdk_sprintf_alloc("-c %s", g_core_mask ? g_core_mask : "0x1");
if (ealargs[1] == NULL) {
perror("ealargs spdk_sprintf_alloc");
return 1;
spdk_env_opts_init(&opts);
opts.name = "perf";
opts.shm_id = g_shm_id;
if (g_core_mask) {
opts.core_mask = g_core_mask;
}
ealargs[3] = mem_size = spdk_sprintf_alloc("-m %d", g_dpdk_mem ? g_dpdk_mem : 512);
if (ealargs[3] == NULL) {
free(ealargs[1]);
perror("ealargs spdk_sprintf_alloc");
return 1;
}
argcount = (sizeof(ealargs) / sizeof(ealargs[0])) - 1;
#ifdef __linux__
if (g_shm_id >= 0) {
ealargs[6] = file_prefix = spdk_sprintf_alloc("--file-prefix=spdk%d",
g_shm_id);
argcount++;
}
#endif
rc = rte_eal_init(argcount, ealargs);
free(core_mask);
free(mem_size);
if (file_prefix) {
free(file_prefix);
}
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
return 1;
if (g_dpdk_mem) {
opts.dpdk_mem_size = g_dpdk_mem;
}
spdk_env_init(&opts);
g_tsc_rate = spdk_get_ticks_hz();

View File

@ -380,25 +380,16 @@ attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
dev->ctrlr = ctrlr;
}
static const char *ealargs[] = {
"reserve",
"-c 0x1",
"-n 4",
"--proc-type=auto",
};
int main(int argc, char **argv)
{
struct dev *iter;
int rc, i;
struct dev *iter;
int rc, i;
struct spdk_env_opts opts;
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]),
(char **)(void *)(uintptr_t)ealargs);
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
exit(1);
}
spdk_env_opts_init(&opts);
opts.name = "reserve";
opts.core_mask = "0x1";
spdk_env_init(&opts);
if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) {
fprintf(stderr, "spdk_nvme_probe() failed\n");

View File

@ -51,6 +51,29 @@ extern "C" {
struct spdk_pci_device;
/**
* \brief Environment initialization options
*/
struct spdk_env_opts {
const char *name;
const char *core_mask;
int shm_id;
int dpdk_mem_channel;
int dpdk_master_core;
int dpdk_mem_size;
};
/**
* \brief Initialize the default value of opts
*/
void spdk_env_opts_init(struct spdk_env_opts *opts);
/**
* \brief Initialize the environment library. This must be called prior to using
* any other functions in this library.
*/
void spdk_env_init(const struct spdk_env_opts *opts);
/**
* Allocate a pinned, physically contiguous memory buffer with the
* given size and alignment.

View File

@ -81,8 +81,8 @@ struct spdk_app_opts {
spdk_sighandler_t usr1_handler;
bool enable_coredump;
uint32_t dpdk_mem_channel;
uint32_t dpdk_master_core;
int dpdk_mem_channel;
int dpdk_master_core;
int dpdk_mem_size;
/* The maximum latency allowed when passing an event
@ -98,11 +98,6 @@ struct spdk_app_opts {
*/
void spdk_app_opts_init(struct spdk_app_opts *opts);
/**
* \brief Initialize DPDK via opts.
*/
void spdk_dpdk_framework_init(struct spdk_app_opts *opts);
/**
* \brief Initialize an application to use the event framework. This must be called prior to using
* any other functions in this library.

View File

@ -34,8 +34,8 @@
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
CFLAGS += $(DPDK_INC)
C_SRCS = env.c pci.c vtophys.c
CFLAGS += $(ENV_CFLAGS)
C_SRCS = env.c pci.c vtophys.c init.c
C_SRCS += pci_nvme.c pci_ioat.c
LIBNAME = env_dpdk

312
lib/env_dpdk/init.c Normal file
View File

@ -0,0 +1,312 @@
/*-
* BSD LICENSE
*
* Copyright (c) Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "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 THE COPYRIGHT
* OWNER OR CONTRIBUTORS 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.
*/
#include "spdk/env.h"
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <rte_config.h>
#include <rte_eal.h>
#define SPDK_ENV_DPDK_DEFAULT_NAME "spdk"
#define SPDK_ENV_DPDK_DEFAULT_SHM_ID -1
#define SPDK_ENV_DPDK_DEFAULT_MEM_SIZE -1
#define SPDK_ENV_DPDK_DEFAULT_MASTER_CORE -1
#define SPDK_ENV_DPDK_DEFAULT_MEM_CHANNEL -1
#define SPDK_ENV_DPDK_DEFAULT_CORE_MASK "0x1"
static char *
_sprintf_alloc(const char *format, ...)
{
va_list args;
va_list args_copy;
char *buf;
size_t bufsize;
int rc;
va_start(args, format);
/* Try with a small buffer first. */
bufsize = 32;
/* Limit maximum buffer size to something reasonable so we don't loop forever. */
while (bufsize <= 1024 * 1024) {
buf = malloc(bufsize);
if (buf == NULL) {
va_end(args);
return NULL;
}
va_copy(args_copy, args);
rc = vsnprintf(buf, bufsize, format, args_copy);
va_end(args_copy);
/*
* If vsnprintf() returned a count within our current buffer size, we are done.
* The count does not include the \0 terminator, so rc == bufsize is not OK.
*/
if (rc >= 0 && (size_t)rc < bufsize) {
va_end(args);
return buf;
}
/*
* vsnprintf() should return the required space, but some libc versions do not
* implement this correctly, so just double the buffer size and try again.
*
* We don't need the data in buf, so rather than realloc(), use free() and malloc()
* again to avoid a copy.
*/
free(buf);
bufsize *= 2;
}
va_end(args);
return NULL;
}
void
spdk_env_opts_init(struct spdk_env_opts *opts)
{
if (!opts) {
return;
}
memset(opts, 0, sizeof(*opts));
opts->name = SPDK_ENV_DPDK_DEFAULT_NAME;
opts->core_mask = SPDK_ENV_DPDK_DEFAULT_CORE_MASK;
opts->shm_id = SPDK_ENV_DPDK_DEFAULT_SHM_ID;
opts->dpdk_mem_size = SPDK_ENV_DPDK_DEFAULT_MEM_SIZE;
opts->dpdk_master_core = SPDK_ENV_DPDK_DEFAULT_MASTER_CORE;
opts->dpdk_mem_channel = SPDK_ENV_DPDK_DEFAULT_MEM_CHANNEL;
}
static void
spdk_free_args(char **args, int argcount)
{
int i;
assert(args != NULL);
for (i = 0; i < argcount; i++) {
assert(args[i] != NULL);
free(args[i]);
}
free(args);
}
static char **
spdk_push_arg(char *args[], int *argcount, char *arg)
{
char **tmp;
if (arg == NULL) {
return NULL;
}
tmp = realloc(args, sizeof(char *) * (*argcount + 1));
if (tmp == NULL) {
spdk_free_args(args, *argcount);
return NULL;
}
tmp[*argcount] = arg;
(*argcount)++;
return tmp;
}
static unsigned long long
spdk_get_coremask(const char *coremask)
{
unsigned long long core_mask, max_coremask = 0;
int num_cores_online;
num_cores_online = sysconf(_SC_NPROCESSORS_ONLN);
if (num_cores_online > 0) {
if (num_cores_online > RTE_MAX_LCORE) {
num_cores_online = RTE_MAX_LCORE;
}
if (num_cores_online >= 64) {
max_coremask = ~0ULL;
} else {
max_coremask = (1ULL << num_cores_online) - 1;
}
}
core_mask = strtoull(coremask, NULL, 16);
core_mask &= max_coremask;
return core_mask;
}
static int
spdk_build_eal_cmdline(const struct spdk_env_opts *opts, char **out[])
{
unsigned long long core_mask;
int argcount = 0;
char **args;
if (out == NULL) {
return -1;
}
*out = NULL;
args = NULL;
/* set the program name */
args = spdk_push_arg(args, &argcount, _sprintf_alloc("%s", opts->name));
if (args == NULL) {
return -1;
}
/* set the coremask */
core_mask = spdk_get_coremask(opts->core_mask);
if (core_mask == 0) {
spdk_free_args(args, argcount);
return -1;
}
args = spdk_push_arg(args, &argcount, _sprintf_alloc("-c %llx", core_mask));
if (args == NULL) {
return -1;
}
/* set the memory channel number */
if (opts->dpdk_mem_channel > 0) {
args = spdk_push_arg(args, &argcount, _sprintf_alloc("-n %d", opts->dpdk_mem_channel));
if (args == NULL) {
return -1;
}
}
/* set the memory size */
if (opts->dpdk_mem_size > 0) {
args = spdk_push_arg(args, &argcount, _sprintf_alloc("-m %d", opts->dpdk_mem_size));
if (args == NULL) {
return -1;
}
}
/* set the master core */
if (opts->dpdk_master_core > 0) {
args = spdk_push_arg(args, &argcount, _sprintf_alloc("--master-lcore=%d",
opts->dpdk_master_core));
if (args == NULL) {
return -1;
}
}
#ifdef __linux__
if (opts->shm_id < 0) {
args = spdk_push_arg(args, &argcount, _sprintf_alloc("--file-prefix=spdk_pid%d",
getpid()));
if (args == NULL) {
return -1;
}
} else {
args = spdk_push_arg(args, &argcount, _sprintf_alloc("--file-prefix=spdk%d",
opts->shm_id));
if (args == NULL) {
return -1;
}
}
/* set the base virtual address */
args = spdk_push_arg(args, &argcount, _sprintf_alloc("--base-virtaddr=0x1000000000"));
if (args == NULL) {
return -1;
}
/* set the process type */
args = spdk_push_arg(args, &argcount, _sprintf_alloc("--proc-type=auto"));
if (args == NULL) {
return -1;
}
#endif
*out = args;
return argcount;
}
void spdk_env_init(const struct spdk_env_opts *opts)
{
char **args = NULL;
char **dpdk_args = NULL;
int argcount, i, rc;
argcount = spdk_build_eal_cmdline(opts, &args);
if (argcount <= 0) {
fprintf(stderr, "Invalid arguments to initialize DPDK\n");
exit(-1);
}
printf("Starting Intel(R) DPDK initialization ... \n");
printf("[ DPDK EAL parameters: ");
for (i = 0; i < argcount; i++) {
printf("%s ", args[i]);
}
printf("]\n");
/* DPDK rearranges the array we pass to it, so make a copy
* before passing so we can still free the individual strings
* correctly.
*/
dpdk_args = calloc(argcount, sizeof(char *));
memcpy(dpdk_args, args, sizeof(char *) * argcount);
fflush(stdout);
rc = rte_eal_init(argcount, dpdk_args);
spdk_free_args(args, argcount);
free(dpdk_args);
if (rc < 0) {
fprintf(stderr, "Failed to initialize DPDK\n");
exit(-1);
}
}

View File

@ -38,7 +38,6 @@
#include <pthread.h>
#include <rte_config.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include "spdk/env.h"

View File

@ -36,7 +36,7 @@ include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
CFLAGS += $(ENV_CFLAGS)
LIBNAME = event
C_SRCS = app.c dpdk_init.c reactor.c subsystem.c
C_SRCS = app.c reactor.c subsystem.c
DIRS-y = rpc

View File

@ -49,6 +49,7 @@
#include <rte_config.h>
#include <rte_lcore.h>
#include "spdk/env.h"
#include "spdk/log.h"
#include "spdk/conf.h"
#include "spdk/trace.h"
@ -56,9 +57,9 @@
#define SPDK_APP_DEFAULT_LOG_FACILITY "local7"
#define SPDK_APP_DEFAULT_LOG_PRIORITY "info"
#define SPDK_APP_DPDK_DEFAULT_MEM_SIZE 2048
#define SPDK_APP_DPDK_DEFAULT_MASTER_CORE 0
#define SPDK_APP_DPDK_DEFAULT_MEM_CHANNEL 4
#define SPDK_APP_DPDK_DEFAULT_MEM_SIZE -1
#define SPDK_APP_DPDK_DEFAULT_MASTER_CORE -1
#define SPDK_APP_DPDK_DEFAULT_MEM_CHANNEL -1
#define SPDK_APP_DPDK_DEFAULT_CORE_MASK "0x1"
/* Add enough here to append ".pid" plus 2 digit instance ID */
@ -243,6 +244,7 @@ spdk_app_init(struct spdk_app_opts *opts)
int rc;
uint64_t tpoint_group_mask;
char *end;
struct spdk_env_opts env_opts = {};
if (opts->enable_coredump) {
struct rlimit core_limits;
@ -279,6 +281,13 @@ spdk_app_init(struct spdk_app_opts *opts)
opts->shm_id = getpid();
}
if (opts->shm_id == -1) {
sp = spdk_conf_find_section(config, "Global");
if (sp != NULL) {
opts->shm_id = spdk_conf_section_get_intval(sp, "MultiprocessGroupID");
}
}
memset(&g_spdk_app, 0, sizeof(g_spdk_app));
g_spdk_app.config = config;
g_spdk_app.shm_id = opts->shm_id;
@ -324,7 +333,16 @@ spdk_app_init(struct spdk_app_opts *opts)
}
}
spdk_dpdk_framework_init(opts);
spdk_env_opts_init(&env_opts);
env_opts.name = opts->name;
env_opts.core_mask = opts->reactor_mask;
env_opts.shm_id = opts->shm_id;
env_opts.dpdk_mem_channel = opts->dpdk_mem_channel;
env_opts.dpdk_master_core = opts->dpdk_master_core;
env_opts.dpdk_mem_size = opts->dpdk_mem_size;
spdk_env_init(&env_opts);
/*
* If mask not specified on command line or in configuration file,

View File

@ -1,211 +0,0 @@
/*-
* BSD LICENSE
*
* Copyright (c) Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "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 THE COPYRIGHT
* OWNER OR CONTRIBUTORS 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.
*/
#include "spdk/event.h"
#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <rte_config.h>
#include <rte_per_lcore.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_common.h>
#include "spdk/string.h"
enum dpdk_eal_args {
EAL_PROGNAME_ARG = 0,
EAL_COREMASK_ARG,
EAL_MEMCHAN_ARG,
EAL_MEMSIZE_ARG,
EAL_MASTER_CORE_ARG,
EAL_FILE_PREFIX_ARG,
EAL_PROC_TYPE_ARG,
EAL_ARG_COUNT
};
/* g_arg_strings contains the original pointers allocated via
* spdk_sprintf_alloc(). These pointers are copied to g_ealargs
* for passing to DPDK rte_eal_init(). Since DPDK may modify the
* pointer values, we use g_arg_strings() to free the strings after
* rte_eal_init() completes.
*/
static char *g_arg_strings[EAL_ARG_COUNT];
static char *g_ealargs[EAL_ARG_COUNT];
static void
spdk_free_ealargs(void)
{
int i;
for (i = 0; i < EAL_ARG_COUNT; i++)
free(g_arg_strings[i]);
}
static unsigned long long
spdk_get_eal_coremask(const char *coremask)
{
unsigned long long core_mask, max_coremask = 0;
int num_cores_online;
num_cores_online = sysconf(_SC_NPROCESSORS_ONLN);
if (num_cores_online > 0) {
if (num_cores_online > RTE_MAX_LCORE) {
num_cores_online = RTE_MAX_LCORE;
}
if (num_cores_online >= 64) {
max_coremask = ~0ULL;
} else {
max_coremask = (1ULL << num_cores_online) - 1;
}
}
core_mask = strtoull(coremask, NULL, 16);
core_mask &= max_coremask;
return core_mask;
}
static void
spdk_build_eal_cmdline(struct spdk_app_opts *opts)
{
unsigned long long core_mask;
/* set the program name */
g_arg_strings[EAL_PROGNAME_ARG] = spdk_sprintf_alloc("%s", opts->name);
if (g_arg_strings[EAL_PROGNAME_ARG] == NULL) {
rte_exit(EXIT_FAILURE, "g_arg_strings spdk_sprintf_alloc");
}
/*set the coremask */
core_mask = spdk_get_eal_coremask(opts->reactor_mask);
g_arg_strings[EAL_COREMASK_ARG] = spdk_sprintf_alloc("-c %llx", core_mask);
if (g_arg_strings[EAL_COREMASK_ARG] == NULL) {
spdk_free_ealargs();
rte_exit(EXIT_FAILURE, "g_arg_strings spdk_sprintf_alloc");
}
/* set the memory channel number */
g_arg_strings[EAL_MEMCHAN_ARG] = spdk_sprintf_alloc("-n %d", opts->dpdk_mem_channel);
if (g_arg_strings[EAL_MEMCHAN_ARG] == NULL) {
spdk_free_ealargs();
rte_exit(EXIT_FAILURE, "g_arg_strings spdk_sprintf_alloc");
}
/* set the memory size */
g_arg_strings[EAL_MEMSIZE_ARG] = spdk_sprintf_alloc("-m %d", opts->dpdk_mem_size);
if (g_arg_strings[EAL_MEMSIZE_ARG] == NULL) {
spdk_free_ealargs();
rte_exit(EXIT_FAILURE, "g_arg_strings spdk_sprintf_alloc");
}
/* set the master core */
g_arg_strings[EAL_MASTER_CORE_ARG] = spdk_sprintf_alloc("--master-lcore=%d",
opts->dpdk_master_core);
if (g_arg_strings[EAL_MASTER_CORE_ARG] == NULL) {
spdk_free_ealargs();
rte_exit(EXIT_FAILURE, "g_arg_strings spdk_sprintf_alloc");
}
#ifdef __linux__
/* set the hugepage file prefix */
g_arg_strings[EAL_FILE_PREFIX_ARG] = spdk_sprintf_alloc("--file-prefix=spdk%d",
opts->shm_id);
#else
/* --file-prefix is not required on FreeBSD */
g_arg_strings[EAL_FILE_PREFIX_ARG] = strdup("");
#endif
if (g_arg_strings[EAL_FILE_PREFIX_ARG] == NULL) {
spdk_free_ealargs();
rte_exit(EXIT_FAILURE, "ealargs spdk_sprintf_alloc");
}
#ifdef __linux__
/* set the process type */
g_arg_strings[EAL_PROC_TYPE_ARG] = spdk_sprintf_alloc("--proc-type=auto");
#else
/* --proc-type is not required on FreeBSD */
/* TODO: to enable the support on FreeBSD once it supports process shared mutex */
g_arg_strings[EAL_PROC_TYPE_ARG] = strdup("");
#endif
if (g_arg_strings[EAL_PROC_TYPE_ARG] == NULL) {
spdk_free_ealargs();
rte_exit(EXIT_FAILURE, "ealargs spdk_sprintf_alloc");
}
memcpy(g_ealargs, g_arg_strings, sizeof(g_arg_strings));
}
static void
spdk_init_dpdk(struct spdk_app_opts *opts)
{
int i, rc;
static bool g_dpdk_initialized = false;
/* to make sure DPDK is only initialized once */
if (g_dpdk_initialized)
rte_exit(EXIT_FAILURE, "DPDK is already initialized\n");
spdk_build_eal_cmdline(opts);
printf("Starting Intel(R) DPDK initialization ... \n");
printf("[ DPDK EAL parameters: ");
for (i = 0; i < EAL_ARG_COUNT; i++) {
printf("%s ", g_ealargs[i]);
}
printf("]\n");
fflush(stdout);
rc = rte_eal_init(EAL_ARG_COUNT, g_ealargs);
spdk_free_ealargs();
if (rc < 0)
rte_exit(EXIT_FAILURE, "Invalid EAL arguments for DPDK\n");
g_dpdk_initialized = true;
printf("done.\n");
}
__attribute__((weak))
void spdk_dpdk_framework_init(struct spdk_app_opts *opts)
{
spdk_init_dpdk(opts);
}

View File

@ -36,17 +36,8 @@
#include <stdlib.h>
#include <string.h>
#include <rte_config.h>
#include <rte_eal.h>
#include "spdk/env.h"
static const char *ealargs[] = {
"vtophys",
"-c 0x1",
"-n 4",
};
static int
vtophys_negative_test(void)
{
@ -122,15 +113,13 @@ vtophys_positive_test(void)
int
main(int argc, char **argv)
{
int rc;
int rc;
struct spdk_env_opts opts;
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]),
(char **)(void *)(uintptr_t)ealargs);
if (rc < 0) {
fprintf(stderr, "Could not init eal\n");
exit(1);
}
spdk_env_opts_init(&opts);
opts.name = "vtophys";
opts.core_mask = "0x1";
spdk_env_init(&opts);
rc = vtophys_negative_test();
if (rc < 0)

View File

@ -38,7 +38,6 @@
#include <unistd.h>
#include <rte_config.h>
#include <rte_eal.h>
#include <rte_ring.h>
#include <rte_lcore.h>

View File

@ -216,27 +216,19 @@ attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
}
}
static const char *ealargs[] = {
"aer",
"-c 0x1",
"-n 4",
};
int main(int argc, char **argv)
{
struct dev *dev;
int rc, i;
struct dev *dev;
int i;
struct spdk_env_opts opts;
spdk_env_opts_init(&opts);
opts.name = "aer";
opts.core_mask = "0x1";
spdk_env_init(&opts);
printf("Asynchronous Event Request test\n");
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]),
(char **)(void *)(uintptr_t)ealargs);
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
exit(1);
}
if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) {
fprintf(stderr, "spdk_nvme_probe() failed\n");
return 1;

View File

@ -631,28 +631,19 @@ attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
printf("Attached to %s\n", dev->name);
}
static const char *ealargs[] = {
"nvme_dp",
"-c 0x1",
"-n 4",
};
int main(int argc, char **argv)
{
struct dev *iter;
int rc, i;
struct dev *iter;
int rc, i;
struct spdk_env_opts opts;
spdk_env_opts_init(&opts);
opts.name = "nvme_dp";
opts.core_mask = "0x1";
spdk_env_init(&opts);
printf("NVMe Write/Read with End-to-End data protection test\n");
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]),
(char **)(void *)(uintptr_t)ealargs);
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
exit(1);
}
if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) {
fprintf(stderr, "nvme_probe() failed\n");
exit(1);

View File

@ -100,7 +100,7 @@ insert_devices
timing_enter hotplug_test
ssh_vm "examples/nvme/hotplug/hotplug -t 10 -i 4 -r 8" &
ssh_vm "examples/nvme/hotplug/hotplug -i 0 -t 10 -n 4 -r 8" &
example_pid=$!
sleep 2

View File

@ -570,28 +570,21 @@ register_controllers(void)
return 0;
}
static char *ealargs[] = {
"perf",
"-c 0x1",
"-n 4",
};
int main(int argc, char **argv)
{
int rc;
int rc;
struct spdk_env_opts opts;
spdk_env_opts_init(&opts);
opts.name = "overhead";
opts.core_mask = "0x1";
spdk_env_init(&opts);
rc = parse_args(argc, argv);
if (rc != 0) {
return rc;
}
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), ealargs);
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
return 1;
}
g_task = spdk_zmalloc(sizeof(struct perf_task), 0, NULL);
if (g_task == NULL) {
fprintf(stderr, "g_task alloc failed\n");

View File

@ -612,29 +612,22 @@ run_nvme_reset_cycle(int retry_count)
return 0;
}
static char *ealargs[] = {
"reset",
"-c 0x1",
"-n 4",
};
int main(int argc, char **argv)
{
int rc;
int i;
int rc;
int i;
struct spdk_env_opts opts;
spdk_env_opts_init(&opts);
opts.name = "reset";
opts.core_mask = "0x1";
spdk_env_init(&opts);
rc = parse_args(argc, argv);
if (rc != 0) {
return rc;
}
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), ealargs);
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
return 1;
}
task_pool = rte_mempool_create("task_pool", 8192,
sizeof(struct reset_task),
64, 0, NULL, NULL, task_ctor, NULL,

View File

@ -37,9 +37,6 @@
#include <inttypes.h>
#include <string.h>
#include <rte_config.h>
#include <rte_eal.h>
#include "spdk/nvme.h"
#include "spdk/env.h"
@ -447,28 +444,19 @@ attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
printf("Attached to %s\n", dev->name);
}
static const char *ealargs[] = {
"nvme_sgl",
"-c 0x1",
"-n 4",
};
int main(int argc, char **argv)
{
struct dev *iter;
int rc, i;
struct dev *iter;
int rc, i;
struct spdk_env_opts opts;
spdk_env_opts_init(&opts);
opts.name = "nvme_sgl";
opts.core_mask = "0x1";
spdk_env_init(&opts);
printf("NVMe Readv/Writev Request test\n");
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]),
(char **)(void *)(uintptr_t)ealargs);
if (rc < 0) {
fprintf(stderr, "could not initialize dpdk\n");
exit(1);
}
if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) {
fprintf(stderr, "nvme_probe() failed\n");
exit(1);