Re: [PATCH v3] kvm: Use a bitmap for tracking used GSIs

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

 



On Wed, 2009-05-13 at 11:30 +0800, Yang, Sheng wrote:
> On Wednesday 13 May 2009 06:07:15 Alex Williamson wrote:
> > We're currently using a counter to track the most recent GSI we've
> > handed out.  This quickly hits KVM_MAX_IRQ_ROUTES when using device
> > assignment with a driver that regularly toggles the MSI enable bit.
> > This can mean only a few minutes of usable run time.  Instead, track
> > used GSIs in a bitmap.
> >
> > Signed-off-by: Alex Williamson <alex.williamson@xxxxxx>
> > ---
> >
> >  v2: Added mutex to protect gsi bitmap
> >  v3: Updated for comments from Michael Tsirkin
> >      No longer depends on "[PATCH] kvm: device-assignment: Catch GSI
> > overflow"
> >
> >  hw/device-assignment.c  |    4 ++
> >  kvm/libkvm/kvm-common.h |    4 ++
> >  kvm/libkvm/libkvm.c     |   83
> > +++++++++++++++++++++++++++++++++++++++++------ kvm/libkvm/libkvm.h     |  
> > 10 ++++++
> >  4 files changed, 88 insertions(+), 13 deletions(-)
> >
> > diff --git a/hw/device-assignment.c b/hw/device-assignment.c
> > index a7365c8..a6cc9b9 100644
> > --- a/hw/device-assignment.c
> > +++ b/hw/device-assignment.c
> > @@ -561,8 +561,10 @@ static void free_dev_irq_entries(AssignedDevice *dev)
> >  {
> >      int i;
> >
> > -    for (i = 0; i < dev->irq_entries_nr; i++)
> > +    for (i = 0; i < dev->irq_entries_nr; i++) {
> >          kvm_del_routing_entry(kvm_context, &dev->entry[i]);
> > +        kvm_free_irq_route_gsi(kvm_context, dev->entry[i].gsi);
> > +    }
> >      free(dev->entry);
> >      dev->entry = NULL;
> >      dev->irq_entries_nr = 0;
> > diff --git a/kvm/libkvm/kvm-common.h b/kvm/libkvm/kvm-common.h
> > index 591fb53..4b3cb51 100644
> > --- a/kvm/libkvm/kvm-common.h
> > +++ b/kvm/libkvm/kvm-common.h
> > @@ -66,8 +66,10 @@ struct kvm_context {
> >  #ifdef KVM_CAP_IRQ_ROUTING
> >  	struct kvm_irq_routing *irq_routes;
> >  	int nr_allocated_irq_routes;
> > +	void *used_gsi_bitmap;
> > +	int max_gsi;
> > +	pthread_mutex_t gsi_mutex;
> >  #endif
> > -	int max_used_gsi;
> >  };
> >
> >  int kvm_alloc_kernel_memory(kvm_context_t kvm, unsigned long memory,
> > diff --git a/kvm/libkvm/libkvm.c b/kvm/libkvm/libkvm.c
> > index ba0a5d1..3d7ab75 100644
> > --- a/kvm/libkvm/libkvm.c
> > +++ b/kvm/libkvm/libkvm.c
> > @@ -35,6 +35,7 @@
> >  #include <errno.h>
> >  #include <sys/ioctl.h>
> >  #include <inttypes.h>
> > +#include <pthread.h>
> >  #include "libkvm.h"
> >
> >  #if defined(__x86_64__) || defined(__i386__)
> > @@ -65,6 +66,8 @@
> >  int kvm_abi = EXPECTED_KVM_API_VERSION;
> >  int kvm_page_size;
> >
> > +static inline void set_bit(uint32_t *buf, unsigned int bit);
> > +
> >  struct slot_info {
> >  	unsigned long phys_addr;
> >  	unsigned long len;
> > @@ -286,6 +289,9 @@ kvm_context_t kvm_init(struct kvm_callbacks *callbacks,
> >  	int fd;
> >  	kvm_context_t kvm;
> >  	int r;
> > +#ifdef KVM_CAP_IRQ_ROUTING
> > +	int gsi_count, gsi_bytes, i;
> > +#endif
> >
> >  	fd = open("/dev/kvm", O_RDWR);
> >  	if (fd == -1) {
> > @@ -322,6 +328,27 @@ kvm_context_t kvm_init(struct kvm_callbacks
> > *callbacks, kvm->dirty_pages_log_all = 0;
> >  	kvm->no_irqchip_creation = 0;
> >  	kvm->no_pit_creation = 0;
> > +#ifdef KVM_CAP_IRQ_ROUTING
> > +	pthread_mutex_init(&kvm->gsi_mutex, NULL);
> > +
> > +	gsi_count = kvm_get_gsi_count(kvm);
> > +	/* Round up so we can search ints using ffs */
> > +	gsi_bytes = (gsi_count + 31) / 32;
> 
> CMIW, should it be gsi_bytes = (gsi_count + 7) / 8? This looks like bits-to-
> int. 

Oops, I missed a multiplier in there.  What you have would be correct
for rounding up to a byte, but we really want to round up to an int, so
I need to factor in a bytes/int, which gives me this:

gsi_bytes = ((gsi_count + 31) / 32) * 4;

Then the rest works out correctly.  Thanks,

Alex

> > +	kvm->used_gsi_bitmap = malloc(gsi_bytes);
> > +	if (!kvm->used_gsi_bitmap) {
> > +		pthread_mutex_unlock(&kvm->gsi_mutex);
> > +		goto out_close;
> > +	}
> > +	memset(kvm->used_gsi_bitmap, 0, gsi_bytes);
> > +	kvm->max_gsi = gsi_bytes * 8;
> 
> So max_gsi = gsi_count / 4?


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[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