bdev/rbd: Reset returns completion after all inflight I/Os complete

Previously, reset just set a long timer to wait until all inflight
I/Os complete.

As already noted as a TODO item, check if any I/O is still inflight
before completing the reset by using a new API
spdk_bdev_get_current_qd().

The RBD bdev module can count outstanding I/Os itself but is not
efficient.

Signed-off-by: liu-darong <liu.darong@xsky.com>
Signed-off-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Change-Id: Iecaf90b06cae8e21198ec3822b978b54f5404d2b
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13945
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: Dong Yi <yidong0635@126.com>
Reviewed-by: Xiaodong Liu <xiaodong.liu@intel.com>
Reviewed-by: GangCao <gang.cao@intel.com>
This commit is contained in:
Shuhei Matsumoto 2022-08-10 07:27:21 +09:00 committed by Tomasz Zawadzki
parent cad6f55e33
commit 72cb529751

View File

@ -458,18 +458,38 @@ static struct spdk_bdev_module rbd_if = {
};
SPDK_BDEV_MODULE_REGISTER(rbd, &rbd_if)
static int bdev_rbd_reset_timer(void *arg);
static void
bdev_rbd_check_outstanding_ios(struct spdk_bdev *bdev, uint64_t current_qd,
void *cb_arg, int rc)
{
struct bdev_rbd *disk = cb_arg;
enum spdk_bdev_io_status bio_status;
if (rc == 0 && current_qd > 0) {
disk->reset_timer = SPDK_POLLER_REGISTER(bdev_rbd_reset_timer, disk, 1000);
return;
}
if (rc != 0) {
bio_status = SPDK_BDEV_IO_STATUS_FAILED;
} else {
bio_status = SPDK_BDEV_IO_STATUS_SUCCESS;
}
bdev_rbd_io_complete(disk->reset_bdev_io, bio_status);
disk->reset_bdev_io = NULL;
}
static int
bdev_rbd_reset_timer(void *arg)
{
struct bdev_rbd *disk = arg;
/*
* TODO: This should check if any I/O is still in flight before completing the reset.
* For now, just complete after the timer expires.
*/
bdev_rbd_io_complete(disk->reset_bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS);
spdk_poller_unregister(&disk->reset_timer);
disk->reset_bdev_io = NULL;
spdk_bdev_get_current_qd(&disk->disk, bdev_rbd_check_outstanding_ios, disk);
return SPDK_POLLER_BUSY;
}
@ -479,11 +499,12 @@ bdev_rbd_reset(struct bdev_rbd *disk, struct spdk_bdev_io *bdev_io)
{
/*
* HACK: Since librbd doesn't provide any way to cancel outstanding aio, just kick off a
* timer to wait for in-flight I/O to complete.
* poller to wait for in-flight I/O to complete.
*/
assert(disk->reset_bdev_io == NULL);
disk->reset_bdev_io = bdev_io;
disk->reset_timer = SPDK_POLLER_REGISTER(bdev_rbd_reset_timer, disk, 1 * 1000 * 1000);
bdev_rbd_reset_timer(disk);
}
static void