Skip to content

Commit

Permalink
KVM: eventfd: Use synchronize_srcu_expedited() on shutdown
Browse files Browse the repository at this point in the history
When hot-unplug a device which has many queues, and guest CPU will has
huge jitter, and unplugging is very slow.

It turns out synchronize_srcu() in irqfd_shutdown() caused the guest
jitter and unplugging latency, so replace synchronize_srcu() with
synchronize_srcu_expedited(), to accelerate the unplugging, and reduce
the guest OS jitter, this accelerates the VM reboot too.

Signed-off-by: Li RongQing <[email protected]>
Message-ID: <[email protected]>
[Call it just once in irqfd_resampler_shutdown. - Paolo]
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
lrq-max authored and bonzini committed Aug 13, 2024
1 parent 238d3d6 commit c9b35a6
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions virt/kvm/eventfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,19 @@ irqfd_resampler_shutdown(struct kvm_kernel_irqfd *irqfd)
mutex_lock(&kvm->irqfds.resampler_lock);

list_del_rcu(&irqfd->resampler_link);
synchronize_srcu(&kvm->irq_srcu);

if (list_empty(&resampler->list)) {
list_del_rcu(&resampler->link);
kvm_unregister_irq_ack_notifier(kvm, &resampler->notifier);
/*
* synchronize_srcu(&kvm->irq_srcu) already called
* synchronize_srcu_expedited(&kvm->irq_srcu) already called
* in kvm_unregister_irq_ack_notifier().
*/
kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
resampler->notifier.gsi, 0, false);
kfree(resampler);
} else {
synchronize_srcu_expedited(&kvm->irq_srcu);
}

mutex_unlock(&kvm->irqfds.resampler_lock);
Expand All @@ -126,7 +127,7 @@ irqfd_shutdown(struct work_struct *work)
u64 cnt;

/* Make sure irqfd has been initialized in assign path. */
synchronize_srcu(&kvm->irq_srcu);
synchronize_srcu_expedited(&kvm->irq_srcu);

/*
* Synchronize with the wait-queue and unhook ourselves to prevent
Expand Down Expand Up @@ -384,7 +385,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
}

list_add_rcu(&irqfd->resampler_link, &irqfd->resampler->list);
synchronize_srcu(&kvm->irq_srcu);
synchronize_srcu_expedited(&kvm->irq_srcu);

mutex_unlock(&kvm->irqfds.resampler_lock);
}
Expand Down Expand Up @@ -523,7 +524,7 @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
mutex_lock(&kvm->irq_lock);
hlist_del_init_rcu(&kian->link);
mutex_unlock(&kvm->irq_lock);
synchronize_srcu(&kvm->irq_srcu);
synchronize_srcu_expedited(&kvm->irq_srcu);
kvm_arch_post_irq_ack_notifier_list_update(kvm);
}

Expand Down Expand Up @@ -608,7 +609,7 @@ kvm_irqfd_release(struct kvm *kvm)

/*
* Take note of a change in irq routing.
* Caller must invoke synchronize_srcu(&kvm->irq_srcu) afterwards.
* Caller must invoke synchronize_srcu_expedited(&kvm->irq_srcu) afterwards.
*/
void kvm_irq_routing_update(struct kvm *kvm)
{
Expand Down

0 comments on commit c9b35a6

Please sign in to comment.