From: Igor Mammedov <imammedo@redhat.com>
To: Laszlo Ersek <lersek@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] memory: move MemoryRegion::size cleanup to memory_region_finalize()
Date: Wed, 10 Oct 2018 14:36:49 +0200 [thread overview]
Message-ID: <20181010143649.37d0892c@redhat.com> (raw)
In-Reply-To: <40220217-aa30-9436-22a8-9d1fca611d8e@redhat.com>
On Tue, 9 Oct 2018 19:09:06 +0200
Laszlo Ersek <lersek@redhat.com> wrote:
> On 10/09/18 17:47, Paolo Bonzini wrote:
> > On 09/10/2018 15:50, Igor Mammedov wrote:
> >> It's not necessary to clean up MemoryRegion::size manually in multiple places
> >> like it's been implemented in
> >> (1cd3d49262 "memory: cleanup side effects of memory_region_init_foo() on failure")
> >> since each memory_region_init_foo() now calls object_unparent(mr) on failure,
> >> memory region destructor memory_region_finalize() will be called upon its
> >> completion for each memory_region_init_foo().
> >> It's sufficient to clean MemoryRegion::size only from memory_region_finalize(),
> >> so do it.
> >
> > Stupid question, why is it necessary to clear mr->size at all?...
>
> IIRC it is explained in the above-mentioned, earlier commit 1cd3d49262:
>
> > if MemoryRegion intialization fails it's left in semi-initialized state,
> > where it's size is not 0 and attached as child to owner object.
> > And this leds to crash in following use-case:
> > (monitor) object_add memory-backend-file,id=mem1,size=99999G,mem-path=/tmp/foo,discard-data=yes
> > memory.c:2083: memory_region_get_ram_ptr: Assertion `mr->ram_block' failed
> > Aborted (core dumped)
> > it happens due to assumption that memory region is intialized when
> > memory_region_size() != 0
> > and therefore it's ok to access it in
> > file_backend_unparent()
> > if (memory_region_size() != 0)
> > memory_region_get_ram_ptr()
> >
> > which happens when object_add fails and unparents failed backend making
> > file_backend_unparent() access invalid memory region.
>
> I think it makes sense to zero out the size even if unparenting would, in itself, prevent the above crash. Because, in host_memory_backend_mr_inited(), we have:
>
> /*
> * NOTE: We forbid zero-length memory backend, so here zero means
> * "we haven't inited the backend memory region yet".
> */
>
> I'm unsure how general that invariant is, but it can't hurt to honor it everywhere. (Especially if we can do the zeroing in one common place.)
yep, we are (ab)using memory_region_size(MemoryRegion *mr) == 0
as a check if memory pointed by 'mr' is valid memory region.
In cases where MemoryRegion is not dynamically allocated,
it allows us to avoid using an external validity flag.
Even though unparenting solves 1cd3d49262 issue
I'd prefer to leave clean state on failure if it doesn't
incur a heavy penalty (performance|code complexity wise)
> Anyway, I should defer to Igor on this! :)
>
> Thanks,
> Laszlo
>
> >> memory.c | 7 +------
> >> 1 file changed, 1 insertion(+), 6 deletions(-)
> >>
> >> diff --git a/memory.c b/memory.c
> >> index d852f11..ad24b57 100644
> >> --- a/memory.c
> >> +++ b/memory.c
> >> @@ -1491,7 +1491,6 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
> >> mr->ram_block = qemu_ram_alloc(size, share, mr, &err);
> >> mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
> >> if (err) {
> >> - mr->size = int128_zero();
> >> object_unparent(OBJECT(mr));
> >> error_propagate(errp, err);
> >> }
> >> @@ -1516,7 +1515,6 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
> >> mr, &err);
> >> mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
> >> if (err) {
> >> - mr->size = int128_zero();
> >> object_unparent(OBJECT(mr));
> >> error_propagate(errp, err);
> >> }
> >> @@ -1541,7 +1539,6 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
> >> mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path, &err);
> >> mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
> >> if (err) {
> >> - mr->size = int128_zero();
> >> object_unparent(OBJECT(mr));
> >> error_propagate(errp, err);
> >> }
> >> @@ -1565,7 +1562,6 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
> >> fd, &err);
> >> mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
> >> if (err) {
> >> - mr->size = int128_zero();
> >> object_unparent(OBJECT(mr));
> >> error_propagate(errp, err);
> >> }
> >> @@ -1628,7 +1624,6 @@ void memory_region_init_rom_nomigrate(MemoryRegion *mr,
> >> mr->ram_block = qemu_ram_alloc(size, false, mr, &err);
> >> mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
> >> if (err) {
> >> - mr->size = int128_zero();
> >> object_unparent(OBJECT(mr));
> >> error_propagate(errp, err);
> >> }
> >> @@ -1652,7 +1647,6 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
> >> mr->destructor = memory_region_destructor_ram;
> >> mr->ram_block = qemu_ram_alloc(size, false, mr, &err);
> >> if (err) {
> >> - mr->size = int128_zero();
> >> object_unparent(OBJECT(mr));
> >> error_propagate(errp, err);
> >> }
> >> @@ -1701,6 +1695,7 @@ static void memory_region_finalize(Object *obj)
> >> memory_region_clear_coalescing(mr);
> >> g_free((char *)mr->name);
> >> g_free(mr->ioeventfds);
> >> + mr->size = int128_zero();
> >> }
> >>
> >> Object *memory_region_owner(MemoryRegion *mr)
> >>
> >
>
next prev parent reply other threads:[~2018-10-10 12:36 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-09 13:50 [Qemu-devel] [PATCH] memory: move MemoryRegion::size cleanup to memory_region_finalize() Igor Mammedov
2018-10-09 15:23 ` Laszlo Ersek
2018-10-09 15:47 ` Paolo Bonzini
2018-10-09 17:09 ` Laszlo Ersek
2018-10-10 12:36 ` Igor Mammedov [this message]
2018-10-10 18:56 ` Paolo Bonzini
2018-10-10 19:03 ` Laszlo Ersek
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=20181010143649.37d0892c@redhat.com \
--to=imammedo@redhat.com \
--cc=lersek@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/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).