bdev_nvme: The RPC call now directly attaches to an NVMe device

No need to build a whitelist and scan anymore - the NVMe
driver can directly attach to a specified device.

Change-Id: Ie60c09b6ab37a7f068c496f0cad53bfdc8617349
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Ben Walker 2017-01-25 16:05:09 -07:00 committed by Jim Harris
parent c30ec061e1
commit ee5ca14e21
3 changed files with 57 additions and 51 deletions

View File

@ -104,8 +104,14 @@ enum data_direction {
BDEV_DISK_WRITE = 1
};
struct nvme_probe_ctx {
int controllers_remaining;
int num_whitelist_controllers;
struct spdk_pci_addr whitelist[NVME_MAX_CONTROLLERS];
};
static struct nvme_blockdev g_blockdev[NVME_MAX_BLOCKDEVS];
static int blockdev_index_max = 0;
static int g_blockdev_index_max = 0;
static int nvme_controller_index = 0;
static int num_controllers = -1;
static int g_reset_controller_on_timeout = 0;
@ -490,6 +496,8 @@ probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
return false;
}
ctx->controllers_remaining--;
return true;
}
@ -511,7 +519,6 @@ static void
attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts)
{
struct nvme_probe_ctx *ctx = cb_ctx;
struct nvme_device *dev;
dev = malloc(sizeof(struct nvme_device));
@ -534,10 +541,6 @@ attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
sizeof(struct nvme_io_channel));
TAILQ_INSERT_TAIL(&g_nvme_devices, dev, tailq);
if (ctx->controllers_remaining > 0) {
ctx->controllers_remaining--;
}
if (g_reset_controller_on_timeout) {
spdk_nvme_ctrlr_register_timeout_callback(ctrlr, g_timeout,
blockdev_nvme_timeout_cb, NULL);
@ -545,44 +548,53 @@ attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
}
static bool
blockdev_nvme_exist(struct nvme_probe_ctx *ctx)
spdk_bdev_nvme_exists(struct spdk_pci_addr *addr)
{
int i;
struct nvme_device *nvme_dev;
for (i = 0; i < ctx->num_whitelist_controllers; i++) {
TAILQ_FOREACH(nvme_dev, &g_nvme_devices, tailq) {
if (spdk_pci_addr_compare(&nvme_dev->pci_addr, &ctx->whitelist[i]) == 0) {
return true;
}
TAILQ_FOREACH(nvme_dev, &g_nvme_devices, tailq) {
if (spdk_pci_addr_compare(&nvme_dev->pci_addr, addr) == 0) {
return true;
}
}
return false;
}
int
spdk_bdev_nvme_create(struct nvme_probe_ctx *ctx)
spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid,
const char **names, size_t *count)
{
struct nvme_probe_ctx probe_ctx;
int prev_index_max, i;
size_t j;
if (blockdev_nvme_exist(ctx)) {
if (spdk_pci_addr_parse(&probe_ctx.whitelist[0], trid->traddr) < 0) {
return -1;
}
probe_ctx.num_whitelist_controllers = 1;
probe_ctx.controllers_remaining = 1;
if (spdk_bdev_nvme_exists(&probe_ctx.whitelist[0])) {
return -1;
}
prev_index_max = blockdev_index_max;
prev_index_max = g_blockdev_index_max;
if (spdk_nvme_probe(NULL, ctx, probe_cb, attach_cb, NULL)) {
if (spdk_nvme_probe(trid, &probe_ctx, probe_cb, attach_cb, NULL)) {
return -1;
}
assert((g_blockdev_index_max - prev_index_max) <= (int)*count);
/*
* Report the new bdevs that were created in this call.
* There can be more than one bdev per NVMe controller since one bdev is created per namespace.
*/
ctx->num_created_bdevs = 0;
for (i = prev_index_max; i < blockdev_index_max; i++) {
ctx->created_bdevs[ctx->num_created_bdevs++] = &g_blockdev[i].disk;
for (i = prev_index_max, j = 0; i < g_blockdev_index_max; i++, j++) {
names[j] = g_blockdev[i].disk.name;
}
*count = j;
return 0;
}
@ -610,8 +622,8 @@ nvme_library_init(void)
/*
* If NumControllers is not found, this will return -1, which we
* will later use to denote that we should initialize all
* controllers.
* will later use to denote that we should initialize all
* controllers.
*/
num_controllers = spdk_conf_section_get_intval(sp, "NumControllers");
@ -652,7 +664,11 @@ nvme_library_init(void)
g_nvme_adminq_poll_timeout_us = 1000000;
}
return spdk_bdev_nvme_create(&probe_ctx);
if (spdk_nvme_probe(NULL, &probe_ctx, probe_cb, attach_cb, NULL)) {
return -1;
}
return 0;
}
static void
@ -689,11 +705,11 @@ nvme_ctrlr_initialize_blockdevs(struct nvme_device *nvme_dev, int ctrlr_id)
continue;
}
if (blockdev_index_max >= NVME_MAX_BLOCKDEVS) {
if (g_blockdev_index_max >= NVME_MAX_BLOCKDEVS) {
return;
}
bdev = &g_blockdev[blockdev_index_max];
bdev = &g_blockdev[g_blockdev_index_max];
bdev->ctrlr = ctrlr;
bdev->dev = nvme_dev;
bdev->ns = ns;
@ -724,7 +740,7 @@ nvme_ctrlr_initialize_blockdevs(struct nvme_device *nvme_dev, int ctrlr_id)
bdev->disk.fn_table = &nvmelib_fn_table;
spdk_bdev_register(&bdev->disk);
blockdev_index_max++;
g_blockdev_index_max++;
}
}

