bdev/nvme: add option to reset on I/O timeout

Change-Id: I7128a1f2916af8470b0564025f5f30e299ab992b
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Isaac Otsiabah 2016-12-10 15:43:18 -07:00 committed by Daniel Verkamp
parent 7c60aec01e
commit 5bc79e9c3d
3 changed files with 41 additions and 0 deletions

View File

@ -106,6 +106,10 @@
# The maximum number of NVMe controllers to claim. Do not include this key to
# claim all of them.
NumControllers 2
# Registers the application to receive timeout callback and to reset the controller.
ResetControllerOnTimeout Yes
# Timeout value.
NvmeTimeoutValue 30
# Users may change this section to create a different number or size of
# malloc LUNs.

View File

@ -64,6 +64,11 @@
# poll. Units in microseconds.
AcceptorPollRate 10000
# Registers the application to receive timeout callback and to reset the controller.
ResetControllerOnTimeout Yes
# Timeout value.
NvmeTimeoutValue 30
# Define an NVMf Subsystem.
# - NQN is required and must be unique.
# - Core may be set or not. If set, the specified subsystem will run on

View File

@ -112,6 +112,8 @@ static int nvme_luns_per_ns = 1;
static int nvme_controller_index = 0;
static int lun_size_in_mb = 0;
static int num_controllers = -1;
static int g_reset_controller_on_timeout = 0;
static int g_timeout = 0;
static TAILQ_HEAD(, nvme_device) g_nvme_devices = TAILQ_HEAD_INITIALIZER(g_nvme_devices);;
@ -445,6 +447,20 @@ probe_cb(void *cb_ctx, const struct spdk_nvme_probe_info *probe_info,
return true;
}
static void
blockdev_nvme_timeout_cb(struct spdk_nvme_ctrlr *ctrlr,
struct spdk_nvme_qpair *qpair, void *cb_arg)
{
int rc;
SPDK_WARNLOG("Warning: Detected a timeout. ctrlr=%p qpair=%p\n", ctrlr, qpair);
rc = spdk_nvme_ctrlr_reset(ctrlr);
if (rc) {
SPDK_ERRLOG("resetting controller failed\n");
}
}
static void
attach_cb(void *cb_ctx, const struct spdk_nvme_probe_info *probe_info,
struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts)
@ -470,6 +486,11 @@ attach_cb(void *cb_ctx, const struct spdk_nvme_probe_info *probe_info,
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);
}
}
static bool
@ -579,6 +600,17 @@ nvme_library_init(void)
probe_ctx.controllers_remaining = num_controllers;
val = spdk_conf_section_get_val(sp, "ResetControllerOnTimeout");
if (val != NULL) {
if (!strcmp(val, "Yes")) {
g_reset_controller_on_timeout = 1;
}
}
if ((g_timeout = spdk_conf_section_get_intval(sp, "NvmeTimeoutValue")) < 0) {
g_timeout = 0;
}
return spdk_bdev_nvme_create(&probe_ctx);
}