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:
parent
c30ec061e1
commit
ee5ca14e21
@ -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) {
|
||||
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;
|
||||
}
|
||||
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user