qemu-kvm/kvm-blockjob-update-nodes-head-while-removing-all-bdrv.patch
Danilo C. L. de Paula 58b71dc108 * Mon Sep 23 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.1.0-11.el8
- kvm-blockjob-update-nodes-head-while-removing-all-bdrv.patch [bz#1746631]
- kvm-hostmem-file-fix-pmem-file-size-check.patch [bz#1724008 bz#1736788]
- kvm-memory-fetch-pmem-size-in-get_file_size.patch [bz#1724008 bz#1736788]
- kvm-pr-manager-Fix-invalid-g_free-crash-bug.patch [bz#1753992]
- Resolves: bz#1724008
  (QEMU core dumped "memory_region_get_ram_ptr: Assertion `mr->ram_block' failed")
- Resolves: bz#1736788
  (QEMU core dumped if boot guest with nvdimm backed by /dev/dax0.0 and option pmem=off)
- Resolves: bz#1746631
  (Qemu core dump when do block commit under stress)
- Resolves: bz#1753992
  (core dump when testing persistent reservation in guest)
2019-09-23 21:47:12 +01:00

73 lines
2.5 KiB
Diff

From 49dd008d58d7527a98981d96106949b2913fb4d9 Mon Sep 17 00:00:00 2001
From: Sergio Lopez Pascual <slp@redhat.com>
Date: Wed, 18 Sep 2019 11:34:14 +0100
Subject: [PATCH 1/4] blockjob: update nodes head while removing all bdrv
RH-Author: Sergio Lopez Pascual <slp@redhat.com>
Message-id: <20190918113414.24522-2-slp@redhat.com>
Patchwork-id: 90748
O-Subject: [RHEL-AV-8.1.0 qemu-kvm PATCH 1/1] blockjob: update nodes head while removing all bdrv
Bugzilla: 1746631
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
block_job_remove_all_bdrv() iterates through job->nodes, calling
bdrv_root_unref_child() for each entry. The call to the latter may
reach child_job_[can_]set_aio_ctx(), which will also attempt to
traverse job->nodes, potentially finding entries that where freed
on previous iterations.
To avoid this situation, update job->nodes head on each iteration to
ensure that already freed entries are no longer linked to the list.
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1746631
Signed-off-by: Sergio Lopez <slp@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190911100316.32282-1-mreitz@redhat.com
Reviewed-by: Sergio Lopez <slp@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit d876bf676f5e7c6aa9ac64555e48cba8734ecb2f)
Signed-off-by: Sergio Lopez <slp@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
blockjob.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/blockjob.c b/blockjob.c
index 20b7f55..74abb97 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -186,14 +186,23 @@ static const BdrvChildRole child_job = {
void block_job_remove_all_bdrv(BlockJob *job)
{
- GSList *l;
- for (l = job->nodes; l; l = l->next) {
+ /*
+ * bdrv_root_unref_child() may reach child_job_[can_]set_aio_ctx(),
+ * which will also traverse job->nodes, so consume the list one by
+ * one to make sure that such a concurrent access does not attempt
+ * to process an already freed BdrvChild.
+ */
+ while (job->nodes) {
+ GSList *l = job->nodes;
BdrvChild *c = l->data;
+
+ job->nodes = l->next;
+
bdrv_op_unblock_all(c->bs, job->blocker);
bdrv_root_unref_child(c);
+
+ g_slist_free_1(l);
}
- g_slist_free(job->nodes);
- job->nodes = NULL;
}
bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs)
--
1.8.3.1