bdevperf: Check current_queue_depth when job starts draining

During debug of some issue, it was found that
current_queue_depth might be 0 when job timer expires,
in that case we won't trigger the job end flow and
bdevperf may hang.

Signed-off-by: Alexey Marchuk <alexeymar@nvidia.com>
Change-Id: Ia49ce6905d329f3ef40216c277bf095782ac9b2d
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15776
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Alexey Marchuk 2022-12-05 16:14:55 +01:00 committed by Tomasz Zawadzki
parent 483d34ad03
commit 893aaacccb

View File

@ -626,25 +626,30 @@ bdevperf_channel_get_histogram_cb(void *cb_arg, int status, struct spdk_histogra
spdk_histogram_data_merge(job_hist, histogram);
}
static void
bdevperf_job_empty(struct bdevperf_job *job)
{
uint64_t end_tsc = 0;
end_tsc = spdk_get_ticks() - g_start_tsc;
job->run_time_in_usec = end_tsc * SPDK_SEC_TO_USEC / spdk_get_ticks_hz();
/* keep histogram info before channel is destroyed */
spdk_bdev_channel_get_histogram(job->ch, bdevperf_channel_get_histogram_cb,
job->histogram);
spdk_put_io_channel(job->ch);
spdk_bdev_close(job->bdev_desc);
spdk_thread_send_msg(g_main_thread, bdevperf_job_end, NULL);
}
static void
bdevperf_end_task(struct bdevperf_task *task)
{
struct bdevperf_job *job = task->job;
uint64_t end_tsc = 0;
TAILQ_INSERT_TAIL(&job->task_list, task, link);
if (job->is_draining) {
if (job->current_queue_depth == 0) {
end_tsc = spdk_get_ticks() - g_start_tsc;
job->run_time_in_usec = end_tsc * SPDK_SEC_TO_USEC / spdk_get_ticks_hz();
/* keep histogram info before channel is destroyed */
spdk_bdev_channel_get_histogram(job->ch, bdevperf_channel_get_histogram_cb,
job->histogram);
spdk_put_io_channel(job->ch);
spdk_bdev_close(job->bdev_desc);
spdk_thread_send_msg(g_main_thread, bdevperf_job_end, NULL);
bdevperf_job_empty(job);
}
}
}
@ -675,6 +680,19 @@ bdevperf_job_drain(void *ctx)
return -1;
}
static int
bdevperf_job_drain_timer(void *ctx)
{
struct bdevperf_job *job = ctx;
bdevperf_job_drain(ctx);
if (job->current_queue_depth == 0) {
bdevperf_job_empty(job);
}
return SPDK_POLLER_BUSY;
}
static void
bdevperf_abort_complete(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
@ -1221,7 +1239,7 @@ bdevperf_job_run(void *ctx)
* completes, another will be submitted. */
/* Start a timer to stop this I/O chain when the run is over */
job->run_timer = SPDK_POLLER_REGISTER(bdevperf_job_drain, job, g_time_in_usec);
job->run_timer = SPDK_POLLER_REGISTER(bdevperf_job_drain_timer, job, g_time_in_usec);
if (job->reset) {
job->reset_timer = SPDK_POLLER_REGISTER(reset_job, job,
10 * SPDK_SEC_TO_USEC);