* Tue Nov 19 2024 Miroslav Rezanina <mrezanin@redhat.com> - 9.1.0-3
- kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch [RHEL-11043] - kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch [RHEL-57682] - kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch [RHEL-57682] - kvm-accel-kvm-refactor-dirty-ring-setup.patch [RHEL-57682] - kvm-KVM-Dynamic-sized-kvm-memslots-array.patch [RHEL-57682] - kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch [RHEL-57682] - kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch [RHEL-57682] - kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch [RHEL-57682] - kvm-Require-new-dtrace-package.patch [RHEL-67900] - Resolves: RHEL-11043 ([RFE] [HPEMC] [RHEL-9.6] qemu-kvm: support up to 4096 VCPUs) - Resolves: RHEL-57682 (Bad migration performance when performing vGPU VM live migration ) - Resolves: RHEL-67900 (Failed to build qemu-kvm due to missing dtrace [rhel-9.6])
This commit is contained in:
parent
462008473e
commit
639b862c69
49
kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch
Normal file
49
kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
From f9dfed0e5fd03ee6fa7364801db7d101bf085a79 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Xu <peterx@redhat.com>
|
||||||
|
Date: Tue, 17 Sep 2024 12:38:33 -0400
|
||||||
|
Subject: [PATCH 6/9] KVM: Define KVM_MEMSLOTS_NUM_MAX_DEFAULT
|
||||||
|
|
||||||
|
RH-Author: Peter Xu <peterx@redhat.com>
|
||||||
|
RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array
|
||||||
|
RH-Jira: RHEL-57682
|
||||||
|
RH-Acked-by: Juraj Marcin <None>
|
||||||
|
RH-Commit: [5/7] c95bdaa406e76b943882fd75c4d345ca5fc397d4 (peterx/qemu-kvm)
|
||||||
|
|
||||||
|
Make the default max nr_slots a macro, it's only used when KVM reports
|
||||||
|
nothing.
|
||||||
|
|
||||||
|
Reviewed-by: David Hildenbrand <david@redhat.com>
|
||||||
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||||
|
Link: https://lore.kernel.org/r/20240917163835.194664-3-peterx@redhat.com
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
(cherry picked from commit b34a908c8f24eedb0a8e5ff486b059b58fd793f4)
|
||||||
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||||
|
---
|
||||||
|
accel/kvm/kvm-all.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||||
|
index 44bf4180fa..3900de8883 100644
|
||||||
|
--- a/accel/kvm/kvm-all.c
|
||||||
|
+++ b/accel/kvm/kvm-all.c
|
||||||
|
@@ -71,6 +71,8 @@
|
||||||
|
|
||||||
|
/* Default num of memslots to be allocated when VM starts */
|
||||||
|
#define KVM_MEMSLOTS_NR_ALLOC_DEFAULT 16
|
||||||
|
+/* Default max allowed memslots if kernel reported nothing */
|
||||||
|
+#define KVM_MEMSLOTS_NR_MAX_DEFAULT 32
|
||||||
|
|
||||||
|
struct KVMParkedVcpu {
|
||||||
|
unsigned long vcpu_id;
|
||||||
|
@@ -2617,7 +2619,7 @@ static int kvm_init(MachineState *ms)
|
||||||
|
|
||||||
|
/* If unspecified, use the default value */
|
||||||
|
if (!s->nr_slots) {
|
||||||
|
- s->nr_slots = 32;
|
||||||
|
+ s->nr_slots_max = KVM_MEMSLOTS_NR_MAX_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->nr_as = kvm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE);
|
||||||
|
--
|
||||||
|
2.39.3
|
||||||
|
|
250
kvm-KVM-Dynamic-sized-kvm-memslots-array.patch
Normal file
250
kvm-KVM-Dynamic-sized-kvm-memslots-array.patch
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
From 9813dc1d19a6afedbab382b79e72691190e42fcf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Xu <peterx@redhat.com>
|
||||||
|
Date: Tue, 17 Sep 2024 12:38:32 -0400
|
||||||
|
Subject: [PATCH 5/9] KVM: Dynamic sized kvm memslots array
|
||||||
|
|
||||||
|
RH-Author: Peter Xu <peterx@redhat.com>
|
||||||
|
RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array
|
||||||
|
RH-Jira: RHEL-57682
|
||||||
|
RH-Acked-by: Juraj Marcin <None>
|
||||||
|
RH-Commit: [4/7] 04d74707873b28a50b1e1bc08e4788c79455518c (peterx/qemu-kvm)
|
||||||
|
|
||||||
|
Zhiyi reported an infinite loop issue in VFIO use case. The cause of that
|
||||||
|
was a separate discussion, however during that I found a regression of
|
||||||
|
dirty sync slowness when profiling.
|
||||||
|
|
||||||
|
Each KVMMemoryListerner maintains an array of kvm memslots. Currently it's
|
||||||
|
statically allocated to be the max supported by the kernel. However after
|
||||||
|
Linux commit 4fc096a99e ("KVM: Raise the maximum number of user memslots"),
|
||||||
|
the max supported memslots reported now grows to some number large enough
|
||||||
|
so that it may not be wise to always statically allocate with the max
|
||||||
|
reported.
|
||||||
|
|
||||||
|
What's worse, QEMU kvm code still walks all the allocated memslots entries
|
||||||
|
to do any form of lookups. It can drastically slow down all memslot
|
||||||
|
operations because each of such loop can run over 32K times on the new
|
||||||
|
kernels.
|
||||||
|
|
||||||
|
Fix this issue by making the memslots to be allocated dynamically.
|
||||||
|
|
||||||
|
Here the initial size was set to 16 because it should cover the basic VM
|
||||||
|
usages, so that the hope is the majority VM use case may not even need to
|
||||||
|
grow at all (e.g. if one starts a VM with ./qemu-system-x86_64 by default
|
||||||
|
it'll consume 9 memslots), however not too large to waste memory.
|
||||||
|
|
||||||
|
There can also be even better way to address this, but so far this is the
|
||||||
|
simplest and should be already better even than before we grow the max
|
||||||
|
supported memslots. For example, in the case of above issue when VFIO was
|
||||||
|
attached on a 32GB system, there are only ~10 memslots used. So it could
|
||||||
|
be good enough as of now.
|
||||||
|
|
||||||
|
In the above VFIO context, measurement shows that the precopy dirty sync
|
||||||
|
shrinked from ~86ms to ~3ms after this patch applied. It should also apply
|
||||||
|
to any KVM enabled VM even without VFIO.
|
||||||
|
|
||||||
|
NOTE: we don't have a FIXES tag for this patch because there's no real
|
||||||
|
commit that regressed this in QEMU. Such behavior existed for a long time,
|
||||||
|
but only start to be a problem when the kernel reports very large
|
||||||
|
nr_slots_max value. However that's pretty common now (the kernel change
|
||||||
|
was merged in 2021) so we attached cc:stable because we'll want this change
|
||||||
|
to be backported to stable branches.
|
||||||
|
|
||||||
|
Cc: qemu-stable <qemu-stable@nongnu.org>
|
||||||
|
Reported-by: Zhiyi Guo <zhguo@redhat.com>
|
||||||
|
Tested-by: Zhiyi Guo <zhguo@redhat.com>
|
||||||
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||||
|
Acked-by: David Hildenbrand <david@redhat.com>
|
||||||
|
Reviewed-by: Fabiano Rosas <farosas@suse.de>
|
||||||
|
Link: https://lore.kernel.org/r/20240917163835.194664-2-peterx@redhat.com
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
(cherry picked from commit 5504a8126115d173687b37e657312a8ffe29fc0c)
|
||||||
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||||
|
---
|
||||||
|
accel/kvm/kvm-all.c | 87 +++++++++++++++++++++++++++++++++-------
|
||||||
|
accel/kvm/trace-events | 1 +
|
||||||
|
include/sysemu/kvm_int.h | 1 +
|
||||||
|
3 files changed, 74 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||||
|
index de709fbc43..44bf4180fa 100644
|
||||||
|
--- a/accel/kvm/kvm-all.c
|
||||||
|
+++ b/accel/kvm/kvm-all.c
|
||||||
|
@@ -69,6 +69,9 @@
|
||||||
|
#define KVM_GUESTDBG_BLOCKIRQ 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+/* Default num of memslots to be allocated when VM starts */
|
||||||
|
+#define KVM_MEMSLOTS_NR_ALLOC_DEFAULT 16
|
||||||
|
+
|
||||||
|
struct KVMParkedVcpu {
|
||||||
|
unsigned long vcpu_id;
|
||||||
|
int kvm_fd;
|
||||||
|
@@ -165,6 +168,57 @@ void kvm_resample_fd_notify(int gsi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * kvm_slots_grow(): Grow the slots[] array in the KVMMemoryListener
|
||||||
|
+ *
|
||||||
|
+ * @kml: The KVMMemoryListener* to grow the slots[] array
|
||||||
|
+ * @nr_slots_new: The new size of slots[] array
|
||||||
|
+ *
|
||||||
|
+ * Returns: True if the array grows larger, false otherwise.
|
||||||
|
+ */
|
||||||
|
+static bool kvm_slots_grow(KVMMemoryListener *kml, unsigned int nr_slots_new)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, cur = kml->nr_slots_allocated;
|
||||||
|
+ KVMSlot *slots;
|
||||||
|
+
|
||||||
|
+ if (nr_slots_new > kvm_state->nr_slots) {
|
||||||
|
+ nr_slots_new = kvm_state->nr_slots;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (cur >= nr_slots_new) {
|
||||||
|
+ /* Big enough, no need to grow, or we reached max */
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (cur == 0) {
|
||||||
|
+ slots = g_new0(KVMSlot, nr_slots_new);
|
||||||
|
+ } else {
|
||||||
|
+ assert(kml->slots);
|
||||||
|
+ slots = g_renew(KVMSlot, kml->slots, nr_slots_new);
|
||||||
|
+ /*
|
||||||
|
+ * g_renew() doesn't initialize extended buffers, however kvm
|
||||||
|
+ * memslots require fields to be zero-initialized. E.g. pointers,
|
||||||
|
+ * memory_size field, etc.
|
||||||
|
+ */
|
||||||
|
+ memset(&slots[cur], 0x0, sizeof(slots[0]) * (nr_slots_new - cur));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = cur; i < nr_slots_new; i++) {
|
||||||
|
+ slots[i].slot = i;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ kml->slots = slots;
|
||||||
|
+ kml->nr_slots_allocated = nr_slots_new;
|
||||||
|
+ trace_kvm_slots_grow(cur, nr_slots_new);
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool kvm_slots_double(KVMMemoryListener *kml)
|
||||||
|
+{
|
||||||
|
+ return kvm_slots_grow(kml, kml->nr_slots_allocated * 2);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
unsigned int kvm_get_max_memslots(void)
|
||||||
|
{
|
||||||
|
KVMState *s = KVM_STATE(current_accel());
|
||||||
|
@@ -193,15 +247,26 @@ unsigned int kvm_get_free_memslots(void)
|
||||||
|
/* Called with KVMMemoryListener.slots_lock held */
|
||||||
|
static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
|
||||||
|
{
|
||||||
|
- KVMState *s = kvm_state;
|
||||||
|
+ unsigned int n;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- for (i = 0; i < s->nr_slots; i++) {
|
||||||
|
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
|
||||||
|
if (kml->slots[i].memory_size == 0) {
|
||||||
|
return &kml->slots[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * If no free slots, try to grow first by doubling. Cache the old size
|
||||||
|
+ * here to avoid another round of search: if the grow succeeded, it
|
||||||
|
+ * means slots[] now must have the existing "n" slots occupied,
|
||||||
|
+ * followed by one or more free slots starting from slots[n].
|
||||||
|
+ */
|
||||||
|
+ n = kml->nr_slots_allocated;
|
||||||
|
+ if (kvm_slots_double(kml)) {
|
||||||
|
+ return &kml->slots[n];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -222,10 +287,9 @@ static KVMSlot *kvm_lookup_matching_slot(KVMMemoryListener *kml,
|
||||||
|
hwaddr start_addr,
|
||||||
|
hwaddr size)
|
||||||
|
{
|
||||||
|
- KVMState *s = kvm_state;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- for (i = 0; i < s->nr_slots; i++) {
|
||||||
|
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
|
||||||
|
KVMSlot *mem = &kml->slots[i];
|
||||||
|
|
||||||
|
if (start_addr == mem->start_addr && size == mem->memory_size) {
|
||||||
|
@@ -267,7 +331,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram,
|
||||||
|
int i, ret = 0;
|
||||||
|
|
||||||
|
kvm_slots_lock();
|
||||||
|
- for (i = 0; i < s->nr_slots; i++) {
|
||||||
|
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
|
||||||
|
KVMSlot *mem = &kml->slots[i];
|
||||||
|
|
||||||
|
if (ram >= mem->ram && ram < mem->ram + mem->memory_size) {
|
||||||
|
@@ -1071,7 +1135,7 @@ static int kvm_physical_log_clear(KVMMemoryListener *kml,
|
||||||
|
|
||||||
|
kvm_slots_lock();
|
||||||
|
|
||||||
|
- for (i = 0; i < s->nr_slots; i++) {
|
||||||
|
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
|
||||||
|
mem = &kml->slots[i];
|
||||||
|
/* Discard slots that are empty or do not overlap the section */
|
||||||
|
if (!mem->memory_size ||
|
||||||
|
@@ -1719,12 +1783,8 @@ static void kvm_log_sync_global(MemoryListener *l, bool last_stage)
|
||||||
|
/* Flush all kernel dirty addresses into KVMSlot dirty bitmap */
|
||||||
|
kvm_dirty_ring_flush();
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * TODO: make this faster when nr_slots is big while there are
|
||||||
|
- * only a few used slots (small VMs).
|
||||||
|
- */
|
||||||
|
kvm_slots_lock();
|
||||||
|
- for (i = 0; i < s->nr_slots; i++) {
|
||||||
|
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
|
||||||
|
mem = &kml->slots[i];
|
||||||
|
if (mem->memory_size && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
|
||||||
|
kvm_slot_sync_dirty_pages(mem);
|
||||||
|
@@ -1839,12 +1899,9 @@ void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- kml->slots = g_new0(KVMSlot, s->nr_slots);
|
||||||
|
kml->as_id = as_id;
|
||||||
|
|
||||||
|
- for (i = 0; i < s->nr_slots; i++) {
|
||||||
|
- kml->slots[i].slot = i;
|
||||||
|
- }
|
||||||
|
+ kvm_slots_grow(kml, KVM_MEMSLOTS_NR_ALLOC_DEFAULT);
|
||||||
|
|
||||||
|
QSIMPLEQ_INIT(&kml->transaction_add);
|
||||||
|
QSIMPLEQ_INIT(&kml->transaction_del);
|
||||||
|
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
|
||||||
|
index 37626c1ac5..ad2ae6fca5 100644
|
||||||
|
--- a/accel/kvm/trace-events
|
||||||
|
+++ b/accel/kvm/trace-events
|
||||||
|
@@ -36,3 +36,4 @@ kvm_io_window_exit(void) ""
|
||||||
|
kvm_run_exit_system_event(int cpu_index, uint32_t event_type) "cpu_index %d, system_even_type %"PRIu32
|
||||||
|
kvm_convert_memory(uint64_t start, uint64_t size, const char *msg) "start 0x%" PRIx64 " size 0x%" PRIx64 " %s"
|
||||||
|
kvm_memory_fault(uint64_t start, uint64_t size, uint64_t flags) "start 0x%" PRIx64 " size 0x%" PRIx64 " flags 0x%" PRIx64
|
||||||
|
+kvm_slots_grow(unsigned int old, unsigned int new) "%u -> %u"
|
||||||
|
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
|
||||||
|
index 1d8fb1473b..48e496b3d4 100644
|
||||||
|
--- a/include/sysemu/kvm_int.h
|
||||||
|
+++ b/include/sysemu/kvm_int.h
|
||||||
|
@@ -46,6 +46,7 @@ typedef struct KVMMemoryListener {
|
||||||
|
MemoryListener listener;
|
||||||
|
KVMSlot *slots;
|
||||||
|
unsigned int nr_used_slots;
|
||||||
|
+ unsigned int nr_slots_allocated;
|
||||||
|
int as_id;
|
||||||
|
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add;
|
||||||
|
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_del;
|
||||||
|
--
|
||||||
|
2.39.3
|
||||||
|
|
@ -0,0 +1,72 @@
|
|||||||
|
From 6c0a0d9734c507af2c84aa33eb1624f35e1f51fb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Xu <peterx@redhat.com>
|
||||||
|
Date: Tue, 17 Sep 2024 12:38:34 -0400
|
||||||
|
Subject: [PATCH 7/9] KVM: Rename KVMMemoryListener.nr_used_slots to
|
||||||
|
nr_slots_used
|
||||||
|
|
||||||
|
RH-Author: Peter Xu <peterx@redhat.com>
|
||||||
|
RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array
|
||||||
|
RH-Jira: RHEL-57682
|
||||||
|
RH-Acked-by: Juraj Marcin <None>
|
||||||
|
RH-Commit: [6/7] 74e9576751e0adeb8113a5e8e495b4b1285b0d76 (peterx/qemu-kvm)
|
||||||
|
|
||||||
|
This will make all nr_slots counters to be named in the same manner.
|
||||||
|
|
||||||
|
Reviewed-by: David Hildenbrand <david@redhat.com>
|
||||||
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||||
|
Link: https://lore.kernel.org/r/20240917163835.194664-4-peterx@redhat.com
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
(cherry picked from commit dbdc00ba5b136bba80d850f61cc79a9cafaae1cd)
|
||||||
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||||
|
---
|
||||||
|
accel/kvm/kvm-all.c | 6 +++---
|
||||||
|
include/sysemu/kvm_int.h | 2 +-
|
||||||
|
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||||
|
index 3900de8883..e414d015c9 100644
|
||||||
|
--- a/accel/kvm/kvm-all.c
|
||||||
|
+++ b/accel/kvm/kvm-all.c
|
||||||
|
@@ -239,7 +239,7 @@ unsigned int kvm_get_free_memslots(void)
|
||||||
|
if (!s->as[i].ml) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- used_slots = MAX(used_slots, s->as[i].ml->nr_used_slots);
|
||||||
|
+ used_slots = MAX(used_slots, s->as[i].ml->nr_slots_used);
|
||||||
|
}
|
||||||
|
kvm_slots_unlock();
|
||||||
|
|
||||||
|
@@ -1516,7 +1516,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
|
||||||
|
}
|
||||||
|
start_addr += slot_size;
|
||||||
|
size -= slot_size;
|
||||||
|
- kml->nr_used_slots--;
|
||||||
|
+ kml->nr_slots_used--;
|
||||||
|
} while (size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -1555,7 +1555,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
|
||||||
|
ram_start_offset += slot_size;
|
||||||
|
ram += slot_size;
|
||||||
|
size -= slot_size;
|
||||||
|
- kml->nr_used_slots++;
|
||||||
|
+ kml->nr_slots_used++;
|
||||||
|
} while (size);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
|
||||||
|
index 48e496b3d4..b705dfc9b4 100644
|
||||||
|
--- a/include/sysemu/kvm_int.h
|
||||||
|
+++ b/include/sysemu/kvm_int.h
|
||||||
|
@@ -45,7 +45,7 @@ typedef struct KVMMemoryUpdate {
|
||||||
|
typedef struct KVMMemoryListener {
|
||||||
|
MemoryListener listener;
|
||||||
|
KVMSlot *slots;
|
||||||
|
- unsigned int nr_used_slots;
|
||||||
|
+ unsigned int nr_slots_used;
|
||||||
|
unsigned int nr_slots_allocated;
|
||||||
|
int as_id;
|
||||||
|
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add;
|
||||||
|
--
|
||||||
|
2.39.3
|
||||||
|
|
89
kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch
Normal file
89
kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
From 5b731abd3a932fe9a21f83f3849a3b3769906e19 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Xu <peterx@redhat.com>
|
||||||
|
Date: Tue, 17 Sep 2024 12:38:35 -0400
|
||||||
|
Subject: [PATCH 8/9] KVM: Rename KVMState->nr_slots to nr_slots_max
|
||||||
|
|
||||||
|
RH-Author: Peter Xu <peterx@redhat.com>
|
||||||
|
RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array
|
||||||
|
RH-Jira: RHEL-57682
|
||||||
|
RH-Acked-by: Juraj Marcin <None>
|
||||||
|
RH-Commit: [7/7] 43471483e7380119ba6415bff6d8ee6c69aa9cd7 (peterx/qemu-kvm)
|
||||||
|
|
||||||
|
This value used to reflect the maximum supported memslots from KVM kernel.
|
||||||
|
Rename it to be clearer.
|
||||||
|
|
||||||
|
Reviewed-by: David Hildenbrand <david@redhat.com>
|
||||||
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||||
|
Link: https://lore.kernel.org/r/20240917163835.194664-5-peterx@redhat.com
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
(cherry picked from commit 943c742868c739c0b14fd996bad3adf744156fec)
|
||||||
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||||
|
---
|
||||||
|
accel/kvm/kvm-all.c | 12 ++++++------
|
||||||
|
include/sysemu/kvm_int.h | 4 ++--
|
||||||
|
2 files changed, 8 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||||
|
index e414d015c9..49dedda47e 100644
|
||||||
|
--- a/accel/kvm/kvm-all.c
|
||||||
|
+++ b/accel/kvm/kvm-all.c
|
||||||
|
@@ -183,8 +183,8 @@ static bool kvm_slots_grow(KVMMemoryListener *kml, unsigned int nr_slots_new)
|
||||||
|
unsigned int i, cur = kml->nr_slots_allocated;
|
||||||
|
KVMSlot *slots;
|
||||||
|
|
||||||
|
- if (nr_slots_new > kvm_state->nr_slots) {
|
||||||
|
- nr_slots_new = kvm_state->nr_slots;
|
||||||
|
+ if (nr_slots_new > kvm_state->nr_slots_max) {
|
||||||
|
+ nr_slots_new = kvm_state->nr_slots_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur >= nr_slots_new) {
|
||||||
|
@@ -225,7 +225,7 @@ unsigned int kvm_get_max_memslots(void)
|
||||||
|
{
|
||||||
|
KVMState *s = KVM_STATE(current_accel());
|
||||||
|
|
||||||
|
- return s->nr_slots;
|
||||||
|
+ return s->nr_slots_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int kvm_get_free_memslots(void)
|
||||||
|
@@ -243,7 +243,7 @@ unsigned int kvm_get_free_memslots(void)
|
||||||
|
}
|
||||||
|
kvm_slots_unlock();
|
||||||
|
|
||||||
|
- return s->nr_slots - used_slots;
|
||||||
|
+ return s->nr_slots_max - used_slots;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called with KVMMemoryListener.slots_lock held */
|
||||||
|
@@ -2615,10 +2615,10 @@ static int kvm_init(MachineState *ms)
|
||||||
|
(kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE);
|
||||||
|
|
||||||
|
kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT);
|
||||||
|
- s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
|
||||||
|
+ s->nr_slots_max = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
|
||||||
|
|
||||||
|
/* If unspecified, use the default value */
|
||||||
|
- if (!s->nr_slots) {
|
||||||
|
+ if (!s->nr_slots_max) {
|
||||||
|
s->nr_slots_max = KVM_MEMSLOTS_NR_MAX_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
|
||||||
|
index b705dfc9b4..2c57194b6b 100644
|
||||||
|
--- a/include/sysemu/kvm_int.h
|
||||||
|
+++ b/include/sysemu/kvm_int.h
|
||||||
|
@@ -103,8 +103,8 @@ struct KVMDirtyRingReaper {
|
||||||
|
struct KVMState
|
||||||
|
{
|
||||||
|
AccelState parent_obj;
|
||||||
|
-
|
||||||
|
- int nr_slots;
|
||||||
|
+ /* Max number of KVM slots supported */
|
||||||
|
+ int nr_slots_max;
|
||||||
|
int fd;
|
||||||
|
int vmfd;
|
||||||
|
int coalesced_mmio;
|
||||||
|
--
|
||||||
|
2.39.3
|
||||||
|
|
143
kvm-accel-kvm-refactor-dirty-ring-setup.patch
Normal file
143
kvm-accel-kvm-refactor-dirty-ring-setup.patch
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
From e27a9d1e5194243084efe4405fe50463442f0fe3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Thu, 12 Sep 2024 11:48:38 +0530
|
||||||
|
Subject: [PATCH 4/9] accel/kvm: refactor dirty ring setup
|
||||||
|
|
||||||
|
RH-Author: Peter Xu <peterx@redhat.com>
|
||||||
|
RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array
|
||||||
|
RH-Jira: RHEL-57682
|
||||||
|
RH-Acked-by: Juraj Marcin <None>
|
||||||
|
RH-Commit: [3/7] 226ae9826237887fc55f75b9175524f12b4fa4a9 (peterx/qemu-kvm)
|
||||||
|
|
||||||
|
Refactor setting up of dirty ring code in kvm_init() so that is can be
|
||||||
|
reused in the future patchsets.
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Link: https://lore.kernel.org/r/20240912061838.4501-1-anisinha@redhat.com
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
(cherry picked from commit 28ed7f9761eb273e7dedcfdc0507d158106d0451)
|
||||||
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||||
|
---
|
||||||
|
accel/kvm/kvm-all.c | 88 +++++++++++++++++++++++++--------------------
|
||||||
|
1 file changed, 50 insertions(+), 38 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||||
|
index 4f96d8b45e..de709fbc43 100644
|
||||||
|
--- a/accel/kvm/kvm-all.c
|
||||||
|
+++ b/accel/kvm/kvm-all.c
|
||||||
|
@@ -2439,6 +2439,55 @@ static int find_kvm_machine_type(MachineState *ms)
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int kvm_setup_dirty_ring(KVMState *s)
|
||||||
|
+{
|
||||||
|
+ uint64_t dirty_log_manual_caps;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Enable KVM dirty ring if supported, otherwise fall back to
|
||||||
|
+ * dirty logging mode
|
||||||
|
+ */
|
||||||
|
+ ret = kvm_dirty_ring_init(s);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is not needed when dirty ring is
|
||||||
|
+ * enabled. More importantly, KVM_DIRTY_LOG_INITIALLY_SET will assume no
|
||||||
|
+ * page is wr-protected initially, which is against how kvm dirty ring is
|
||||||
|
+ * usage - kvm dirty ring requires all pages are wr-protected at the very
|
||||||
|
+ * beginning. Enabling this feature for dirty ring causes data corruption.
|
||||||
|
+ *
|
||||||
|
+ * TODO: Without KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 and kvm clear dirty log,
|
||||||
|
+ * we may expect a higher stall time when starting the migration. In the
|
||||||
|
+ * future we can enable KVM_CLEAR_DIRTY_LOG to work with dirty ring too:
|
||||||
|
+ * instead of clearing dirty bit, it can be a way to explicitly wr-protect
|
||||||
|
+ * guest pages.
|
||||||
|
+ */
|
||||||
|
+ if (!s->kvm_dirty_ring_size) {
|
||||||
|
+ dirty_log_manual_caps =
|
||||||
|
+ kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
|
||||||
|
+ dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
|
||||||
|
+ KVM_DIRTY_LOG_INITIALLY_SET);
|
||||||
|
+ s->manual_dirty_log_protect = dirty_log_manual_caps;
|
||||||
|
+ if (dirty_log_manual_caps) {
|
||||||
|
+ ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
|
||||||
|
+ dirty_log_manual_caps);
|
||||||
|
+ if (ret) {
|
||||||
|
+ warn_report("Trying to enable capability %"PRIu64" of "
|
||||||
|
+ "KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
|
||||||
|
+ "Falling back to the legacy mode. ",
|
||||||
|
+ dirty_log_manual_caps);
|
||||||
|
+ s->manual_dirty_log_protect = 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int kvm_init(MachineState *ms)
|
||||||
|
{
|
||||||
|
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||||
|
@@ -2458,7 +2507,6 @@ static int kvm_init(MachineState *ms)
|
||||||
|
const KVMCapabilityInfo *missing_cap;
|
||||||
|
int ret;
|
||||||
|
int type;
|
||||||
|
- uint64_t dirty_log_manual_caps;
|
||||||
|
|
||||||
|
qemu_mutex_init(&kml_slots_lock);
|
||||||
|
|
||||||
|
@@ -2570,47 +2618,11 @@ static int kvm_init(MachineState *ms)
|
||||||
|
s->coalesced_pio = s->coalesced_mmio &&
|
||||||
|
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * Enable KVM dirty ring if supported, otherwise fall back to
|
||||||
|
- * dirty logging mode
|
||||||
|
- */
|
||||||
|
- ret = kvm_dirty_ring_init(s);
|
||||||
|
+ ret = kvm_setup_dirty_ring(s);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is not needed when dirty ring is
|
||||||
|
- * enabled. More importantly, KVM_DIRTY_LOG_INITIALLY_SET will assume no
|
||||||
|
- * page is wr-protected initially, which is against how kvm dirty ring is
|
||||||
|
- * usage - kvm dirty ring requires all pages are wr-protected at the very
|
||||||
|
- * beginning. Enabling this feature for dirty ring causes data corruption.
|
||||||
|
- *
|
||||||
|
- * TODO: Without KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 and kvm clear dirty log,
|
||||||
|
- * we may expect a higher stall time when starting the migration. In the
|
||||||
|
- * future we can enable KVM_CLEAR_DIRTY_LOG to work with dirty ring too:
|
||||||
|
- * instead of clearing dirty bit, it can be a way to explicitly wr-protect
|
||||||
|
- * guest pages.
|
||||||
|
- */
|
||||||
|
- if (!s->kvm_dirty_ring_size) {
|
||||||
|
- dirty_log_manual_caps =
|
||||||
|
- kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
|
||||||
|
- dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
|
||||||
|
- KVM_DIRTY_LOG_INITIALLY_SET);
|
||||||
|
- s->manual_dirty_log_protect = dirty_log_manual_caps;
|
||||||
|
- if (dirty_log_manual_caps) {
|
||||||
|
- ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
|
||||||
|
- dirty_log_manual_caps);
|
||||||
|
- if (ret) {
|
||||||
|
- warn_report("Trying to enable capability %"PRIu64" of "
|
||||||
|
- "KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
|
||||||
|
- "Falling back to the legacy mode. ",
|
||||||
|
- dirty_log_manual_caps);
|
||||||
|
- s->manual_dirty_log_protect = 0;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
#ifdef KVM_CAP_VCPU_EVENTS
|
||||||
|
s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS);
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
2.39.3
|
||||||
|
|
143
kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch
Normal file
143
kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
From 90a18a9e2e585413eba96ab96df4a878f6c405be Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Thu, 8 Aug 2024 17:08:38 +0530
|
||||||
|
Subject: [PATCH 3/9] kvm: refactor core virtual machine creation into its own
|
||||||
|
function
|
||||||
|
|
||||||
|
RH-Author: Peter Xu <peterx@redhat.com>
|
||||||
|
RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array
|
||||||
|
RH-Jira: RHEL-57682
|
||||||
|
RH-Acked-by: Juraj Marcin <None>
|
||||||
|
RH-Commit: [2/7] 3db75ee31b109048ef2de5c7f193116ab8c185a7 (peterx/qemu-kvm)
|
||||||
|
|
||||||
|
Refactoring the core logic around KVM_CREATE_VM into its own separate function
|
||||||
|
so that it can be called from other functions in subsequent patches. There is
|
||||||
|
no functional change in this patch.
|
||||||
|
|
||||||
|
CC: pbonzini@redhat.com
|
||||||
|
CC: zhao1.liu@intel.com
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Link: https://lore.kernel.org/r/20240808113838.1697366-1-anisinha@redhat.com
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
(cherry picked from commit 67388078da1cf6dac89e5a7c748cca3444d49690)
|
||||||
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||||
|
---
|
||||||
|
accel/kvm/kvm-all.c | 89 ++++++++++++++++++++++++++++-----------------
|
||||||
|
1 file changed, 56 insertions(+), 33 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||||
|
index b51441523d..4f96d8b45e 100644
|
||||||
|
--- a/accel/kvm/kvm-all.c
|
||||||
|
+++ b/accel/kvm/kvm-all.c
|
||||||
|
@@ -2385,6 +2385,60 @@ uint32_t kvm_dirty_ring_size(void)
|
||||||
|
return kvm_state->kvm_dirty_ring_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int do_kvm_create_vm(MachineState *ms, int type)
|
||||||
|
+{
|
||||||
|
+ KVMState *s;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ s = KVM_STATE(ms->accelerator);
|
||||||
|
+
|
||||||
|
+ do {
|
||||||
|
+ ret = kvm_ioctl(s, KVM_CREATE_VM, type);
|
||||||
|
+ } while (ret == -EINTR);
|
||||||
|
+
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret));
|
||||||
|
+
|
||||||
|
+#ifdef TARGET_S390X
|
||||||
|
+ if (ret == -EINVAL) {
|
||||||
|
+ error_printf("Host kernel setup problem detected."
|
||||||
|
+ " Please verify:\n");
|
||||||
|
+ error_printf("- for kernels supporting the"
|
||||||
|
+ " switch_amode or user_mode parameters, whether");
|
||||||
|
+ error_printf(" user space is running in primary address space\n");
|
||||||
|
+ error_printf("- for kernels supporting the vm.allocate_pgste"
|
||||||
|
+ " sysctl, whether it is enabled\n");
|
||||||
|
+ }
|
||||||
|
+#elif defined(TARGET_PPC)
|
||||||
|
+ if (ret == -EINVAL) {
|
||||||
|
+ error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
|
||||||
|
+ (type == 2) ? "pr" : "hv");
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int find_kvm_machine_type(MachineState *ms)
|
||||||
|
+{
|
||||||
|
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||||
|
+ int type;
|
||||||
|
+
|
||||||
|
+ if (object_property_find(OBJECT(current_machine), "kvm-type")) {
|
||||||
|
+ g_autofree char *kvm_type;
|
||||||
|
+ kvm_type = object_property_get_str(OBJECT(current_machine),
|
||||||
|
+ "kvm-type",
|
||||||
|
+ &error_abort);
|
||||||
|
+ type = mc->kvm_type(ms, kvm_type);
|
||||||
|
+ } else if (mc->kvm_type) {
|
||||||
|
+ type = mc->kvm_type(ms, NULL);
|
||||||
|
+ } else {
|
||||||
|
+ type = kvm_arch_get_default_type(ms);
|
||||||
|
+ }
|
||||||
|
+ return type;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int kvm_init(MachineState *ms)
|
||||||
|
{
|
||||||
|
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||||
|
@@ -2467,45 +2521,14 @@ static int kvm_init(MachineState *ms)
|
||||||
|
}
|
||||||
|
s->as = g_new0(struct KVMAs, s->nr_as);
|
||||||
|
|
||||||
|
- if (object_property_find(OBJECT(current_machine), "kvm-type")) {
|
||||||
|
- g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
|
||||||
|
- "kvm-type",
|
||||||
|
- &error_abort);
|
||||||
|
- type = mc->kvm_type(ms, kvm_type);
|
||||||
|
- } else if (mc->kvm_type) {
|
||||||
|
- type = mc->kvm_type(ms, NULL);
|
||||||
|
- } else {
|
||||||
|
- type = kvm_arch_get_default_type(ms);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
+ type = find_kvm_machine_type(ms);
|
||||||
|
if (type < 0) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
- do {
|
||||||
|
- ret = kvm_ioctl(s, KVM_CREATE_VM, type);
|
||||||
|
- } while (ret == -EINTR);
|
||||||
|
-
|
||||||
|
+ ret = do_kvm_create_vm(ms, type);
|
||||||
|
if (ret < 0) {
|
||||||
|
- error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret));
|
||||||
|
-
|
||||||
|
-#ifdef TARGET_S390X
|
||||||
|
- if (ret == -EINVAL) {
|
||||||
|
- error_printf("Host kernel setup problem detected."
|
||||||
|
- " Please verify:\n");
|
||||||
|
- error_printf("- for kernels supporting the"
|
||||||
|
- " switch_amode or user_mode parameters, whether");
|
||||||
|
- error_printf(" user space is running in primary address space\n");
|
||||||
|
- error_printf("- for kernels supporting the vm.allocate_pgste"
|
||||||
|
- " sysctl, whether it is enabled\n");
|
||||||
|
- }
|
||||||
|
-#elif defined(TARGET_PPC)
|
||||||
|
- if (ret == -EINVAL) {
|
||||||
|
- error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
|
||||||
|
- (type == 2) ? "pr" : "hv");
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.39.3
|
||||||
|
|
131
kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch
Normal file
131
kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
From 66c634c4749d58c0c3644ace27a656c507433288 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Wed, 28 Aug 2024 18:15:39 +0530
|
||||||
|
Subject: [PATCH 2/9] kvm: replace fprintf with error_report()/printf() in
|
||||||
|
kvm_init()
|
||||||
|
|
||||||
|
RH-Author: Peter Xu <peterx@redhat.com>
|
||||||
|
RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array
|
||||||
|
RH-Jira: RHEL-57682
|
||||||
|
RH-Acked-by: Juraj Marcin <None>
|
||||||
|
RH-Commit: [1/7] 3dd0b67d3b6662001eb35201ca41b15d0dd97994 (peterx/qemu-kvm)
|
||||||
|
|
||||||
|
error_report() is more appropriate for error situations. Replace fprintf with
|
||||||
|
error_report() and error_printf() as appropriate. Some improvement in error
|
||||||
|
reporting also happens as a part of this change. For example:
|
||||||
|
|
||||||
|
From:
|
||||||
|
$ ./qemu-system-x86_64 --accel kvm
|
||||||
|
Could not access KVM kernel module: No such file or directory
|
||||||
|
|
||||||
|
To:
|
||||||
|
$ ./qemu-system-x86_64 --accel kvm
|
||||||
|
qemu-system-x86_64: --accel kvm: Could not access KVM kernel module: No such file or directory
|
||||||
|
|
||||||
|
CC: qemu-trivial@nongnu.org
|
||||||
|
CC: zhao1.liu@intel.com
|
||||||
|
CC: armbru@redhat.com
|
||||||
|
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
|
||||||
|
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Link: https://lore.kernel.org/r/20240828124539.62672-1-anisinha@redhat.com
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
(cherry picked from commit 804dfbe3ef5e950328b162ae85741be2e228544f)
|
||||||
|
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||||
|
---
|
||||||
|
accel/kvm/kvm-all.c | 40 ++++++++++++++++++----------------------
|
||||||
|
1 file changed, 18 insertions(+), 22 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||||
|
index a220178822..b51441523d 100644
|
||||||
|
--- a/accel/kvm/kvm-all.c
|
||||||
|
+++ b/accel/kvm/kvm-all.c
|
||||||
|
@@ -2427,7 +2427,7 @@ static int kvm_init(MachineState *ms)
|
||||||
|
QLIST_INIT(&s->kvm_parked_vcpus);
|
||||||
|
s->fd = qemu_open_old(s->device ?: "/dev/kvm", O_RDWR);
|
||||||
|
if (s->fd == -1) {
|
||||||
|
- fprintf(stderr, "Could not access KVM kernel module: %m\n");
|
||||||
|
+ error_report("Could not access KVM kernel module: %m");
|
||||||
|
ret = -errno;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
@@ -2437,13 +2437,13 @@ static int kvm_init(MachineState *ms)
|
||||||
|
if (ret >= 0) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
- fprintf(stderr, "kvm version too old\n");
|
||||||
|
+ error_report("kvm version too old");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret > KVM_API_VERSION) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
- fprintf(stderr, "kvm version not supported\n");
|
||||||
|
+ error_report("kvm version not supported");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2488,26 +2488,22 @@ static int kvm_init(MachineState *ms)
|
||||||
|
} while (ret == -EINTR);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
- fprintf(stderr, "ioctl(KVM_CREATE_VM) failed: %d %s\n", -ret,
|
||||||
|
- strerror(-ret));
|
||||||
|
+ error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret));
|
||||||
|
|
||||||
|
#ifdef TARGET_S390X
|
||||||
|
if (ret == -EINVAL) {
|
||||||
|
- fprintf(stderr,
|
||||||
|
- "Host kernel setup problem detected. Please verify:\n");
|
||||||
|
- fprintf(stderr, "- for kernels supporting the switch_amode or"
|
||||||
|
- " user_mode parameters, whether\n");
|
||||||
|
- fprintf(stderr,
|
||||||
|
- " user space is running in primary address space\n");
|
||||||
|
- fprintf(stderr,
|
||||||
|
- "- for kernels supporting the vm.allocate_pgste sysctl, "
|
||||||
|
- "whether it is enabled\n");
|
||||||
|
+ error_printf("Host kernel setup problem detected."
|
||||||
|
+ " Please verify:\n");
|
||||||
|
+ error_printf("- for kernels supporting the"
|
||||||
|
+ " switch_amode or user_mode parameters, whether");
|
||||||
|
+ error_printf(" user space is running in primary address space\n");
|
||||||
|
+ error_printf("- for kernels supporting the vm.allocate_pgste"
|
||||||
|
+ " sysctl, whether it is enabled\n");
|
||||||
|
}
|
||||||
|
#elif defined(TARGET_PPC)
|
||||||
|
if (ret == -EINVAL) {
|
||||||
|
- fprintf(stderr,
|
||||||
|
- "PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
|
||||||
|
- (type == 2) ? "pr" : "hv");
|
||||||
|
+ error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
|
||||||
|
+ (type == 2) ? "pr" : "hv");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
goto err;
|
||||||
|
@@ -2526,9 +2522,9 @@ static int kvm_init(MachineState *ms)
|
||||||
|
nc->name, nc->num, soft_vcpus_limit);
|
||||||
|
|
||||||
|
if (nc->num > hard_vcpus_limit) {
|
||||||
|
- fprintf(stderr, "Number of %s cpus requested (%d) exceeds "
|
||||||
|
- "the maximum cpus supported by KVM (%d)\n",
|
||||||
|
- nc->name, nc->num, hard_vcpus_limit);
|
||||||
|
+ error_report("Number of %s cpus requested (%d) exceeds "
|
||||||
|
+ "the maximum cpus supported by KVM (%d)",
|
||||||
|
+ nc->name, nc->num, hard_vcpus_limit);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2542,8 +2538,8 @@ static int kvm_init(MachineState *ms)
|
||||||
|
}
|
||||||
|
if (missing_cap) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
- fprintf(stderr, "kvm does not support %s\n%s",
|
||||||
|
- missing_cap->name, upgrade_note);
|
||||||
|
+ error_report("kvm does not support %s", missing_cap->name);
|
||||||
|
+ error_printf("%s", upgrade_note);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.39.3
|
||||||
|
|
75
kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch
Normal file
75
kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
From d06f8670b9304c66d45e2270a4f5b462ed6cbe09 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Wed, 16 Oct 2024 17:21:34 +0530
|
||||||
|
Subject: [PATCH 1/9] pc: q35: Bump max_cpus to 4096 vcpus
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
RH-Author: Ani Sinha <anisinha@redhat.com>
|
||||||
|
RH-MergeRequest: 273: pc: q35: Bump max_cpus to 4096 vcpus
|
||||||
|
RH-Jira: RHEL-11043
|
||||||
|
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
||||||
|
RH-Acked-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||||
|
RH-Acked-by: MST <mst@redhat.com>
|
||||||
|
RH-Commit: [1/1] 23caa8c9e4f34c3114701b7a5bb25002a9372b2e (anisinha/centos-qemu-kvm)
|
||||||
|
|
||||||
|
This is the downstream change equivalent of the upstream QEMU commit
|
||||||
|
e4e98c7e ("pc: q35: Bump max_cpus to 4096 vcpus")
|
||||||
|
|
||||||
|
Since upstream Linux kernel commit
|
||||||
|
f10a570b093e6 ("KVM: x86: Add CONFIG_KVM_MAX_NR_VCPUS to allow up to 4096 vCPUs")
|
||||||
|
Linux kernel can support upto a maximum number of 4096 vcpus when MAXSMP is
|
||||||
|
enabled in the kernel. This upstream change has been backported to c9s kernel
|
||||||
|
already. Please see JIRA https://issues.redhat.com/browse/RHEL-11579 and the
|
||||||
|
following commit authored by Vitaly Kuznetsov:
|
||||||
|
a85f846be686b0a ("KVM: x86: Add CONFIG_KVM_MAX_NR_VCPUS to allow up to 4096 vCPUs")
|
||||||
|
|
||||||
|
At present, QEMU has been tested to correctly boot a linux guest with 4096
|
||||||
|
vcpus using edk2 that has the fixes corresponding to the following two upstream
|
||||||
|
edk2 PRs:
|
||||||
|
|
||||||
|
https://github.com/tianocore/edk2/pull/5410
|
||||||
|
https://github.com/tianocore/edk2/pull/5418
|
||||||
|
|
||||||
|
The changes corresponding to the above two upstream edk2 PRs has been included
|
||||||
|
in the downstream c9s edk2 with the following MR:
|
||||||
|
https://gitlab.com/redhat/centos-stream/src/edk2/-/merge_requests/59
|
||||||
|
|
||||||
|
So bump up the value max_cpus to 4096 for RHEL q35 machines versions 9.6 and
|
||||||
|
newer. Q35 RHEL machines versions 9.4 and older continue to support 710 maximum
|
||||||
|
vcpus as before for compatibility reasons.
|
||||||
|
|
||||||
|
See also https://gitlab.com/redhat/centos-stream/src/qemu-kvm/-/merge_requests/236
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
---
|
||||||
|
hw/i386/pc_q35.c | 5 ++++-
|
||||||
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
|
||||||
|
index 7606007bda..578f63524f 100644
|
||||||
|
--- a/hw/i386/pc_q35.c
|
||||||
|
+++ b/hw/i386/pc_q35.c
|
||||||
|
@@ -344,7 +344,7 @@ static void pc_q35_machine_options(MachineClass *m)
|
||||||
|
m->default_display = "std";
|
||||||
|
m->default_nic = "e1000e";
|
||||||
|
m->no_floppy = 1;
|
||||||
|
- m->max_cpus = 710;
|
||||||
|
+ m->max_cpus = 4096;
|
||||||
|
m->no_parallel = 1;
|
||||||
|
machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE);
|
||||||
|
machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE);
|
||||||
|
@@ -687,6 +687,9 @@ static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m)
|
||||||
|
{
|
||||||
|
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||||
|
pc_q35_rhel_machine_9_6_0_options(m);
|
||||||
|
+
|
||||||
|
+ /* older RHEL machines continue to support 710 vcpus */
|
||||||
|
+ m->max_cpus = 710;
|
||||||
|
m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)";
|
||||||
|
m->alias = NULL;
|
||||||
|
pcmc->smbios_stream_product = "RHEL";
|
||||||
|
--
|
||||||
|
2.39.3
|
||||||
|
|
@ -149,7 +149,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \
|
|||||||
Summary: QEMU is a machine emulator and virtualizer
|
Summary: QEMU is a machine emulator and virtualizer
|
||||||
Name: qemu-kvm
|
Name: qemu-kvm
|
||||||
Version: 9.1.0
|
Version: 9.1.0
|
||||||
Release: 2%{?rcrel}%{?dist}%{?cc_suffix}
|
Release: 3%{?rcrel}%{?dist}%{?cc_suffix}
|
||||||
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
|
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
|
||||||
# Epoch 15 used for RHEL 8
|
# Epoch 15 used for RHEL 8
|
||||||
# Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5)
|
# Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5)
|
||||||
@ -252,6 +252,22 @@ Patch55: kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch
|
|||||||
Patch56: kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch
|
Patch56: kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch
|
||||||
# For RHEL-60914 - Fail migration properly when put cpu register fails
|
# For RHEL-60914 - Fail migration properly when put cpu register fails
|
||||||
Patch57: kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch
|
Patch57: kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch
|
||||||
|
# For RHEL-11043 - [RFE] [HPEMC] [RHEL-9.6] qemu-kvm: support up to 4096 VCPUs
|
||||||
|
Patch58: kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch
|
||||||
|
# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration
|
||||||
|
Patch59: kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch
|
||||||
|
# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration
|
||||||
|
Patch60: kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch
|
||||||
|
# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration
|
||||||
|
Patch61: kvm-accel-kvm-refactor-dirty-ring-setup.patch
|
||||||
|
# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration
|
||||||
|
Patch62: kvm-KVM-Dynamic-sized-kvm-memslots-array.patch
|
||||||
|
# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration
|
||||||
|
Patch63: kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch
|
||||||
|
# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration
|
||||||
|
Patch64: kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch
|
||||||
|
# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration
|
||||||
|
Patch65: kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch
|
||||||
|
|
||||||
%if %{have_clang}
|
%if %{have_clang}
|
||||||
BuildRequires: clang
|
BuildRequires: clang
|
||||||
@ -289,6 +305,8 @@ BuildRequires: librbd-devel
|
|||||||
# We need both because the 'stap' binary is probed for by configure
|
# We need both because the 'stap' binary is probed for by configure
|
||||||
BuildRequires: systemtap
|
BuildRequires: systemtap
|
||||||
BuildRequires: systemtap-sdt-devel
|
BuildRequires: systemtap-sdt-devel
|
||||||
|
# Required as we use dtrace for trace backend
|
||||||
|
BuildRequires: /usr/bin/dtrace
|
||||||
# For VNC PNG support
|
# For VNC PNG support
|
||||||
BuildRequires: libpng-devel
|
BuildRequires: libpng-devel
|
||||||
# For virtiofs
|
# For virtiofs
|
||||||
@ -1316,6 +1334,23 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Nov 19 2024 Miroslav Rezanina <mrezanin@redhat.com> - 9.1.0-3
|
||||||
|
- kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch [RHEL-11043]
|
||||||
|
- kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch [RHEL-57682]
|
||||||
|
- kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch [RHEL-57682]
|
||||||
|
- kvm-accel-kvm-refactor-dirty-ring-setup.patch [RHEL-57682]
|
||||||
|
- kvm-KVM-Dynamic-sized-kvm-memslots-array.patch [RHEL-57682]
|
||||||
|
- kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch [RHEL-57682]
|
||||||
|
- kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch [RHEL-57682]
|
||||||
|
- kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch [RHEL-57682]
|
||||||
|
- kvm-Require-new-dtrace-package.patch [RHEL-67900]
|
||||||
|
- Resolves: RHEL-11043
|
||||||
|
([RFE] [HPEMC] [RHEL-9.6] qemu-kvm: support up to 4096 VCPUs)
|
||||||
|
- Resolves: RHEL-57682
|
||||||
|
(Bad migration performance when performing vGPU VM live migration )
|
||||||
|
- Resolves: RHEL-67900
|
||||||
|
(Failed to build qemu-kvm due to missing dtrace [rhel-9.6])
|
||||||
|
|
||||||
* Mon Nov 11 2024 Miroslav Rezanina <mrezanin@redhat.com> - 9.1.0-2
|
* Mon Nov 11 2024 Miroslav Rezanina <mrezanin@redhat.com> - 9.1.0-2
|
||||||
- kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch [RHEL-11424]
|
- kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch [RHEL-11424]
|
||||||
- kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch [RHEL-11424]
|
- kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch [RHEL-11424]
|
||||||
|
Loading…
Reference in New Issue
Block a user