From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52594) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zzo6F-0007im-RU for qemu-devel@nongnu.org; Fri, 20 Nov 2015 10:59:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zzo6C-0001wu-K5 for qemu-devel@nongnu.org; Fri, 20 Nov 2015 10:59:47 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39851) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zzo6C-0001wU-AS for qemu-devel@nongnu.org; Fri, 20 Nov 2015 10:59:44 -0500 References: <006e01d12377$0b9c2d40$22d487c0$@samsung.com> From: Paolo Bonzini Message-ID: <564F4366.90402@redhat.com> Date: Fri, 20 Nov 2015 16:59:34 +0100 MIME-Version: 1.0 In-Reply-To: <006e01d12377$0b9c2d40$22d487c0$@samsung.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH] memory: emulate ioeventfd List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Pavel Fedin , qemu-devel@nongnu.org Cc: "'Michael S. Tsirkin'" On 20/11/2015 10:37, Pavel Fedin wrote: > The ioeventfd mechanism is used by vhost, dataplane, and virtio-pci to > turn guest MMIO/PIO writes into eventfd file descriptor events. This > allows arbitrary threads to be notified when the guest writes to a > specific MMIO/PIO address. > > qtest and TCG do not support ioeventfd because memory writes are not > checked against registered ioeventfds in QEMU. This patch implements > this in memory_region_dispatch_write() so qtest can use ioeventfd. > > Also this patch fixes vhost aborting on some misconfigured old kernels > like 3.18.0 on ARM. It is possible to explicitly enable CONFIG_EVENTFD > in expert settings, while MMIO binding support in KVM will still be > missing. > > Signed-off-by: Stefan Hajnoczi > Signed-off-by: Pavel Fedin > --- > RFC => PATCH: > - Add !kvm_eventfds_enabled() conditions to bypass eventfd injection when not needed > - Renamed "ioeventfd" to "eventfd", just to make words shorter > - Add a one-shot warning about missing MMIO bindings in KVM > --- > kvm-all.c | 6 ++++-- > memory.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 46 insertions(+), 2 deletions(-) > > diff --git a/kvm-all.c b/kvm-all.c > index ddb007a..70f5cec 100644 > --- a/kvm-all.c > +++ b/kvm-all.c > @@ -1633,8 +1633,10 @@ static int kvm_init(MachineState *ms) > > kvm_state = s; > > - s->memory_listener.listener.eventfd_add = kvm_mem_ioeventfd_add; > - s->memory_listener.listener.eventfd_del = kvm_mem_ioeventfd_del; > + if (kvm_eventfds_allowed) { > + s->memory_listener.listener.eventfd_add = kvm_mem_ioeventfd_add; > + s->memory_listener.listener.eventfd_del = kvm_mem_ioeventfd_del; > + } > s->memory_listener.listener.coalesced_mmio_add = kvm_coalesce_mmio_region; > s->memory_listener.listener.coalesced_mmio_del = kvm_uncoalesce_mmio_region; > > diff --git a/memory.c b/memory.c > index e193658..4d138fb 100644 > --- a/memory.c > +++ b/memory.c > @@ -18,12 +18,14 @@ > #include "exec/ioport.h" > #include "qapi/visitor.h" > #include "qemu/bitops.h" > +#include "qemu/error-report.h" > #include "qom/object.h" > #include "trace.h" > #include > > #include "exec/memory-internal.h" > #include "exec/ram_addr.h" > +#include "sysemu/kvm.h" > #include "sysemu/sysemu.h" > > //#define DEBUG_UNASSIGNED > @@ -1141,6 +1143,32 @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr, > return r; > } > > +/* Return true if an eventfd was signalled */ > +static bool memory_region_dispatch_write_eventfds(MemoryRegion *mr, > + hwaddr addr, > + uint64_t data, > + unsigned size, > + MemTxAttrs attrs) > +{ > + MemoryRegionIoeventfd ioeventfd = { > + .addr = addrrange_make(int128_make64(addr), int128_make64(size)), > + .data = data, > + }; > + unsigned i; > + > + for (i = 0; i < mr->ioeventfd_nb; i++) { > + ioeventfd.match_data = mr->ioeventfds[i].match_data; > + ioeventfd.e = mr->ioeventfds[i].e; > + > + if (memory_region_ioeventfd_equal(ioeventfd, mr->ioeventfds[i])) { > + event_notifier_set(ioeventfd.e); > + return true; > + } > + } > + > + return false; > +} > + > MemTxResult memory_region_dispatch_write(MemoryRegion *mr, > hwaddr addr, > uint64_t data, > @@ -1154,6 +1182,11 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr, > > adjust_endianness(mr, &data, size); > > + if ((!kvm_eventfds_enabled()) && > + memory_region_dispatch_write_eventfds(mr, addr, data, size, attrs)) { > + return MEMTX_OK; > + } > + > if (mr->ops->write) { > return access_with_adjusted_size(addr, &data, size, > mr->ops->impl.min_access_size, > @@ -1672,6 +1705,8 @@ void memory_region_clear_global_locking(MemoryRegion *mr) > mr->global_locking = false; > } > > +static bool userspace_eventfd_warning; > + > void memory_region_add_eventfd(MemoryRegion *mr, > hwaddr addr, > unsigned size, > @@ -1688,6 +1723,13 @@ void memory_region_add_eventfd(MemoryRegion *mr, > }; > unsigned i; > > + if (kvm_enabled() && (!(kvm_eventfds_enabled() || > + userspace_eventfd_warning))) { > + userspace_eventfd_warning = true; > + error_report("Using eventfd without MMIO binding in KVM. " > + "Suboptimal performance expected"); > + } > + > if (size) { > adjust_endianness(mr, &mrfd.data, size); > } > Queued for 2.6. Paolo