From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=44025 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PiOTo-0004jX-JC for qemu-devel@nongnu.org; Thu, 27 Jan 2011 04:49:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PiOTe-0006xS-7v for qemu-devel@nongnu.org; Thu, 27 Jan 2011 04:49:19 -0500 Received: from mx1.redhat.com ([209.132.183.28]:1030) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PiOTd-0006xN-W1 for qemu-devel@nongnu.org; Thu, 27 Jan 2011 04:49:18 -0500 Message-ID: <4D413F98.4010205@redhat.com> Date: Thu, 27 Jan 2011 11:49:12 +0200 From: Avi Kivity MIME-Version: 1.0 Subject: Re: [Qemu-devel] [RFC][PATCH 11/12] qcow2: Convert qcow2 to use coroutines for async I/O References: <1295688567-25496-1-git-send-email-stefanha@linux.vnet.ibm.com> <1295688567-25496-12-git-send-email-stefanha@linux.vnet.ibm.com> <4D40406B.2070302@redhat.com> <4D4042A8.2040903@redhat.com> <4D4046EF.3050108@codemonkey.ws> <4D40481E.9040309@redhat.com> <4D404B9F.7040801@codemonkey.ws> <4D404E1F.50809@redhat.com> <4D4055FB.6090104@codemonkey.ws> <4D413A88.2060204@redhat.com> In-Reply-To: <4D413A88.2060204@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Kevin Wolf Cc: Stefan Hajnoczi , qemu-devel@nongnu.org On 01/27/2011 11:27 AM, Kevin Wolf wrote: > Well, but in the case of qcow2, you don't want to have a big mutex > around everything. We perfectly know which parts are asynchronous and > which are synchronous, so we'd want to do it finer grained from the > beginning. Yes we do. And the way I proposed it, the new mutex does not introduce any new serialization. To repeat, for every qcow2 callback or completion X (not qcow2 read or write operation), we transform it in the following manner: 1. Rename X into do_X. If X is called directly from within qcow2, change the call to do_x. Create a new X which simply calls do_X(). This change is purely textual and doesn't affect runtime at all. 2. Change X to X() { create a coroutine pack arguments to X in a structure schedule the coroutine to execute a new function call_X with the structure as argument wait for the coroutine to complete unpack the result (if any) dispose of the coroutine return the result } call_X() { unpack arguments co_mutex_lock(&bs->mutex) result = do_X() co_mutex_unlock(&bs->mutex) pack result } (in the case of aio_X callbacks, we return a fake AIOCB: aio_X() { allocate AIOCB allocate coroutine pack arguments to X, and fake AIOCB in a structure schedule the coroutine to execute call_X with the structure as argument return fake AIOCB } call_aio_X() { unpack arguments co_mutex_lock(&bs->mutex) do_X() co_mutex_unlock(&bs->mutex) } and change the completion to complete the fake AIOCB ) The result of this transformation is: - if X1 executed without blocking, it still executes without blocking, except for the case below - if X2 blocked, it will serialize any X1 which doesn't, but it will no longer block the vcpu thread We could do this transformation in the block layer, as it doesn't involve qcow2 at all. I don't think that's a good idea, though, as qcow2 would be the only beneficiary and it would be harder to further evolve qcow2. -- error compiling committee.c: too many arguments to function