qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 0/2] aio: add aio_context_acquire() and aio_cont


From: Stefan Hajnoczi
Subject: Re: [Qemu-devel] [PATCH 0/2] aio: add aio_context_acquire() and aio_context_release()
Date: Wed, 9 Oct 2013 13:32:42 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

On Wed, Oct 09, 2013 at 12:16:47PM +0200, Paolo Bonzini wrote:
> Il 09/10/2013 11:55, Stefan Hajnoczi ha scritto:
> > aio_context_acquire() and aio_context_release() make it possible for 
> > multiple
> > threads to safely operate on a shared AioContext.  This is a prerequisite 
> > for
> > using the block layer outside the QEMU global mutex.
> > 
> > Imagine that a dataplane thread is performing I/O on behalf of the guest 
> > when
> > the user issues a monitor command that needs to access the BlockDriverState.
> > The monitor thread needs to acquire the AioContext before calling bdrv_*()
> > functions on it.  This prevents the dataplane thread from interfering with 
> > the
> > monitor thread.
> > 
> > There was a discussion in the RFC email thread about how to implement 
> > fairness:
> > each thread should get a turn to acquire the AioContext so that starvation 
> > is
> > avoided.
> > 
> > Paolo suggested doing what the QEMU main loop does today: drop the lock 
> > before
> > invoking ppoll(2).  It turns out that this is tricky since we want both 
> > threads
> > to be able to call aio_poll() simultaneously.  AioContext->pollfds[] 
> > currently
> > prevents two simultaneous aio_poll() calls since it is a shared resource.  
> > It's
> > also tricky to avoid deadlocks if two threads execute aio_poll() 
> > simulatenously
> > except by waking all threads each time *any* thread makes any progress.
> > 
> > I found the simplest solution is to implement RFifoLock, a recursive lock 
> > with
> > FIFO ordering.  This lock supports the semantics we need for the following
> > pattern:
> > 
> >   /* Event loop thread */
> >   while (running) {
> >       aio_context_acquire(ctx);
> >       aio_poll(ctx, true);
> >       aio_context_release(ctx);
> >   }
> > 
> >   /* Another thread */
> >   aio_context_acquire(ctx);
> >   bdrv_read(bs, 0x1000, buf, 1);
> >   aio_context_release(ctx);
> 
> Should bdrv_read itself call aio_context_acquire?  If not, what's the
> use of recursion?

Recursion is an artifact of our previous discussions.  In a few days I
should have explored enough use cases to know whether we need it or not
- I'm converting code to use acquire/release right now.

Will let you know once I've figured out if we really need it or not.

Stefan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]