From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44650) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X7LTJ-0000gS-2t for qemu-devel@nongnu.org; Wed, 16 Jul 2014 05:26:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X7LTB-0005jB-Dt for qemu-devel@nongnu.org; Wed, 16 Jul 2014 05:25:57 -0400 Received: from mx1.redhat.com ([209.132.183.28]:20105) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X7LTB-0005j4-64 for qemu-devel@nongnu.org; Wed, 16 Jul 2014 05:25:49 -0400 Date: Wed, 16 Jul 2014 10:25:39 +0100 From: "Dr. David Alan Gilbert" Message-ID: <20140716092538.GD2514@work-vm> References: <1404495717-4239-1-git-send-email-dgilbert@redhat.com> <1404495717-4239-16-git-send-email-dgilbert@redhat.com> <53B7D2B8.7000002@redhat.com> <20140707143539.GB3443@work-vm> <53BAB466.8060609@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <53BAB466.8060609@redhat.com> Subject: Re: [Qemu-devel] [PATCH 15/46] Rework loadvm path for subloops List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini Cc: aarcange@redhat.com, yamahata@private.email.ne.jp, quintela@redhat.com, qemu-devel@nongnu.org, lilei@linux.vnet.ibm.com * Paolo Bonzini (pbonzini@redhat.com) wrote: > Il 07/07/2014 16:35, Dr. David Alan Gilbert ha scritto: > >* Paolo Bonzini (pbonzini@redhat.com) wrote: > >>Il 04/07/2014 19:41, Dr. David Alan Gilbert (git) ha scritto: > >>>From: "Dr. David Alan Gilbert" > >>> > >>>Postcopy needs to have two migration streams loading concurrently; > >>>one from memory (with the device state) and the other from the fd > >>>with the memory transactions. > >> > >>Can you explain this? > >> > >>I would have though the order is > >> > >> precopy RAM and everything > >> prepare postcopy RAM ("sent && dirty" bitmap) > >> finish precopy non-RAM > >> finish devices > >> postcopy RAM > >> > >>Why do you need to have all the packaging stuff and a separate memory-based > >>migration stream for devices? I'm sure I'm missing something. :) > > > >The thing you're missing is the details of 'finish devices'. > >The device emulation may access guest memory as part of loading it's > >state, so you can't successfully complete 'finish devices' without > >having the 'postcopy RAM' available to provide pages. > > I see. Can you document the flow (preferrably as a reply to this email > _and_ in docs/ when you send v2 of the code :))? I thought I documented enough in the docs/migration.txt stuff in the last patch (see the 'Postcopy states' section); however lets see if I the following is better: ---- Postcopy stream Loading of device data may cause the device emulation to access guest RAM that may trigger faults that have to be resolved by the source, as such the migration stream has to be able to respond with page data *during* the device load, and hence the device data has to be read from the stream completely before the device load begins to free the stream up. This is acheived by 'packaging' the device data into a blob that's read in one go. Source behaviour Until postcopy is entered the migration stream is identical to normal postcopy, except for the addition of a 'postcopy advise' command at the beginning to let the destination know that postcopy might happen. When postcopy starts the source sends the page discard data and then forms the 'package' containing: Command: 'postcopy ram listen' The device state A series of sections, identical to the precopy streams device state stream containing everything except postcopiable devices (i.e. RAM) Command: 'postcopy ram run' The 'package' is sent as the data part of a Command: 'CMD_PACKAGED', and the contents are formatted in the same way as the main migration stream. Destination behaviour Initially the destination looks the same as precopy, with a single thread reading the migration stream; the 'postcopy advise' and 'discard' commands are processed to change the way RAM is managed, but don't affect the stream processing. ------------------------------------------------------------------------------ 1 2 3 4 5 6 7 main -----DISCARD-CMD_PACKAGED ( LISTEN DEVICE DEVICE DEVICE RUN ) thread | | | (page request) | \___ v \ listen thread: --- page -- page -- page -- page -- page -- a b c ------------------------------------------------------------------------------ On receipt of CMD_PACKAGED (1) All the data associated with the package - the ( ... ) section in the diagram - is read into memory (into a QEMUSizedBuffer), and the main thread recurses into qemu_loadvm_state_main to process the contents of the package (2) which contains commands (3,6) and devices (4...) On receipt of 'postcopy ram listen' - 3 -(i.e. the 1st command in the package) a new thread (a) is started that takes over servicing the migration stream, while the main thread carries on loading the package. It loads normal background page data (b) but if during a device load a fault happens (5) the returned page (c) is loaded by the listen thread allowing the main threads device load to carry on. The last thing in the CMD_PACKAGED is a 'RUN' command (6) letting the destination CPUs start running. At the end of the CMD_PACKAGED (7) the main thread returns to normal running behaviour and is no longer used by migration, while the listen thread carries on servicing page data until the end of migration. ---- Is that any better? Dave P.S. I know of at least one bug in this code at the moment, it happens on a VM that doesn't have many dirty pages where all the pages are transmitted, and hence the listen thread finishes, before the main thread gets to 'run'. > From my cursory read of the code it is something like this on the source: > > finish precopy non-RAM > start RAM postcopy > for each device > pack up data > send it to destination > > and on the destination: > > while source sends packet > pick up packet atomically > pass the packet to device loader > (while the loader works, userfaultfd does background magic) > > But something is missing still, either some kind of ack is needed between > device data sends or userfaultfd needs to be able to process device data > packets. > > Paolo > > >Thus you need to be able to start up 'postcopy RAM' before 'finish devices' > >has completed, and you can't do that if 'finish devices' is still stuffing > >data down the fd. > > > >Now, if hypothetically you had: > > 1) A migration format that let you separate out device state so that you > >could load all the state of the device off the fd without calling the device > >IO code. > > 2) All devices were good and didn't touch guest memory while loading their > >state. > > > >then you could avoid this complexity. However, if you look at how Stefan's > >BER code tried to do 1 (which I don't do in my way of doing it), it was by > >using the same trick of stuffing the device data into a dummy memory file > >to find out the size of the data. And I'm not convinced (2) will happen > >this century. > > > >>Paolo > > > >Dave > >-- > >Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK > > > -- Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK