Re: [Qemu-devel] [RFC] create a single workqueue for each vm to update vm irq routing table

Avi Kivity
2013-11-26T14:54:49Z

On 11/26/2013 04:46 PM, Paolo Bonzini wrote:
> Il 26/11/2013 15:36, Avi Kivity ha scritto:
>> No, this would be exactly the same code that is running now:
>>
>> mutex_lock(&kvm->irq_lock);
>> old = kvm->irq_routing;
>> kvm_irq_routing_update(kvm, new);
>> mutex_unlock(&kvm->irq_lock);
>>
>> synchronize_rcu();
>> kfree(old);
>> return 0;
>>
>> Except that the kfree would run in the call_rcu kernel thread instead of
>> the vcpu thread. But the vcpus already see the new routing table after
>> the rcu_assign_pointer that is in kvm_irq_routing_update.
>>
>> I understood the proposal was also to eliminate the synchronize_rcu(),
>> so while new interrupts would see the new routing table, interrupts
>> already in flight could pick up the old one.
> Isn't that always the case with RCU? (See my answer above: "the vcpus
> already see the new routing table after the rcu_assign_pointer that is
> in kvm_irq_routing_update").

With synchronize_rcu(), you have the additional guarantee that any
parallel accesses to the old routing table have completed. Since we
also trigger the irq from rcu context, you know that after
synchronize_rcu() you won't get any interrupts to the old destination
(see kvm_set_irq_inatomic()).

It's another question whether the hardware provides the same guarantee.

> If you eliminate the synchronize_rcu, new interrupts would see the new
> routing table, while interrupts already in flight will get a dangling
> pointer.

Sure, if you drop the synchronize_rcu(), you have to add call_rcu().