nvme: fix confusion around nvme_ctrlr_set_state

In most places, we are passing NVME_TIMEOUT_INFINITE as the
timeout_in_ms argument to nvme_ctrlr_set_state, presumably in an attempt
to specify an infinite timeout. However, nvme_ctrlr_set_state only
checked against 0 when setting the actual timeout, and we didn't have
any logic to check for overflow so we just ended up setting random
timeout_tsc values which changes the behavior of the
nvme_ctrlr_process_init function in several places.

So, change NVME_TIMEOUT_INFINITE to 0, and add some integer overflow
checking to nvme_ctrlr_set_state.

Change-Id: Ic9d0cc57ed153df30c3b20313c3742072a5f992d
Signed-off-by: Seth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/469485
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Alexey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Seth Howell 2019-09-25 15:32:40 -07:00 committed by Jim Harris
parent a10d0ce79c
commit 06746448c1
2 changed files with 27 additions and 9 deletions

View File

@ -828,16 +828,34 @@ static void
nvme_ctrlr_set_state(struct spdk_nvme_ctrlr *ctrlr, enum nvme_ctrlr_state state,
uint64_t timeout_in_ms)
{
uint64_t ticks_per_ms, timeout_in_ticks, now_ticks;
ctrlr->state = state;
if (timeout_in_ms == 0) {
SPDK_DEBUGLOG(SPDK_LOG_NVME, "setting state to %s (no timeout)\n",
nvme_ctrlr_state_string(ctrlr->state));
ctrlr->state_timeout_tsc = NVME_TIMEOUT_INFINITE;
} else {
SPDK_DEBUGLOG(SPDK_LOG_NVME, "setting state to %s (timeout %" PRIu64 " ms)\n",
nvme_ctrlr_state_string(ctrlr->state), timeout_in_ms);
ctrlr->state_timeout_tsc = spdk_get_ticks() + (timeout_in_ms * spdk_get_ticks_hz()) / 1000;
if (timeout_in_ms == NVME_TIMEOUT_INFINITE) {
goto inf;
}
ticks_per_ms = spdk_get_ticks_hz() / 1000;
if (timeout_in_ms > UINT64_MAX / ticks_per_ms) {
SPDK_ERRLOG("Specified timeout would cause integer overflow. Defaulting to no timeout.\n");
goto inf;
}
now_ticks = spdk_get_ticks();
timeout_in_ticks = timeout_in_ms * ticks_per_ms;
if (timeout_in_ticks > UINT64_MAX - now_ticks) {
SPDK_ERRLOG("Specified timeout would cause integer overflow. Defaulting to no timeout.\n");
goto inf;
}
ctrlr->state_timeout_tsc = timeout_in_ticks + now_ticks;
SPDK_DEBUGLOG(SPDK_LOG_NVME, "setting state to %s (timeout %" PRIu64 " ms)\n",
nvme_ctrlr_state_string(ctrlr->state), ctrlr->state_timeout_tsc);
return;
inf:
SPDK_DEBUGLOG(SPDK_LOG_NVME, "setting state to %s (no timeout)\n",
nvme_ctrlr_state_string(ctrlr->state));
ctrlr->state_timeout_tsc = NVME_TIMEOUT_INFINITE;
}
static void

View File

@ -559,7 +559,7 @@ enum nvme_ctrlr_state {
NVME_CTRLR_STATE_ERROR
};
#define NVME_TIMEOUT_INFINITE UINT64_MAX
#define NVME_TIMEOUT_INFINITE 0
/*
* Used to track properties for all processes accessing the controller.