Commit 885bc995 authored by JinYu's avatar JinYu Committed by Jim Harris
Browse files

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: default avatarJinYu <jin.yu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/439822


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent c5c102ce
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -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;