From 885bc995964b5cc7b3b3e923b1ead6a3b968cd96 Mon Sep 17 00:00:00 2001 From: JinYu Date: Thu, 10 Jan 2019 21:10:42 +0800 Subject: [PATCH] nvme/hotplug: add ctrlr a timeout callback in hotplug example The example would endlessly loop in unregister_dev()->spdk_nvme_ ctrlr_free_io_qpair(), if the device has been removed after leave hotplug monitoring. Add the timeout callback to handle this corner case. The case will not be friendly to newcomers, if we use the event framework to update it, because the hotplug has been hidden in frame work. Change-Id: I33a81efd356fdf1e7921f5721e9d95936470e8b0 Signed-off-by: JinYu Reviewed-on: https://review.gerrithub.io/c/439822 Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris --- examples/nvme/hotplug/hotplug.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/examples/nvme/hotplug/hotplug.c b/examples/nvme/hotplug/hotplug.c index 456a5194f..104accc08 100644 --- a/examples/nvme/hotplug/hotplug.c +++ b/examples/nvme/hotplug/hotplug.c @@ -36,6 +36,7 @@ #include "spdk/nvme.h" #include "spdk/queue.h" #include "spdk/string.h" +#include "spdk/util.h" struct dev_ctx { TAILQ_ENTRY(dev_ctx) tailq; @@ -71,10 +72,21 @@ static int g_expected_removal_times = -1; static int g_insert_times; static int g_removal_times; static int g_shm_id = -1; +static uint64_t g_timeout_in_us = SPDK_SEC_TO_USEC; static void task_complete(struct perf_task *task); +static void +timeout_cb(void *cb_arg, struct spdk_nvme_ctrlr *ctrlr, + struct spdk_nvme_qpair *qpair, uint16_t cid) +{ + /* leave hotplug monitor loop, use the timeout_cb to monitor the hotplug */ + if (spdk_nvme_probe(NULL, NULL, NULL, NULL, NULL) != 0) { + fprintf(stderr, "spdk_nvme_probe() failed\n"); + } +} + static void register_dev(struct spdk_nvme_ctrlr *ctrlr) { @@ -94,6 +106,8 @@ register_dev(struct spdk_nvme_ctrlr *ctrlr) dev->is_removed = false; dev->is_draining = false; + spdk_nvme_ctrlr_register_timeout_callback(ctrlr, g_timeout_in_us, timeout_cb, NULL); + dev->ns = spdk_nvme_ctrlr_get_ns(ctrlr, 1); if (!dev->ns || !spdk_nvme_ns_is_active(dev->ns)) { @@ -388,6 +402,7 @@ static void usage(char *program_name) { printf("%s options", program_name); printf("\n"); + printf("\t[-c timeout for each command in second(default:1s)]\n"); printf("\t[-i shm id (optional)]\n"); printf("\t[-n expected hot insert times]\n"); printf("\t[-r expected hot removal times]\n"); @@ -403,7 +418,7 @@ parse_args(int argc, char **argv) /* default value */ g_time_in_sec = 0; - while ((op = getopt(argc, argv, "i:n:r:t:")) != -1) { + while ((op = getopt(argc, argv, "c:i:n:r:t:")) != -1) { if (op == '?') { usage(argv[0]); return 1; @@ -415,6 +430,9 @@ parse_args(int argc, char **argv) return val; } switch (op) { + case 'c': + g_timeout_in_us = val * SPDK_SEC_TO_USEC; + break; case 'i': g_shm_id = val; break;