Re: [PATCH 1/1] KVM: mark kvm->busses as rcu protected

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 07/07/2017 01:19 PM, Paolo Bonzini wrote:
> 
> 
> On 07/07/2017 12:58, Christian Borntraeger wrote:
>> mark kvm->busses as rcu protected and use the correct access
>> function everywhere.
>>
>> found by sparse
>> virt/kvm/kvm_main.c:3490:15: error: incompatible types in comparison expression (different address spaces)
>> virt/kvm/kvm_main.c:3509:15: error: incompatible types in comparison expression (different address spaces)
>> virt/kvm/kvm_main.c:3561:15: error: incompatible types in comparison expression (different address spaces)
>> virt/kvm/kvm_main.c:3644:15: error: incompatible types in comparison expression (different address spaces)
>>
>> Signed-off-by: Christian Borntraeger <borntraeger@xxxxxxxxxx>
>> ---
>>  include/linux/kvm_host.h |  2 +-
>>  virt/kvm/eventfd.c       |  8 +++++---
>>  virt/kvm/kvm_main.c      | 17 ++++++++++-------
>>  3 files changed, 16 insertions(+), 11 deletions(-)
>>
>> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
>> index 7c32905..220f251 100644
>> --- a/include/linux/kvm_host.h
>> +++ b/include/linux/kvm_host.h
>> @@ -404,7 +404,7 @@ struct kvm {
>>  	int last_boosted_vcpu;
>>  	struct list_head vm_list;
>>  	struct mutex lock;
>> -	struct kvm_io_bus *buses[KVM_NR_BUSES];
>> +	struct kvm_io_bus __rcu *buses[KVM_NR_BUSES];
>>  #ifdef CONFIG_HAVE_KVM_EVENTFD
>>  	struct {
>>  		spinlock_t        lock;
>> diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
>> index a8d5403..3e08b43 100644
>> --- a/virt/kvm/eventfd.c
>> +++ b/virt/kvm/eventfd.c
>> @@ -825,7 +825,7 @@ static int kvm_assign_ioeventfd_idx(struct kvm *kvm,
>>  	if (ret < 0)
>>  		goto unlock_fail;
>>  
>> -	kvm->buses[bus_idx]->ioeventfd_count++;
>> +	rcu_dereference_protected(kvm->buses[bus_idx], 1)->ioeventfd_count++;
> 
> Whenever possible, we should use (s)rcu_dereference_check and a better 
> predicate than "1".  In this case:
> 
> static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, int i)
> {
> 	struct kvm_io_bus **buses =
> 		srcu_dereference_check(kvm->buses, &kvm->srcu,
> 				       lockdep_is_held(&kvm->slots_lock));
> 	return buses[i];
> }

Hmm, now this makes me wonder.

does this
	struct kvm_io_bus __rcu *buses[KVM_NR_BUSES];

mark
**buses 
as rcu protected or does it mark each element of the array
iow
*buses[0]
*buses[1]
as rcu protected?

My code certainly assumes that each single point is protected,

So I would have done something like this on top

diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 3e08b43..91210ee 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -779,6 +779,12 @@ static enum kvm_bus ioeventfd_bus_from_flags(__u32 flags)
        return KVM_MMIO_BUS;
 }
 
+static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, int i)
+{
+       return srcu_dereference_check(kvm->buses[i], &kvm->srcu,
+                                     lockdep_is_held(&kvm->slots_lock));
+}
+
 static int kvm_assign_ioeventfd_idx(struct kvm *kvm,
                                enum kvm_bus bus_idx,
                                struct kvm_ioeventfd *args)
@@ -825,7 +831,7 @@ static int kvm_assign_ioeventfd_idx(struct kvm *kvm,
        if (ret < 0)
                goto unlock_fail;
 
-       rcu_dereference_protected(kvm->buses[bus_idx], 1)->ioeventfd_count++;
+       kvm_get_bus(kvm, bus_idx)->ioeventfd_count++;
        list_add_tail(&p->list, &kvm->ioeventfds);
 
        mutex_unlock(&kvm->slots_lock);


> (since you are at it, __kvm_memslots should also use srcu_dereference_check
> instead of rcu_dereference_check!).

Yes, will do a fixup for that patch.




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux