bdev: fix completion for unsubmitted IOs
If an IO is completed, before submitting it to a module, it isn't put on the io_submitted list, so we can't use bdev_io_complete() to complete it, as it'll break that list. To avoid that, a new function was added, bdev_io_complete_unsubmitted(), that will safely complete the IOs in such case. For now, it's equivalent to executing user's completion callback, but it'll serve as a good place to release any resources that should be freed before an IO is completed. Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Change-Id: I1442ead9d272d9210553803bed1d1c989a2bf761 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16970 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
parent
7b71fdc28c
commit
9beb6b163c
@ -361,6 +361,7 @@ struct spdk_bdev_io_error_stat {
|
||||
#define __io_ch_to_bdev_mgmt_ch(io_ch) ((struct spdk_bdev_mgmt_channel *)spdk_io_channel_get_ctx(io_ch))
|
||||
|
||||
static inline void bdev_io_complete(void *ctx);
|
||||
static inline void bdev_io_complete_unsubmitted(struct spdk_bdev_io *bdev_io);
|
||||
|
||||
static void bdev_write_zero_buffer_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg);
|
||||
static void bdev_write_zero_buffer_next(void *_bdev_io);
|
||||
@ -388,8 +389,6 @@ static int bdev_unlock_lba_range(struct spdk_bdev_desc *desc, struct spdk_io_cha
|
||||
uint64_t offset, uint64_t length,
|
||||
lock_range_cb cb_fn, void *cb_arg);
|
||||
|
||||
static inline void bdev_io_complete(void *ctx);
|
||||
|
||||
static bool bdev_abort_queued_io(bdev_io_tailq_t *queue, struct spdk_bdev_io *bio_to_abort);
|
||||
static bool bdev_abort_buf_io(struct spdk_bdev_mgmt_channel *ch, struct spdk_bdev_io *bio_to_abort);
|
||||
|
||||
@ -1416,7 +1415,8 @@ _bdev_memory_domain_get_io_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *b
|
||||
{
|
||||
if (!success) {
|
||||
SPDK_ERRLOG("Failed to get data buffer, completing IO\n");
|
||||
bdev_io_complete(bdev_io);
|
||||
bdev_io->internal.status = SPDK_BDEV_IO_STATUS_FAILED;
|
||||
bdev_io_complete_unsubmitted(bdev_io);
|
||||
} else {
|
||||
bdev_io_submit(bdev_io);
|
||||
}
|
||||
@ -6484,6 +6484,18 @@ bdev_io_update_io_stat(struct spdk_bdev_io *bdev_io, uint64_t tsc_diff)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
_bdev_io_complete(void *ctx)
|
||||
{
|
||||
struct spdk_bdev_io *bdev_io = ctx;
|
||||
|
||||
assert(bdev_io->internal.cb != NULL);
|
||||
assert(spdk_get_thread() == spdk_bdev_io_get_thread(bdev_io));
|
||||
|
||||
bdev_io->internal.cb(bdev_io, bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS,
|
||||
bdev_io->internal.caller_ctx);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bdev_io_complete(void *ctx)
|
||||
{
|
||||
@ -6513,12 +6525,23 @@ bdev_io_complete(void *ctx)
|
||||
}
|
||||
|
||||
bdev_io_update_io_stat(bdev_io, tsc_diff);
|
||||
_bdev_io_complete(bdev_io);
|
||||
}
|
||||
|
||||
assert(bdev_io->internal.cb != NULL);
|
||||
assert(spdk_get_thread() == spdk_bdev_io_get_thread(bdev_io));
|
||||
/* The difference between this function and bdev_io_complete() is that this should be called to
|
||||
* complete IOs that haven't been submitted via bdev_io_submit(), as they weren't added onto the
|
||||
* io_submitted list and don't have submit_tsc updated.
|
||||
*/
|
||||
static inline void
|
||||
bdev_io_complete_unsubmitted(struct spdk_bdev_io *bdev_io)
|
||||
{
|
||||
/* Since the IO hasn't been submitted it's bound to be failed */
|
||||
assert(bdev_io->internal.status != SPDK_BDEV_IO_STATUS_SUCCESS);
|
||||
|
||||
bdev_io->internal.cb(bdev_io, bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS,
|
||||
bdev_io->internal.caller_ctx);
|
||||
/* At this point we don't know if the IO is completed from submission context or not, but,
|
||||
* since this is an error path, we can always do an spdk_thread_send_msg(). */
|
||||
spdk_thread_send_msg(spdk_bdev_io_get_thread(bdev_io),
|
||||
_bdev_io_complete, bdev_io);
|
||||
}
|
||||
|
||||
static void bdev_destroy_cb(void *io_device);
|
||||
|
Loading…
Reference in New Issue
Block a user