On Thu, Nov 17, 2011 at 10:50 PM, <zanghongyong@xxxxxxxxxx> wrote: > From: Hongyong Zang <zanghongyong@xxxxxxxxxx> > > This patch, adds a PIO BAR3 for guest notifying qemu. And we find the new notification way of PIO BAR3 reduces 30% time in comparison with the original MMIO BAR0 way. Come to think of it, should we bump the PIO to BAR4 so that the shared memory region could be made a 64-bit BAR and therefore take up BAR2 and BAR3? > > Signed-off-by: Hongyong Zang <zanghongyong@xxxxxxxxxx> > --- > hw/ivshmem.c | 24 ++++++++++++++++++++++-- > kvm-all.c | 23 +++++++++++++++++++++++ > kvm.h | 1 + > 3 files changed, 46 insertions(+), 2 deletions(-) > > diff --git a/hw/ivshmem.c b/hw/ivshmem.c > index 242fbea..031cdd8 100644 > --- a/hw/ivshmem.c > +++ b/hw/ivshmem.c > @@ -29,6 +29,7 @@ > #define IVSHMEM_MASTER 1 > > #define IVSHMEM_REG_BAR_SIZE 0x100 > +#define IVSHIO_REG_BAR_SIZE 0x10 > > //#define DEBUG_IVSHMEM > #ifdef DEBUG_IVSHMEM > @@ -57,8 +58,10 @@ typedef struct IVShmemState { > CharDriverState **eventfd_chr; > CharDriverState *server_chr; > MemoryRegion ivshmem_mmio; > + MemoryRegion ivshmem_pio; > > pcibus_t mmio_addr; > + pcibus_t pio_addr; > /* We might need to register the BAR before we actually have the memory. > * So prepare a container MemoryRegion for the BAR immediately and > * add a subregion when we have the memory. > @@ -234,7 +237,7 @@ static uint64_t ivshmem_io_read(void *opaque, target_phys_addr_t addr, > return ret; > } > > -static const MemoryRegionOps ivshmem_mmio_ops = { > +static const MemoryRegionOps ivshmem_io_ops = { > .read = ivshmem_io_read, > .write = ivshmem_io_write, > .endianness = DEVICE_NATIVE_ENDIAN, > @@ -348,6 +351,8 @@ static void close_guest_eventfds(IVShmemState *s, int posn) > for (i = 0; i < guest_curr_max; i++) { > kvm_set_ioeventfd_mmio_long(s->peers[posn].eventfds[i], > s->mmio_addr + DOORBELL, (posn << 16) | i, 0); > + kvm_set_ioeventfd_pio_long(s->peers[posn].eventfds[i], > + s->pio_addr + DOORBELL, (posn << 16) | i, 0); > close(s->peers[posn].eventfds[i]); > } > > @@ -367,6 +372,12 @@ static void setup_ioeventfds(IVShmemState *s) { > true, > (i << 16) | j, > s->peers[i].eventfds[j]); > + memory_region_add_eventfd(&s->ivshmem_pio, > + DOORBELL, > + 4, > + true, > + (i << 16) | j, > + s->peers[i].eventfds[j]); > } > } > } > @@ -495,6 +506,10 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags) > (incoming_posn << 16) | guest_max_eventfd, 1) < 0) { > fprintf(stderr, "ivshmem: ioeventfd not available\n"); > } > + if (kvm_set_ioeventfd_pio_long(incoming_fd, s->pio_addr + DOORBELL, > + (incoming_posn << 16) | guest_max_eventfd, 1) < 0) { > + fprintf(stderr, "ivshmem: ioeventfd not available\n"); > + } > } > > return; > @@ -656,8 +671,10 @@ static int pci_ivshmem_init(PCIDevice *dev) > > s->shm_fd = 0; > > - memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s, > + memory_region_init_io(&s->ivshmem_mmio, &ivshmem_io_ops, s, > "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE); > + memory_region_init_io(&s->ivshmem_pio, &ivshmem_io_ops, s, > + "ivshmem-pio", IVSHIO_REG_BAR_SIZE); > > if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { > setup_ioeventfds(s); > @@ -666,6 +683,8 @@ static int pci_ivshmem_init(PCIDevice *dev) > /* region for registers*/ > pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, > &s->ivshmem_mmio); > + pci_register_bar(&s->dev, 3, PCI_BASE_ADDRESS_SPACE_IO, > + &s->ivshmem_pio); > > memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size); > > @@ -742,6 +761,7 @@ static int pci_ivshmem_uninit(PCIDevice *dev) > IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); > > memory_region_destroy(&s->ivshmem_mmio); > + memory_region_destroy(&s->ivshmem_pio); > memory_region_del_subregion(&s->bar, &s->ivshmem); > memory_region_destroy(&s->ivshmem); > memory_region_destroy(&s->bar); > diff --git a/kvm-all.c b/kvm-all.c > index 5d500e1..737c2e2 100644 > --- a/kvm-all.c > +++ b/kvm-all.c > @@ -1396,6 +1396,29 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, uint32_t val, bool assign > return 0; > } > > +int kvm_set_ioeventfd_pio_long(int fd, uint32_t addr, uint32_t val, bool assign) > +{ > + struct kvm_ioeventfd kick = { > + .datamatch = val, > + .addr = addr, > + .len = 4, > + .flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO, > + .fd = fd, > + }; > + int r; > + if (!kvm_enabled()) { > + return -ENOSYS; > + } > + if (!assign) { > + kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; > + } > + r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick); > + if (r < 0) { > + return r; > + } > + return 0; > +} > + > int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign) > { > struct kvm_ioeventfd kick = { > diff --git a/kvm.h b/kvm.h > index b15e1dd..c2373c9 100644 > --- a/kvm.h > +++ b/kvm.h > @@ -198,6 +198,7 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign) > > int kvm_set_irqfd(int gsi, int fd, bool assigned); > > +int kvm_set_ioeventfd_pio_long(int fd, uint32_t adr, uint32_t val, bool assign); > int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool assign); > > typedef struct KVMMsiMessage { > -- > 1.7.1 > -- 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