qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: Eric Blake <eblake@redhat.com>, qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Peter Lieven <pl@kamp.de>,
	Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v2 21/21] iotests: Add test for different refcount widths
Date: Thu, 20 Nov 2014 15:03:39 +0100	[thread overview]
Message-ID: <546DF4BB.9040302@redhat.com> (raw)
In-Reply-To: <546C3022.9070701@redhat.com>

On 2014-11-19 at 06:52, Eric Blake wrote:
> On 11/18/2014 01:26 PM, Eric Blake wrote:
>
>> Now, in response to your question about some other 3-pass inducing
>> pattern, let's think back to v1, where you questioned what would happen
>> if a hole in the reftable gets turned into data due to a later
>> allocation.  Let's see if I can come up with a scenario for that...
>>
>> Let's stick with a cluster size of 512, and use 32-bit and 64-bit widths
>> as our two sizes.  If we downsize from 64 to 32 bits, then every two
>> refblock clusters in the old table results in one call to operation()
>> for the new table; conversely, if we upsize, then every refblock cluster
>> in the old table gives two calls to operation() in the new table.  The
>> trick at hand is to come up with some image where we punch a hole so
>> that on the first pass, we call operation() with refblock_empty true for
>> one iteration (necessarily a call later than the first, since the image
>> header guarantees the first refblock is not empty), but where we have
>> data after the hole, where it is the later data that triggers the
>> allocation that will finally start to fill the hole.
>>
>> How about starting with an image that occupies between 1.5 and 2
>> refblocks worth of 32-width clusters (so an image anywhere between 193
>> and 256 clusters, or between 98816 and 131072 bytes).  You should be
>> able to figure out how many clusters this consumes for L1, L2, plus 1
>> for header, reftable, and 2 for refblocks, in order to figure out how
>> many remaining clusters are dedicated to data; ideally, the data
>> clusters are contiguous, and occupy a swath that covers at least
>> clusters 126 through 192.  Widening to 64-bit width will require 4
>> refblocks instead of 2, if all refblocks are needed.  But the whole idea
>> of punching a hole is that we don't need a refblock if it will be
>> all-zero entries.  So take this original image, and discard the data
>> clusters from physical index 126 through 192, (this is NOT the data
>> visible at guest offset 31744, but whatever actual offset of guest data
>> that maps to physical offset 31744).  The old reftable now looks like {
>> refblock_o1 [0-125 occupied, 126 and 127 empty], refblock_o2 [128-191
>> empty, 192-whatever occupied, tail empty] }.  With no allocations
>> required, this would in turn would map to the following new refblocks: {
>> refblock_n1 [0-64 occupied], refblock_n2 [65-125 occupied, 126-127
>> empty], NULL, refblock_n4 [192-whatever occupied] }.  Note that we do
>> not need to allocate refblock_n3 because of the hole in the old
>> refblock; we DO end up allocating three refblocks, but in the sequence
>> of things, refblock_n1 and refblock_n2 are allocated while we are
>> visiting refblock_o1 and still fit in refblock_o1, while refblock_n4 is
>> not allocated until after we have already passed over the first half of
>> refblock_o2.
>>
>> Thus, the second walk over the image will see that we need to allocate
>> refblock_n3 because it now contains entries (in particular, the entry
>> for refblock_n4, but also the 1-cluster entry for the proposed reftable
>> that is allocated between the walks).  So, while your test used the
>> allocation of the reftable as the spillover point, my scenario here uses
>> the allocation of later refblocks as the spillover point that got missed
>> during the first iteration.
>>
> Oops,...
>
>> which means the reftable now looks like { refblock1, NULL, refblock3,
>> NULL... }; and where refblock1 now has at least two free entries
>> (possibly three, if the just-freed refblock2 happened to live before
>> cluster 62).  is we can also free refblock2
>>
> ...forgot to delete these random thoughts that I typed up but no longer
> needed after reworking the above text.
>
> At any rate, I'm not certain we can come up with a four-pass scenario;
> if it is even possible, it would be quite complex.

[snip] (But rest assured, I read it all ;-))

> At this point, I've spent far too long writing this email.  I haven't
> completely ruled out the possibility of a corner case needing four
> passes through the do loop, but the image sizes required to get there
> are starting to be quite large compared to your simpler test of needing
> three passes through the do loop.

Right, see test 026. Without an SSD, it takes more than ten minutes, not 
least because it tests resizing the reftable which means writing a lot 
of data to an image with 512 byte clusters.

> I won't be bothered if we call it
> good, and quit trying to come up with any other "interesting" allocation
> sequencing.

