Blame SOURCES/kvm-throttle-groups-fix-hang-when-group-member-leaves.patch

ae23c9
From 1b487f2a77c49129267e4f779956dd549684d8d9 Mon Sep 17 00:00:00 2001
ae23c9
From: Stefan Hajnoczi <stefanha@redhat.com>
ae23c9
Date: Mon, 23 Jul 2018 16:36:29 +0200
ae23c9
Subject: [PATCH 256/268] throttle-groups: fix hang when group member leaves
ae23c9
ae23c9
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
ae23c9
Message-id: <20180723163629.7600-2-stefanha@redhat.com>
ae23c9
Patchwork-id: 81469
ae23c9
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH 1/1] throttle-groups: fix hang when group member leaves
ae23c9
Bugzilla: 1535914
ae23c9
RH-Acked-by: Fam Zheng <famz@redhat.com>
ae23c9
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
ae23c9
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
ae23c9
ae23c9
Throttle groups consist of members sharing one throttling state
ae23c9
(including bps/iops limits).  Round-robin scheduling is used to ensure
ae23c9
fairness.  If a group member already has a timer pending then other
ae23c9
groups members do not schedule their own timers.  The next group member
ae23c9
will have its turn when the existing timer expires.
ae23c9
ae23c9
A hang may occur when a group member leaves while it had a timer
ae23c9
scheduled.  Although the code carefully removes the group member from
ae23c9
the round-robin list, it does not schedule the next member.  Therefore
ae23c9
remaining members continue to wait for the removed member's timer to
ae23c9
expire.
ae23c9
ae23c9
This patch schedules the next request if a timer is pending.
ae23c9
Unfortunately the actual bug is a race condition that I've been unable
ae23c9
to capture in a test case.
ae23c9
ae23c9
Sometimes drive2 hangs when drive1 is removed from the throttling group:
ae23c9
ae23c9
  $ qemu ... -drive if=none,id=drive1,cache=none,format=qcow2,file=data1.qcow2,iops=100,group=foo \
ae23c9
             -device virtio-blk-pci,id=virtio-blk-pci0,drive=drive1 \
ae23c9
             -drive if=none,id=drive2,cache=none,format=qcow2,file=data2.qcow2,iops=10,group=foo \
ae23c9
             -device virtio-blk-pci,id=virtio-blk-pci1,drive=drive2
ae23c9
  (guest-console1)# fio -filename /dev/vda 4k-seq-read.job
ae23c9
  (guest-console2)# fio -filename /dev/vdb 4k-seq-read.job
ae23c9
  (qmp) {"execute": "block_set_io_throttle", "arguments": {"device": "drive1","bps": 0,"bps_rd": 0,"bps_wr": 0,"iops": 0,"iops_rd": 0,"iops_wr": 0}}
ae23c9
ae23c9
Reported-by: Nini Gu <ngu@redhat.com>
ae23c9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
ae23c9
Message-id: 20180704145410.794-1-stefanha@redhat.com
ae23c9
Cc: Alberto Garcia <berto@igalia.com>
ae23c9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
ae23c9
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
ae23c9
---
ae23c9
 block/throttle-groups.c | 4 ++++
ae23c9
 1 file changed, 4 insertions(+)
ae23c9
ae23c9
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
ae23c9
index 36cc043..e297b04 100644
ae23c9
--- a/block/throttle-groups.c
ae23c9
+++ b/block/throttle-groups.c
ae23c9
@@ -564,6 +564,10 @@ void throttle_group_unregister_tgm(ThrottleGroupMember *tgm)
ae23c9
 
ae23c9
     qemu_mutex_lock(&tg->lock);
ae23c9
     for (i = 0; i < 2; i++) {
ae23c9
+        if (timer_pending(tgm->throttle_timers.timers[i])) {
ae23c9
+            tg->any_timer_armed[i] = false;
ae23c9
+            schedule_next_request(tgm, i);
ae23c9
+        }
ae23c9
         if (tg->tokens[i] == tgm) {
ae23c9
             token = throttle_group_next_tgm(tgm);
ae23c9
             /* Take care of the case where this is the last tgm in the group */
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9