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

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