From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sasha Levin Subject: Re: [PATCH 5/5] ioeventfd: Introduce KVM_IOEVENTFD_FLAG_SOCKET Date: Wed, 06 Jul 2011 15:58:54 +0300 Message-ID: <1309957134.15123.10.camel@sasha> References: <1309927078-5983-1-git-send-email-levinsasha928@gmail.com> <1309927078-5983-5-git-send-email-levinsasha928@gmail.com> <4E145783.2000605@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Cc: kvm@vger.kernel.org, Ingo Molnar , Marcelo Tosatti , "Michael S. Tsirkin" , Pekka Enberg To: Avi Kivity Return-path: Received: from mail-wy0-f174.google.com ([74.125.82.174]:60832 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751290Ab1GFM67 (ORCPT ); Wed, 6 Jul 2011 08:58:59 -0400 Received: by wyg8 with SMTP id 8so4647991wyg.19 for ; Wed, 06 Jul 2011 05:58:58 -0700 (PDT) In-Reply-To: <4E145783.2000605@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: On Wed, 2011-07-06 at 15:39 +0300, Avi Kivity wrote: > On 07/06/2011 07:37 AM, Sasha Levin wrote: > > The new flag allows passing a connected socket instead of an > > eventfd to be notified of writes or reads to the specified memory region. > > > > Instead of signaling an event, On write - the value written to the memory > > region is written to the pipe. > > On read - a notification of the read is sent to the host, and a response > > is expected with the value to be 'read'. > > > > Using a socket instead of an eventfd is usefull when any value can be > > written to the memory region but we're interested in recieving the > > actual value instead of just a notification. > > > > A simple example for practical use is the serial port. we are not > > interested in an exit every time a char is written to the port, but > > we do need to know what was written so we could handle it on the guest. > > > > > > > > @@ -534,6 +607,7 @@ ioeventfd_read(struct kvm_io_device *this, gpa_t addr, int len, > > void *val) > > { > > struct _ioeventfd *p = to_ioeventfd(this); > > + struct kvm_ioeventfd_data data; > > > > /* Exit if signaling on reads isn't requested */ > > if (!p->track_reads) > > @@ -542,7 +616,21 @@ ioeventfd_read(struct kvm_io_device *this, gpa_t addr, int len, > > if (!ioeventfd_in_range(p, addr, len, val)) > > return -EOPNOTSUPP; > > > > - eventfd_signal(p->eventfd, 1); > > + data = (struct kvm_ioeventfd_data) { > > + .addr = addr, > > + .len = len, > > + .is_write = 0, > > + }; > > + > > + if (p->sock) { > > + socket_write(p->sock,&data, sizeof(data)); > > + socket_read(p->sock,&data, sizeof(data)); > > + set_val(val, len, data.data); > > + } else { > > + set_val(val, len, p->datamatch); > > + eventfd_signal(p->eventfd, 1); > > + } > > + > > return 0; > > } > > If there are two reads on the same ioeventfd range, then the responses > can mix up. Need to make sure we get the right response. > > Note that a mutex on the ioeventfd structure is insufficient, since the > same socket may be used for multiple ranges. > > One way out is to require that sockets not be shared among vcpus (there > can be only one outstanding read per vcpu). It seems heavy handed though. > What about something as follows: This requires an addition of a mutex to struct ioeventfd. 1. When adding a new ioeventfd, scan exiting ioeventfds (we already do it anyway) and check whether another ioeventfd is using the socket already. 2. If the existing ioeventfd doesn't have a mutex assigned, create a new mutex and assign it to both ioeventfds. 3. If the existing ioeventfd already has a mutex assigned, copy it to the new ioeventfd. 4. When removing an ioeventfd, do everything the other way around :) This mutex can be used to lock the write/read pair. -- Sasha.