[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v5 03/23] block: Connect BlockBackend to BlockDr
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH v5 03/23] block: Connect BlockBackend to BlockDriverState |
Date: |
Thu, 02 Oct 2014 13:37:05 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) |
Kevin Wolf <address@hidden> writes:
> Am 02.10.2014 um 11:04 hat Markus Armbruster geschrieben:
>> Convenience function blk_new_with_bs() creates a BlockBackend with its
>> BlockDriverState. Callers have to unref both. The commit after next
>> will relieve them of the need to unref the BlockDriverState.
>>
>> Complication: due to the silly way drive_del works, we need a way to
>> hide a BlockBackend, just like bdrv_make_anon(). To emphasize its
>> "special" status, give the function a suitably off-putting name:
>> blk_hide_on_behalf_of_do_drive_del(). Unfortunately, hiding turns the
>> BlockBackend's name into the empty string. Can't avoid that without
>> breaking the blk->bs->device_name equals blk->name invariant.
>>
>> The patch adds a memory leak: drive_del while a device model is
>> connected leaks the BlockBackend. Avoiding the leak here is rather
>> hairy, but it'll become straightforward shortly, so I mark it FIXME in
>> the code now, and plug it when it's easy.
>
> Does this leak actually still exist now that you have a blk_unref() in
> drive_del() (which is called during autodel) rather than do_drive_del()?
Yes. The following hunk adds it:
@@ -1813,11 +1811,11 @@ int do_drive_del(Monitor *mon, const QDict *qdict,
QObject **ret_data)
* then we can just get rid of the block driver state right here.
*/
if (bdrv_get_attached_dev(bs)) {
- bdrv_make_anon(bs);
-
+ blk_hide_on_behalf_of_do_drive_del(blk);
/* Further I/O must not pause the guest */
bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
BLOCKDEV_ON_ERROR_REPORT);
+ /* FIXME bs->blk leaked when bs dies */
} else {
drive_del(dinfo);
}
where blk_hide_on_behalf_of_do_drive_del() is from a few hunks further
up:
+/*
+ * Hide @blk.
+ * @blk must not have been hidden already.
+ * Make attached BlockDriverState, if any, anonymous.
+ * Once hidden, @blk is invisible to all functions that don't receive
+ * it as argument. For example, blk_by_name() won't return it.
+ * Strictly for use by do_drive_del().
+ * TODO get rid of it!
+ */
+void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk)
+{
+ QTAILQ_REMOVE(&blk_backends, blk, link);
+ blk->name[0] = 0;
+ if (blk->bs) {
+ bdrv_make_anon(blk->bs);
+ }
+}
The net effect is just
+ QTAILQ_REMOVE(&blk_backends, blk, link);
+ blk->name[0] = 0;
Admittedly not obvious: this messes with drive_del()! Let's follow the
call chain.
void blockdev_auto_del(BlockDriverState *bs)
{
DriveInfo *dinfo = drive_get_by_blockdev(bs);
if (dinfo && dinfo->auto_del) {
drive_del(dinfo);
}
}
drive_get_by_blockdev() still returns the DriveInfo, as we haven't
touched drives (we will in the next patch). However:
void drive_del(DriveInfo *dinfo)
{
BlockBackend *blk = blk_by_name(dinfo->id);
bdrv_unref(dinfo->bdrv);
blk_unref(blk);
}
blk_by_name() returns null rather than the BB, because
blk_hide_on_behalf_of_do_drive_del() already removed the BB from
blk_backends.
PATCH 06 plugs the leak: blockdev_auto_del() passes the BB straight to
blk_unref().
But there's still a bug! Your review of v3 convinced me that the leak
was already plugged in PATCH 04. Maybe it was in v3 (I didn't check
again), but in v5, there's temporary breakage instead. I'll try to
extend the test suite to cover it in v6.
- [Qemu-devel] [PATCH v5 00/23] Split BlockBackend off BDS with an axe, Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 01/23] block: Split bdrv_new_root() off bdrv_new(), Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 05/23] block: Code motion to get rid of stubs/blockdev.c, Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 13/23] virtio-blk: Drop redundant VirtIOBlock member conf, Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 07/23] block: Eliminate bdrv_iterate(), use bdrv_next(), Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 03/23] block: Connect BlockBackend to BlockDriverState, Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 09/23] block: Merge BlockBackend and BlockDriverState name spaces, Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 02/23] block: New BlockBackend, Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 04/23] block: Connect BlockBackend and DriveInfo, Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 10/23] block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo(), Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 06/23] block: Make BlockBackend own its BlockDriverState, Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 21/23] blockdev: Convert qmp_eject(), qmp_change_blockdev() to BlockBackend, Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 14/23] virtio-blk: Rename VirtIOBlkConf variables to conf, Markus Armbruster, 2014/10/02
- [Qemu-devel] [PATCH v5 20/23] block/qapi: Convert qmp_query_block() to BlockBackend, Markus Armbruster, 2014/10/02