From 5d9d13a95c6c9a43f33debd99d62e4ad535b315a Mon Sep 17 00:00:00 2001 From: GangCao Date: Wed, 27 Dec 2017 21:18:12 -0500 Subject: [PATCH] bdev/qos: add the QoS parameters for the bdev channel This patch adds the QoS parameters on the bdev channel. Change-Id: I0cb9bf9e9cdbbe61c70c4a3df4eeb8be774793a0 Signed-off-by: GangCao Reviewed-on: https://review.gerrithub.io/393129 Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto --- lib/bdev/bdev.c | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 4392cbd82..6b9c1dc0a 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -55,12 +55,13 @@ int __itt_init_ittlib(const char *, __itt_group_id); #endif -#define SPDK_BDEV_IO_POOL_SIZE (64 * 1024) -#define SPDK_BDEV_IO_CACHE_SIZE 256 -#define BUF_SMALL_POOL_SIZE 8192 -#define BUF_LARGE_POOL_SIZE 1024 -#define NOMEM_THRESHOLD_COUNT 8 -#define ZERO_BUFFER_SIZE 0x100000 +#define SPDK_BDEV_IO_POOL_SIZE (64 * 1024) +#define SPDK_BDEV_IO_CACHE_SIZE 256 +#define BUF_SMALL_POOL_SIZE 8192 +#define BUF_LARGE_POOL_SIZE 1024 +#define NOMEM_THRESHOLD_COUNT 8 +#define ZERO_BUFFER_SIZE 0x100000 +#define SPDK_BDEV_QOS_TIMESLICE_IN_US 1000 typedef TAILQ_HEAD(, spdk_bdev_io) bdev_io_tailq_t; typedef STAILQ_HEAD(, spdk_bdev_io) bdev_io_stailq_t; @@ -134,7 +135,7 @@ struct spdk_bdev_channel { struct spdk_io_channel *channel; /* Channel for the bdev manager */ - struct spdk_io_channel *mgmt_channel; + struct spdk_io_channel *mgmt_channel; struct spdk_bdev_io_stat stat; @@ -142,6 +143,32 @@ struct spdk_bdev_channel { uint32_t flags; + /* + * Rate limiting on this channel. + * Queue of IO awaiting issue because of a QoS rate limiting happened + * on this channel. + */ + bdev_io_tailq_t qos_io; + + /* + * Rate limiting on this channel. + * Maximum allowed IOs to be issued in one timeslice (e.g., 1ms) and + * only valid for the master channel which manages the outstanding IOs. + */ + uint64_t qos_max_ios_per_timeslice; + + /* + * Rate limiting on this channel. + * Submitted IO in one timeslice (e.g., 1ms) + */ + uint64_t io_submitted_this_timeslice; + + /* + * Rate limiting on this channel. + * Periodic running QoS poller in millisecond. + */ + struct spdk_poller *qos_poller; + /* Per-device channel */ struct spdk_bdev_module_channel *module_ch; @@ -914,6 +941,10 @@ _spdk_bdev_channel_create(struct spdk_bdev_channel *ch, void *io_device) memset(&ch->stat, 0, sizeof(ch->stat)); TAILQ_INIT(&ch->queued_resets); + TAILQ_INIT(&ch->qos_io); + ch->qos_max_ios_per_timeslice = 0; + ch->io_submitted_this_timeslice = 0; + ch->qos_poller = NULL; ch->flags = 0; ch->module_ch = shared_ch; @@ -1034,6 +1065,7 @@ _spdk_bdev_channel_destroy(struct spdk_bdev_channel *ch) mgmt_channel = spdk_io_channel_get_ctx(ch->mgmt_channel); _spdk_bdev_abort_queued_io(&ch->queued_resets, ch); + _spdk_bdev_abort_queued_io(&ch->qos_io, ch); _spdk_bdev_abort_queued_io(&shared_ch->nomem_io, ch); _spdk_bdev_abort_buf_io(&mgmt_channel->need_buf_small, ch); _spdk_bdev_abort_buf_io(&mgmt_channel->need_buf_large, ch); @@ -1622,6 +1654,7 @@ _spdk_bdev_reset_freeze_channel(struct spdk_io_channel_iter *i) channel->flags |= BDEV_CH_RESET_IN_PROGRESS; _spdk_bdev_abort_queued_io(&shared_ch->nomem_io, channel); + _spdk_bdev_abort_queued_io(&channel->qos_io, channel); _spdk_bdev_abort_buf_io(&mgmt_channel->need_buf_small, channel); _spdk_bdev_abort_buf_io(&mgmt_channel->need_buf_large, channel);