View File

@ -36,24 +36,13 @@
#include <stdint.h>
#include "spdk/bdev.h"
#include "spdk/env.h"
#include "spdk/nvme.h"
#define NVME_MAX_CONTROLLERS 16
#define NVME_MAX_BLOCKDEVS_PER_CONTROLLER 256
#define NVME_MAX_BLOCKDEVS (NVME_MAX_BLOCKDEVS_PER_CONTROLLER * NVME_MAX_CONTROLLERS)
struct nvme_probe_ctx {
int controllers_remaining;
int num_whitelist_controllers;
struct spdk_pci_addr whitelist[NVME_MAX_CONTROLLERS];
/* Filled by spdk_bdev_nvme_create() with the bdevs that were added */
int num_created_bdevs;
struct spdk_bdev *created_bdevs[NVME_MAX_BLOCKDEVS];
};
int
spdk_bdev_nvme_create(struct nvme_probe_ctx *ctx);
int spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid,
const char **names, size_t *count);
#endif // SPDK_BLOCKDEV_NVME_H

View File

@ -31,6 +31,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#include "blockdev_nvme.h"
#include "spdk/rpc.h"
@ -57,8 +59,10 @@ spdk_rpc_construct_nvme_bdev(struct spdk_jsonrpc_server_conn *conn,
{
struct rpc_construct_nvme req = {};
struct spdk_json_write_ctx *w;
struct nvme_probe_ctx ctx = {};
int i;
struct spdk_nvme_transport_id trid = {};
const char *names[NVME_MAX_BLOCKDEVS];
size_t count = 0;
size_t i;
if (spdk_json_decode_object(params, rpc_construct_nvme_decoders,
sizeof(rpc_construct_nvme_decoders) / sizeof(*rpc_construct_nvme_decoders),
@ -67,14 +71,11 @@ spdk_rpc_construct_nvme_bdev(struct spdk_jsonrpc_server_conn *conn,
goto invalid;
}
ctx.controllers_remaining = 1;
ctx.num_whitelist_controllers = 1;
trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
snprintf(trid.traddr, sizeof(trid.traddr), "%s", req.pci_address);
if (spdk_pci_addr_parse(&ctx.whitelist[0], req.pci_address) < 0) {
goto invalid;
}
if (spdk_bdev_nvme_create(&ctx)) {
count = NVME_MAX_BLOCKDEVS;
if (spdk_bdev_nvme_create(&trid, names, &count)) {
goto invalid;
}
@ -86,8 +87,8 @@ spdk_rpc_construct_nvme_bdev(struct spdk_jsonrpc_server_conn *conn,
w = spdk_jsonrpc_begin_result(conn, id);
spdk_json_write_array_begin(w);
for (i = 0; i < ctx.num_created_bdevs; i++) {
spdk_json_write_string(w, ctx.created_bdevs[i]->name);
for (i = 0; i < count; i++) {
spdk_json_write_string(w, names[i]);
}
spdk_json_write_array_end(w);
spdk_jsonrpc_end_result(conn, w);