bdev/qos: Process whole QoS queue on every Qos poll

We have to process whole QoS queue on each QoS poll. It may contain
IOs that still have quota or not affected by QoS rules at all. If we
stop on the first queued IO, all IOs will be limited by the minimum
QoS rule even if they're not affected by this rule.

Here is an example and simple test. We have a NVMf target with Null
bdev and QoS configured with read bandwidth limited to 10 MB/s and
write bandwidth limited to 100 MB/s. First we start nvme_perf with
only write IOs and we see that reported bandwidth is 100 MB/s. Then we
start another instance of nvme_perf with only read IOs. We see that
reported read bandwidth is 10 MB/s but we also see that write
bandwidth also drops to 10 MB/s.

Signed-off-by: Evgeniy Kochetov <evgeniik@nvidia.com>
Change-Id: I1edf09d038e65f873deef19ecb0f4bf9725a5ca5
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13767
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
This commit is contained in:
Evgeniy Kochetov 2022-07-19 10:58:49 +03:00 committed by Konrad Sztyber
parent f79af9ab19
commit b46cfdb6c9

View File

@ -2199,13 +2199,11 @@ bdev_qos_io_submit(struct spdk_bdev_channel *ch, struct spdk_bdev_qos *qos)
int submitted_ios = 0;
TAILQ_FOREACH_SAFE(bdev_io, &qos->queued, internal.link, tmp) {
if (bdev_qos_queue_io(qos, bdev_io)) {
return submitted_ios;
if (!bdev_qos_queue_io(qos, bdev_io)) {
TAILQ_REMOVE(&qos->queued, bdev_io, internal.link);
bdev_io_do_submit(ch, bdev_io);
submitted_ios++;
}
TAILQ_REMOVE(&qos->queued, bdev_io, internal.link);
bdev_io_do_submit(ch, bdev_io);
submitted_ios++;
}
return submitted_ios;