The problem is, in my opinion, that we won't gain a whole lot from 
proving that there are cases where you need a fourth pass and test these 
cases. Fundamentally, they are not different from cases with three 
passes (technically, not even different from two pass cases). You scan 
through the refcounts, you detect that you need refblocks which you have 
not yet allocated, you allocate them, then you respin until all 
allocations are done. The only problem would be whether it'd be possible 
to run into an infinite loop: Can allocating new refblocks lead to a 
case where we have to allocate even more refblocks? Well, just judging 
from how complicated it is to even find a case where the number of new 
allocations hasn't gone down to zero in the fourth pass, we can safely 
rule that out.

Some people may ask why the walks are performed in a loop without a 
fixed limit (because they can't find cases where allocations haven't 
settled at the third pass). But I doubt that'll be a serious problem. 
It's much easier to have such a basically unlimited loop with the 
reasoning "We don't know exactly how many loops it'll take, but it will 
definitely settle at some point in time" than limiting the loop and then 
having to explain why we know exactly that it won't take more than X 
passes. The only problem with not limiting is that we need one walk to 
verify that all allocations have settled. But we need that for the 
common case (two passes) anyway, so that's not an issue.

The code from this version does not care whether it takes one, two, 
three, four or 42 passes. It's all the same. It will never take one and 
it will probably never take 42 passes; but if it does, well, it will 
work. Therefore, I think testing one non-standard number of passes 
(three) is enough. I'd like to test more, but the effort's just not 
worth it. I think.

Max

  reply	other threads:[~2014-11-20 14:04 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-14 13:05 [Qemu-devel] [PATCH v2 00/21] qcow2: Support refcount orders != 4 Max Reitz
2014-11-14 13:05 ` [Qemu-devel] [PATCH v2 01/21] qcow2: Add two new fields to BDRVQcowState Max Reitz
2014-11-14 13:05 ` [Qemu-devel] [PATCH v2 02/21] qcow2: Add refcount_width to format-specific info Max Reitz
2014-11-15 16:00   ` Eric Blake
2014-11-14 13:05 ` [Qemu-devel] [PATCH v2 03/21] qcow2: Use 64 bits for refcount values Max Reitz
2014-11-14 13:05 ` [Qemu-devel] [PATCH v2 04/21] qcow2: Respect error in qcow2_alloc_bytes() Max Reitz
2014-11-14 13:05 ` [Qemu-devel] [PATCH v2 05/21] qcow2: Refcount overflow and qcow2_alloc_bytes() Max Reitz
2014-11-14 13:05 ` [Qemu-devel] [PATCH v2 06/21] qcow2: Helper for refcount array reallocation Max Reitz
2014-11-15 16:50   ` Eric Blake
2014-11-17  8:37     ` Max Reitz
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 07/21] qcow2: Helper function for refcount modification Max Reitz
2014-11-15 17:02   ` Eric Blake
2014-11-17  8:42     ` Max Reitz
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 08/21] qcow2: More helpers " Max Reitz
2014-11-15 17:08   ` Eric Blake
2014-11-17  8:44     ` Max Reitz
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 09/21] qcow2: Open images with refcount order != 4 Max Reitz
2014-11-15 17:09   ` Eric Blake
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 10/21] qcow2: refcount_order parameter for qcow2_create2 Max Reitz
2014-11-15 17:13   ` Eric Blake
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 11/21] iotests: Prepare for refcount_width option Max Reitz
2014-11-15 17:17   ` Eric Blake
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 12/21] qcow2: Allow creation with refcount order != 4 Max Reitz
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 13/21] block: Add opaque value to the amend CB Max Reitz
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 14/21] qcow2: Use error_report() in qcow2_amend_options() Max Reitz
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 15/21] qcow2: Use abort() instead of assert(false) Max Reitz
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 16/21] qcow2: Split upgrade/downgrade paths for amend Max Reitz
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 17/21] qcow2: Use intermediate helper CB " Max Reitz
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 18/21] qcow2: Add function for refcount order amendment Max Reitz
2014-11-18 17:55   ` Eric Blake
2014-11-18 18:58     ` Max Reitz
2014-11-18 19:56       ` Eric Blake
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 19/21] qcow2: Invoke refcount order amendment function Max Reitz
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 20/21] qcow2: Point to amend function in check Max Reitz
2014-11-14 13:06 ` [Qemu-devel] [PATCH v2 21/21] iotests: Add test for different refcount widths Max Reitz
2014-11-15 14:50   ` Eric Blake
2014-11-17  8:34     ` Max Reitz
2014-11-17 10:38       ` Max Reitz
2014-11-17 11:02         ` Max Reitz
2014-11-17 12:06     ` Max Reitz
2014-11-18 20:26       ` Eric Blake
2014-11-19  5:52         ` Eric Blake
2014-11-20 14:03           ` Max Reitz [this message]
2014-11-20 21:21             ` Eric Blake
2014-11-20 13:48         ` Max Reitz
2014-11-20 21:27           ` Eric Blake

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=546DF4BB.9040302@redhat.com \
    --to=mreitz@redhat.com \
    --cc=eblake@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=pl@kamp.de \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).