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

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