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

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