From: John Snow <jsnow@redhat.com>
To: Stefan Hajnoczi <stefanha@redhat.com>
Cc: kwolf@redhat.com, famz@redhat.com, qemu-block@nongnu.org,
qemu-devel@nongnu.org, mreitz@redhat.com,
vsementsov@parallels.com
Subject: Re: [Qemu-devel] [PATCH v4 06/11] block: add refcount to Job object
Date: Fri, 22 May 2015 18:38:08 -0400 [thread overview]
Message-ID: <555FAFD0.5090408@redhat.com> (raw)
In-Reply-To: <20150520092703.GA6945@stefanha-thinkpad.redhat.com>
On 05/20/2015 05:27 AM, Stefan Hajnoczi wrote:
> On Tue, May 19, 2015 at 06:15:23PM -0400, John Snow wrote:
>> On 05/18/2015 11:45 AM, Stefan Hajnoczi wrote:
>>> On Mon, May 11, 2015 at 07:04:21PM -0400, John Snow wrote:
>>>> If we want to get at the job after the life of the job, we'll
>>>> need a refcount for this object.
>>>>
>>>> This may occur for example if we wish to inspect the actions
>>>> taken by a particular job after a transactional group of
>>>> jobs runs, and further actions are required.
>>>>
>>>> Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Max
>>>> Reitz <mreitz@redhat.com> --- blockjob.c | 18
>>>> ++++++++++++++++-- include/block/blockjob.h | 21
>>>> +++++++++++++++++++++ 2 files changed, 37 insertions(+), 2
>>>> deletions(-)
>>>
>>> I think the only reason for this refcount is so that
>>> backup_transaction_complete() can be called. It accesses
>>> BackupBlockJob->sync_bitmap so the BackupBlockJob instance
>>> needs to be alive.
>>>
>>> The bitmap refcount is incremented in blockdev.c, not
>>> block/backup.c, so it is fine to drop
>>> backup_transaction_complete() and decrement the bitmap refcount
>>> in blockdev.c instead.
>>>
>>> If you do that then there is no need to add a refcount to block
>>> job. This would simplify things.
>>>
>>
>> So you are suggesting that I cache the bitmap reference (instead
>> of the job reference) and then just increment/decrement it
>> directly in .prepare, .abort and .cb as needed.
>>
>> You did find the disparity with the reference count for the
>> bitmap, at least: that is kind of gross. I was coincidentally
>> thinking of punting it back into a backup_transaction_start to
>> keep more code /out/ of blockdev...
>>
>> I'll sit on this one for a few more minutes. I'll try to get rid
>> of the job refcnt, but I also want to keep the transaction
>> actions as tidy as I can.
>>
>> Maybe it's too much abstraction for a simple task, but I wanted
>> to make sure I wasn't hacking in transaction callbacks in a
>> manner where they'd only be useful to me, for only this one case.
>> It's conceivable that if anyone else attempts to use this
>> callback hijacking mechanism that they'll need to find a way to
>> modify objects within the Job without pulling everything up to
>> the transaction actions, too.
>
> Hmm...I think this could be achieved without refcounting in
> transactions, actions, or block jobs.
>
> Create a separate MultiCompletion struct with a counter and list
> of callbacks:
>
> typedef struct MultiCompletionCB { BlockCompletionFunc cb; void
> *opaque; QSLIST_ENTRY(MultiCompletionCB) list; }
> MultiCompletionCB;
>
> typedef struct { unsigned refcnt; /* callbacks invoked when this
> reaches zero */ QSLIST_HEAD(, MultiCompletionCB) callbacks; int
> ret; } MultiCompletion;
>
> void multicomp_add_cb(MultiCompletion *mc, BlockCompletionFunc cb,
> void *opaque);
>
> /* Note the first argument is MultiCompletion* but this prototype *
> allows it to be used as a blockjob cb. */ void
> multicomp_complete(void *opaque, int ret) { MultiCompletion *mc =
> opaque;
>
> if (ret < 0) { mc->ret = ret; }
>
> if (--mc->refcnt == 0) { MultiCompletionCB *cb_data; while
> ((cb_data = QSLIST_FIRST(&mc->callbacks)) != NULL) {
> cb_data->cb(cb_data->opaque, mc->ret);
>
> QSLIST_REMOVE_HEAD(&mc->callbacks, list); g_free(cb_data); }
>
> g_free(mc); } }
>
> qmp_transaction() creates a MultiCompletion and passes it to
> action .prepare(). If an action wishes to join the
> MultiCompletion, it calls multicomp_add_cb() after creating a block
> job:
>
> static void backup_completion(void *opaque, int ret) { HBitmap
> *bmap = opaque; if (ret < 0) { ...merge bitmap back in... } else {
> ...drop frozen bitmap... } }
>
> ... backup_start(..., multicomp_completion, mc);
> multicomp_add_cb(mc, backup_completion, bmap);
>
> The multicomp_complete() function gets called by a blockjob cb
> function.
>
> This approach is more reusable since MultiCompletion is independent
> of transactions or block jobs. It also doesn't hold on to
> transactions, actions, or block jobs after they have served their
> purpose.
>
> Is this along the lines you were thinking about?
>
> Stefan
>
Yes, this is roughly what I was aiming for in the design of this
series as it stands now, except I did essentially bake the
MultiCompletion functionality into the BlkTransactionState structure
instead of leaving it separate.
I think it might be worth doing, though I could also just drop a lot
of the refcounts now and rework who picks up the bitmap reference
count and achieve something nearly similar.
I'll play around with the patches I have now and see if I can't tidy
it up to the point where I'm happy with the way it's managing
references, and if not I might scrap it and try the even more
abstracted version.
I'll probably just choose whatever looks cleanest :)
--js
next prev parent reply other threads:[~2015-05-22 22:38 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-11 23:04 [Qemu-devel] [PATCH v4 00/11] block: incremental backup transactions John Snow
2015-05-11 23:04 ` [Qemu-devel] [PATCH v4 01/11] qapi: Add transaction support to block-dirty-bitmap operations John Snow
2015-05-18 16:14 ` Max Reitz
2015-05-11 23:04 ` [Qemu-devel] [PATCH v4 02/11] iotests: add transactional incremental backup test John Snow
2015-05-11 23:04 ` [Qemu-devel] [PATCH v4 03/11] block: rename BlkTransactionState and BdrvActionOps John Snow
2015-05-18 12:24 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2015-05-11 23:04 ` [Qemu-devel] [PATCH v4 04/11] block: re-add BlkTransactionState John Snow
2015-05-18 12:33 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2015-05-11 23:04 ` [Qemu-devel] [PATCH v4 05/11] block: add transactional callbacks feature John Snow
2015-05-11 23:04 ` [Qemu-devel] [PATCH v4 06/11] block: add refcount to Job object John Snow
2015-05-18 15:45 ` Stefan Hajnoczi
2015-05-19 22:15 ` John Snow
2015-05-20 9:27 ` Stefan Hajnoczi
2015-05-22 22:38 ` John Snow [this message]
2015-05-11 23:04 ` [Qemu-devel] [PATCH v4 07/11] block: add delayed bitmap successor cleanup John Snow
2015-05-11 23:04 ` [Qemu-devel] [PATCH v4 08/11] qmp: Add an implementation wrapper for qmp_drive_backup John Snow
2015-05-18 14:42 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2015-05-18 15:10 ` John Snow
2015-05-11 23:04 ` [Qemu-devel] [PATCH v4 09/11] block: drive_backup transaction callback support John Snow
2015-05-18 15:35 ` Stefan Hajnoczi
2015-05-18 15:53 ` John Snow
2015-05-18 15:48 ` Stefan Hajnoczi
2015-05-11 23:04 ` [Qemu-devel] [PATCH v4 10/11] iotests: 124 - transactional failure test John Snow
2015-05-11 23:04 ` [Qemu-devel] [PATCH v4 11/11] qmp-commands.hx: Update the supported 'transaction' operations John Snow
2015-05-18 16:22 ` Max Reitz
2015-05-19 15:30 ` Kashyap Chamarthy
2015-05-19 15:37 ` John Snow
2015-05-20 11:12 ` Kashyap Chamarthy
2015-05-20 11:27 ` John Snow
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=555FAFD0.5090408@redhat.com \
--to=jsnow@redhat.com \
--cc=famz@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--cc=vsementsov@parallels.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.