lib/bdev: Add all submitted I/Os to the list including any I/O generated by splitting

This is a preparation to abort split I/Os. To abort any I/O by
bio_cb_arg, they have to be managed by the submitted I/O list.

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I9459d9d2d3511aad0325dcc20d88610444a4ea04
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2231
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Community-CI: Broadcom CI
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Shuhei Matsumoto 2020-05-07 06:31:13 +09:00 committed by Tomasz Zawadzki
parent 29f86a2630
commit fc3e40618c
3 changed files with 17 additions and 27 deletions

View File

@ -269,8 +269,7 @@ struct spdk_bdev_channel {
uint64_t io_outstanding;
/*
* List of spdk_bdev_io directly associated with a call to the public bdev API.
* It does not include any spdk_bdev_io that are generated via splitting.
* List of all submitted I/Os including I/O that are generated via splitting.
*/
bdev_io_tailq_t io_submitted;
@ -2126,14 +2125,7 @@ bdev_io_submit(struct spdk_bdev_io *bdev_io)
}
}
/* Add the bdev_io to io_submitted only if it is the original
* submission from the bdev user. When a bdev_io is split,
* it comes back through this code path, so we need to make sure
* we don't try to add it a second time.
*/
if (bdev_io->internal.cb != bdev_io_split_done) {
TAILQ_INSERT_TAIL(&ch->io_submitted, bdev_io, internal.ch_link);
}
TAILQ_INSERT_TAIL(&ch->io_submitted, bdev_io, internal.ch_link);
if (bdev->split_on_optimal_io_boundary && bdev_io_should_split(bdev_io)) {
bdev_io->internal.submit_tsc = spdk_get_ticks();
@ -2430,8 +2422,14 @@ bdev_channel_poll_timeout_io(struct spdk_io_channel_iter *i)
now = spdk_get_ticks();
TAILQ_FOREACH(bdev_io, &bdev_ch->io_submitted, internal.ch_link) {
/* I/O are added to this TAILQ as they are submitted.
* So once we find an I/O that has not timed out, we can immediately exit the loop. */
/* Exclude any I/O that are generated via splitting. */
if (bdev_io->internal.cb == bdev_io_split_done) {
continue;
}
/* Once we find an I/O that has not timed out, we can immediately
* exit the loop.
*/
if (now < (bdev_io->internal.submit_tsc +
ctx->timeout_in_sec * spdk_get_ticks_hz())) {
goto end;
@ -4765,13 +4763,8 @@ bdev_io_complete(void *ctx)
tsc = spdk_get_ticks();
tsc_diff = tsc - bdev_io->internal.submit_tsc;
spdk_trace_record_tsc(tsc, TRACE_BDEV_IO_DONE, 0, 0, (uintptr_t)bdev_io, 0);
/* When a bdev_io is split, the children bdev_io are not added
* to the io_submitted list. So don't try to remove them in that
* case.
*/
if (bdev_io->internal.cb != bdev_io_split_done) {
TAILQ_REMOVE(&bdev_ch->io_submitted, bdev_io, internal.ch_link);
}
TAILQ_REMOVE(&bdev_ch->io_submitted, bdev_io, internal.ch_link);
if (bdev_io->internal.ch->histogram) {
spdk_histogram_data_tally(bdev_io->internal.ch->histogram, tsc_diff);

View File

@ -2687,13 +2687,10 @@ bdev_set_io_timeout(void)
* Set up the expected values before calling spdk_bdev_read_blocks
*/
CU_ASSERT(spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL) == 0);
/* We only count the submitted IO by the user
* Even the IO split into two IOs but we only count one.
* Becauce the user only see one IO.
*/
CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 1);
/* We count all submitted IOs including IO that are generated by splitting. */
CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 3);
stub_complete_io(1);
CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 1);
CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 2);
stub_complete_io(1);
CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 0);

View File

@ -1674,7 +1674,7 @@ bdev_set_io_timeout_mt(void)
set_thread(2);
CU_ASSERT(spdk_bdev_read_blocks(g_desc, ch[2], (void *)0xF000, 14, 8, io_done, NULL) == 0);
bdev_ch[2] = spdk_io_channel_get_ctx(ch[2]);
CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch[2]) == 1);
CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch[2]) == 3);
set_thread(0);
memset(&cb_arg, 0, sizeof(cb_arg));
@ -1709,7 +1709,7 @@ bdev_set_io_timeout_mt(void)
CU_ASSERT(cb_arg.iov.iov_base == (void *)0xF000);
CU_ASSERT(cb_arg.iov.iov_len == 8 * g_bdev.bdev.blocklen);
stub_complete_io(g_bdev.io_target, 1);
CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch[2]) == 1);
CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch[2]) == 2);
stub_complete_io(g_bdev.io_target, 1);
CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch[2]) == 0);