bdev/qos: add the function pointers for qos operations
This patch added two new function pointers (queue_io, update_io) for related qos operations like iops and bandwidth rate limits. Change-Id: I2ffd67c5f1c421eab448fd5e95f809da55805fcd Signed-off-by: GangCao <gang.cao@intel.com> Reviewed-on: https://review.gerrithub.io/c/438157 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
parent
ff3c2e3c84
commit
cd4dd43ab8
@ -141,6 +141,12 @@ struct spdk_bdev_qos_limit {
|
||||
|
||||
/** Maximum allowed IOs or bytes to be issued in one timeslice (e.g., 1ms). */
|
||||
uint32_t max_per_timeslice;
|
||||
|
||||
/** Function to check whether to queue the IO. */
|
||||
bool (*queue_io)(const struct spdk_bdev_qos_limit *limit, struct spdk_bdev_io *io);
|
||||
|
||||
/** Function to update for the submitted IO. */
|
||||
void (*update_quota)(struct spdk_bdev_qos_limit *limit, struct spdk_bdev_io *io);
|
||||
};
|
||||
|
||||
struct spdk_bdev_qos {
|
||||
@ -1248,24 +1254,49 @@ _spdk_bdev_get_io_size_in_byte(struct spdk_bdev_io *bdev_io)
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
_spdk_bdev_qos_rw_queue_io(const struct spdk_bdev_qos_limit *limit, struct spdk_bdev_io *io)
|
||||
{
|
||||
if (limit->max_per_timeslice > 0 && limit->remaining_this_timeslice <= 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_bdev_qos_update_per_io(struct spdk_bdev_qos *qos, uint64_t io_size_in_byte)
|
||||
_spdk_bdev_qos_rw_iops_update_quota(struct spdk_bdev_qos_limit *limit, struct spdk_bdev_io *io)
|
||||
{
|
||||
limit->remaining_this_timeslice--;
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_bdev_qos_rw_bps_update_quota(struct spdk_bdev_qos_limit *limit, struct spdk_bdev_io *io)
|
||||
{
|
||||
limit->remaining_this_timeslice -= _spdk_bdev_get_io_size_in_byte(io);
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_bdev_qos_set_ops(struct spdk_bdev_qos *qos)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; i++) {
|
||||
if (qos->rate_limits[i].limit == SPDK_BDEV_QOS_LIMIT_NOT_DEFINED) {
|
||||
qos->rate_limits[i].queue_io = NULL;
|
||||
qos->rate_limits[i].update_quota = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (i) {
|
||||
case SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT:
|
||||
qos->rate_limits[i].remaining_this_timeslice--;
|
||||
qos->rate_limits[i].queue_io = _spdk_bdev_qos_rw_queue_io;
|
||||
qos->rate_limits[i].update_quota = _spdk_bdev_qos_rw_iops_update_quota;
|
||||
break;
|
||||
case SPDK_BDEV_QOS_RW_BPS_RATE_LIMIT:
|
||||
qos->rate_limits[i].remaining_this_timeslice -= io_size_in_byte;
|
||||
qos->rate_limits[i].queue_io = _spdk_bdev_qos_rw_queue_io;
|
||||
qos->rate_limits[i].update_quota = _spdk_bdev_qos_rw_bps_update_quota;
|
||||
break;
|
||||
case SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1275,30 +1306,35 @@ _spdk_bdev_qos_update_per_io(struct spdk_bdev_qos *qos, uint64_t io_size_in_byte
|
||||
static int
|
||||
_spdk_bdev_qos_io_submit(struct spdk_bdev_channel *ch, struct spdk_bdev_qos *qos)
|
||||
{
|
||||
struct spdk_bdev_io *bdev_io = NULL;
|
||||
struct spdk_bdev_io *bdev_io = NULL, *tmp = NULL;
|
||||
struct spdk_bdev *bdev = ch->bdev;
|
||||
struct spdk_bdev_shared_resource *shared_resource = ch->shared_resource;
|
||||
int i, submitted_ios = 0;
|
||||
bool to_limit_io;
|
||||
uint64_t io_size_in_byte;
|
||||
|
||||
while (!TAILQ_EMPTY(&qos->queued)) {
|
||||
for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; i++) {
|
||||
if (qos->rate_limits[i].max_per_timeslice > 0 &&
|
||||
(qos->rate_limits[i].remaining_this_timeslice <= 0)) {
|
||||
return submitted_ios;
|
||||
TAILQ_FOREACH_SAFE(bdev_io, &qos->queued, internal.link, tmp) {
|
||||
if (_spdk_bdev_qos_io_to_limit(bdev_io) == true) {
|
||||
for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; i++) {
|
||||
if (!qos->rate_limits[i].queue_io) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (qos->rate_limits[i].queue_io(&qos->rate_limits[i],
|
||||
bdev_io) == true) {
|
||||
return submitted_ios;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; i++) {
|
||||
if (!qos->rate_limits[i].update_quota) {
|
||||
continue;
|
||||
}
|
||||
|
||||
qos->rate_limits[i].update_quota(&qos->rate_limits[i], bdev_io);
|
||||
}
|
||||
}
|
||||
|
||||
bdev_io = TAILQ_FIRST(&qos->queued);
|
||||
TAILQ_REMOVE(&qos->queued, bdev_io, internal.link);
|
||||
ch->io_outstanding++;
|
||||
shared_resource->io_outstanding++;
|
||||
to_limit_io = _spdk_bdev_qos_io_to_limit(bdev_io);
|
||||
if (to_limit_io == true) {
|
||||
io_size_in_byte = _spdk_bdev_get_io_size_in_byte(bdev_io);
|
||||
_spdk_bdev_qos_update_per_io(qos, io_size_in_byte);
|
||||
}
|
||||
bdev->fn_table->submit_request(ch->channel, bdev_io);
|
||||
submitted_ios++;
|
||||
}
|
||||
@ -1688,6 +1724,8 @@ spdk_bdev_qos_update_max_quota_per_timeslice(struct spdk_bdev_qos *qos)
|
||||
|
||||
qos->rate_limits[i].remaining_this_timeslice = qos->rate_limits[i].max_per_timeslice;
|
||||
}
|
||||
|
||||
_spdk_bdev_qos_set_ops(qos);
|
||||
}
|
||||
|
||||
static int
|
||||
|
Loading…
Reference in New Issue
Block a user