qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] memory: move MemoryRegion::size cleanup to memo


From: Laszlo Ersek
Subject: Re: [Qemu-devel] [PATCH] memory: move MemoryRegion::size cleanup to memory_region_finalize()
Date: Tue, 9 Oct 2018 19:09:06 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1

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.)

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)
>>
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]