diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 0d5a94ff2..dc2f34e8d 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -142,6 +142,12 @@ struct spdk_bdev_channel { struct spdk_bdev_io_stat stat; + /* + * Count of I/O submitted through this channel and waiting for completion. + * Incremented before submit_request() is called on an spdk_bdev_io. + */ + uint64_t io_outstanding; + bdev_io_tailq_t queued_resets; uint32_t flags; @@ -861,12 +867,14 @@ _spdk_bdev_io_submit(void *ctx) struct spdk_bdev_module_channel *shared_ch = bdev_ch->module_ch; bdev_io->submit_tsc = spdk_get_ticks(); + bdev_ch->io_outstanding++; shared_ch->io_outstanding++; bdev_io->in_submit_request = true; if (spdk_likely(bdev_ch->flags == 0)) { if (spdk_likely(TAILQ_EMPTY(&shared_ch->nomem_io))) { bdev->fn_table->submit_request(ch, bdev_io); } else { + bdev_ch->io_outstanding--; shared_ch->io_outstanding--; TAILQ_INSERT_TAIL(&shared_ch->nomem_io, bdev_io, link); } @@ -1011,6 +1019,7 @@ _spdk_bdev_channel_create(struct spdk_bdev_channel *ch, void *io_device) } memset(&ch->stat, 0, sizeof(ch->stat)); + ch->io_outstanding = 0; TAILQ_INIT(&ch->queued_resets); TAILQ_INIT(&ch->qos_io); ch->qos_max_ios_per_timeslice = 0; @@ -1039,6 +1048,7 @@ _spdk_bdev_channel_destroy_resource(struct spdk_bdev_channel *ch) if (ch->mgmt_channel) { shared_ch = ch->module_ch; if (shared_ch) { + assert(ch->io_outstanding == 0); assert(shared_ch->ref > 0); shared_ch->ref--; if (shared_ch->ref == 0) { @@ -1177,6 +1187,7 @@ _spdk_bdev_abort_queued_io(bdev_io_tailq_t *queue, struct spdk_bdev_channel *ch) * that spdk_bdev_io_complete() will do. */ if (bdev_io->type != SPDK_BDEV_IO_TYPE_RESET) { + ch->io_outstanding++; ch->module_ch->io_outstanding++; } spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED); @@ -2052,6 +2063,7 @@ _spdk_bdev_ch_retry_io(struct spdk_bdev_channel *bdev_ch) while (!TAILQ_EMPTY(&shared_ch->nomem_io)) { bdev_io = TAILQ_FIRST(&shared_ch->nomem_io); TAILQ_REMOVE(&shared_ch->nomem_io, bdev_io, link); + bdev_io->ch->io_outstanding++; shared_ch->io_outstanding++; bdev_io->status = SPDK_BDEV_IO_STATUS_PENDING; bdev->fn_table->submit_request(bdev_io->ch->channel, bdev_io); @@ -2147,7 +2159,9 @@ spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status sta return; } } else { + assert(bdev_ch->io_outstanding > 0); assert(shared_ch->io_outstanding > 0); + bdev_ch->io_outstanding--; shared_ch->io_outstanding--; if (spdk_unlikely(status == SPDK_BDEV_IO_STATUS_NOMEM)) {