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). */
|
/** Maximum allowed IOs or bytes to be issued in one timeslice (e.g., 1ms). */
|
||||||
uint32_t max_per_timeslice;
|
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 {
|
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
|
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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; 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) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case SPDK_BDEV_QOS_RW_IOPS_RATE_LIMIT:
|
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;
|
break;
|
||||||
case SPDK_BDEV_QOS_RW_BPS_RATE_LIMIT:
|
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;
|
break;
|
||||||
case SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES:
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1275,30 +1306,35 @@ _spdk_bdev_qos_update_per_io(struct spdk_bdev_qos *qos, uint64_t io_size_in_byte
|
|||||||
static int
|
static int
|
||||||
_spdk_bdev_qos_io_submit(struct spdk_bdev_channel *ch, struct spdk_bdev_qos *qos)
|
_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 *bdev = ch->bdev;
|
||||||
struct spdk_bdev_shared_resource *shared_resource = ch->shared_resource;
|
struct spdk_bdev_shared_resource *shared_resource = ch->shared_resource;
|
||||||
int i, submitted_ios = 0;
|
int i, submitted_ios = 0;
|
||||||
bool to_limit_io;
|
|
||||||
uint64_t io_size_in_byte;
|
|
||||||
|
|
||||||
while (!TAILQ_EMPTY(&qos->queued)) {
|
TAILQ_FOREACH_SAFE(bdev_io, &qos->queued, internal.link, tmp) {
|
||||||
for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; i++) {
|
if (_spdk_bdev_qos_io_to_limit(bdev_io) == true) {
|
||||||
if (qos->rate_limits[i].max_per_timeslice > 0 &&
|
for (i = 0; i < SPDK_BDEV_QOS_NUM_RATE_LIMIT_TYPES; i++) {
|
||||||
(qos->rate_limits[i].remaining_this_timeslice <= 0)) {
|
if (!qos->rate_limits[i].queue_io) {
|
||||||
return submitted_ios;
|
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);
|
TAILQ_REMOVE(&qos->queued, bdev_io, internal.link);
|
||||||
ch->io_outstanding++;
|
ch->io_outstanding++;
|
||||||
shared_resource->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);
|
bdev->fn_table->submit_request(ch->channel, bdev_io);
|
||||||
submitted_ios++;
|
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;
|
qos->rate_limits[i].remaining_this_timeslice = qos->rate_limits[i].max_per_timeslice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_spdk_bdev_qos_set_ops(qos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user