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 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 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 nvme_controller_index = 0;
static int num_controllers = -1; static int num_controllers = -1;
static int g_reset_controller_on_timeout = 0; 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; return false;
} }
ctx->controllers_remaining--;
return true; return true;
} }
@ -511,7 +519,6 @@ static void
attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, 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 spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts)
{ {
struct nvme_probe_ctx *ctx = cb_ctx;
struct nvme_device *dev; struct nvme_device *dev;
dev = malloc(sizeof(struct nvme_device)); 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)); sizeof(struct nvme_io_channel));
TAILQ_INSERT_TAIL(&g_nvme_devices, dev, tailq); TAILQ_INSERT_TAIL(&g_nvme_devices, dev, tailq);
if (ctx->controllers_remaining > 0) {
ctx->controllers_remaining--;
}
if (g_reset_controller_on_timeout) { if (g_reset_controller_on_timeout) {
spdk_nvme_ctrlr_register_timeout_callback(ctrlr, g_timeout, spdk_nvme_ctrlr_register_timeout_callback(ctrlr, g_timeout,
blockdev_nvme_timeout_cb, NULL); blockdev_nvme_timeout_cb, NULL);
@ -545,44 +548,53 @@ attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
} }
static bool 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; struct nvme_device *nvme_dev;
for (i = 0; i < ctx->num_whitelist_controllers; i++) { TAILQ_FOREACH(nvme_dev, &g_nvme_devices, tailq) {
TAILQ_FOREACH(nvme_dev, &g_nvme_devices, tailq) { if (spdk_pci_addr_compare(&nvme_dev->pci_addr, addr) == 0) {
if (spdk_pci_addr_compare(&nvme_dev->pci_addr, &ctx->whitelist[i]) == 0) { return true;
return true;
}
} }
} }
return false; return false;
} }
int 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; 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; 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; return -1;
} }
assert((g_blockdev_index_max - prev_index_max) <= (int)*count);
/* /*
* Report the new bdevs that were created in this call. * 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. * 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, j = 0; i < g_blockdev_index_max; i++, j++) {
for (i = prev_index_max; i < blockdev_index_max; i++) { names[j] = g_blockdev[i].disk.name;
ctx->created_bdevs[ctx->num_created_bdevs++] = &g_blockdev[i].disk;
} }
*count = j;
return 0; return 0;
} }
@ -610,8 +622,8 @@ nvme_library_init(void)
/* /*
* If NumControllers is not found, this will return -1, which we * If NumControllers is not found, this will return -1, which we
* will later use to denote that we should initialize all * will later use to denote that we should initialize all
* controllers. * controllers.
*/ */
num_controllers = spdk_conf_section_get_intval(sp, "NumControllers"); num_controllers = spdk_conf_section_get_intval(sp, "NumControllers");
@ -652,7 +664,11 @@ nvme_library_init(void)
g_nvme_adminq_poll_timeout_us = 1000000; 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 static void
@ -689,11 +705,11 @@ nvme_ctrlr_initialize_blockdevs(struct nvme_device *nvme_dev, int ctrlr_id)
continue; continue;
} }
if (blockdev_index_max >= NVME_MAX_BLOCKDEVS) { if (g_blockdev_index_max >= NVME_MAX_BLOCKDEVS) {
return; return;
} }
bdev = &g_blockdev[blockdev_index_max]; bdev = &g_blockdev[g_blockdev_index_max];
bdev->ctrlr = ctrlr; bdev->ctrlr = ctrlr;
bdev->dev = nvme_dev; bdev->dev = nvme_dev;
bdev->ns = ns; 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; bdev->disk.fn_table = &nvmelib_fn_table;
spdk_bdev_register(&bdev->disk); spdk_bdev_register(&bdev->disk);
blockdev_index_max++; g_blockdev_index_max++;
} }
} }

View File

@ -36,24 +36,13 @@
#include <stdint.h> #include <stdint.h>
#include "spdk/bdev.h" #include "spdk/nvme.h"
#include "spdk/env.h"
#define NVME_MAX_CONTROLLERS 16 #define NVME_MAX_CONTROLLERS 16
#define NVME_MAX_BLOCKDEVS_PER_CONTROLLER 256 #define NVME_MAX_BLOCKDEVS_PER_CONTROLLER 256
#define NVME_MAX_BLOCKDEVS (NVME_MAX_BLOCKDEVS_PER_CONTROLLER * NVME_MAX_CONTROLLERS) #define NVME_MAX_BLOCKDEVS (NVME_MAX_BLOCKDEVS_PER_CONTROLLER * NVME_MAX_CONTROLLERS)
struct nvme_probe_ctx { int spdk_bdev_nvme_create(struct spdk_nvme_transport_id *trid,
int controllers_remaining; const char **names, size_t *count);
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);
#endif // SPDK_BLOCKDEV_NVME_H #endif // SPDK_BLOCKDEV_NVME_H

View File

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