Commit ee5ca14e authored by Ben Walker's avatar Ben Walker Committed by Jim Harris
Browse files

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: default avatarBen Walker <benjamin.walker@intel.com>
parent c30ec061
Loading
Loading
Loading
Loading
+42 −26
Original line number Diff line number Diff line
@@ -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 (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 (blockdev_nvme_exist(ctx)) {
	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++;
	}
}

+3 −14
Original line number Diff line number Diff line
@@ -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
+12 −11
Original line number Diff line number Diff line
@@ -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;

	if (spdk_pci_addr_parse(&ctx.whitelist[0], req.pci_address) < 0) {
		goto invalid;
	}
	trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
	snprintf(trid.traddr, sizeof(trid.traddr), "%s", req.pci_address);

	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);