mirror of https://github.com/xemu-project/xemu.git
kvm: Add helper kvm_dirty_ring_init()
Due to multiple capabilities associated with the dirty ring for different architectures: KVM_CAP_DIRTY_{LOG_RING, LOG_RING_ACQ_REL} for x86 and arm64 separately. There will be more to be done in order to support the dirty ring for arm64. Lets add helper kvm_dirty_ring_init() to enable the dirty ring. With this, the code looks a bit clean. No functional change intended. Signed-off-by: Gavin Shan <gshan@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Tested-by: Zhenyu Zhang <zhenyzha@redhat.com> Message-Id: <20230509022122.20888-4-gshan@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
b20cc77692
commit
3794cb9485
|
@ -1462,6 +1462,50 @@ static int kvm_dirty_ring_reaper_init(KVMState *s)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int kvm_dirty_ring_init(KVMState *s)
|
||||||
|
{
|
||||||
|
uint32_t ring_size = s->kvm_dirty_ring_size;
|
||||||
|
uint64_t ring_bytes = ring_size * sizeof(struct kvm_dirty_gfn);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
s->kvm_dirty_ring_size = 0;
|
||||||
|
s->kvm_dirty_ring_bytes = 0;
|
||||||
|
|
||||||
|
/* Bail if the dirty ring size isn't specified */
|
||||||
|
if (!ring_size) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the max supported pages. Fall back to dirty logging mode
|
||||||
|
* if the dirty ring isn't supported.
|
||||||
|
*/
|
||||||
|
ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING);
|
||||||
|
if (ret <= 0) {
|
||||||
|
warn_report("KVM dirty ring not available, using bitmap method");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ring_bytes > ret) {
|
||||||
|
error_report("KVM dirty ring size %" PRIu32 " too big "
|
||||||
|
"(maximum is %ld). Please use a smaller value.",
|
||||||
|
ring_size, (long)ret / sizeof(struct kvm_dirty_gfn));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING, 0, ring_bytes);
|
||||||
|
if (ret) {
|
||||||
|
error_report("Enabling of KVM dirty ring failed: %s. "
|
||||||
|
"Suggested minimum value is 1024.", strerror(-ret));
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->kvm_dirty_ring_size = ring_size;
|
||||||
|
s->kvm_dirty_ring_bytes = ring_bytes;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void kvm_region_add(MemoryListener *listener,
|
static void kvm_region_add(MemoryListener *listener,
|
||||||
MemoryRegionSection *section)
|
MemoryRegionSection *section)
|
||||||
{
|
{
|
||||||
|
@ -2531,35 +2575,9 @@ static int kvm_init(MachineState *ms)
|
||||||
* Enable KVM dirty ring if supported, otherwise fall back to
|
* Enable KVM dirty ring if supported, otherwise fall back to
|
||||||
* dirty logging mode
|
* dirty logging mode
|
||||||
*/
|
*/
|
||||||
if (s->kvm_dirty_ring_size > 0) {
|
ret = kvm_dirty_ring_init(s);
|
||||||
uint64_t ring_bytes;
|
if (ret < 0) {
|
||||||
|
goto err;
|
||||||
ring_bytes = s->kvm_dirty_ring_size * sizeof(struct kvm_dirty_gfn);
|
|
||||||
|
|
||||||
/* Read the max supported pages */
|
|
||||||
ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING);
|
|
||||||
if (ret > 0) {
|
|
||||||
if (ring_bytes > ret) {
|
|
||||||
error_report("KVM dirty ring size %" PRIu32 " too big "
|
|
||||||
"(maximum is %ld). Please use a smaller value.",
|
|
||||||
s->kvm_dirty_ring_size,
|
|
||||||
(long)ret / sizeof(struct kvm_dirty_gfn));
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING, 0, ring_bytes);
|
|
||||||
if (ret) {
|
|
||||||
error_report("Enabling of KVM dirty ring failed: %s. "
|
|
||||||
"Suggested minimum value is 1024.", strerror(-ret));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->kvm_dirty_ring_bytes = ring_bytes;
|
|
||||||
} else {
|
|
||||||
warn_report("KVM dirty ring not available, using bitmap method");
|
|
||||||
s->kvm_dirty_ring_size = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue