All of lore.kernel.org
 help / color / mirror / Atom feed
From: Haozhong Zhang <haozhong.zhang@intel.com>
To: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org, Igor Mammedov <imammedo@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Peter Crosthwaite <crosthwaite.peter@gmail.com>,
	Richard Henderson <rth@twiddle.net>
Subject: Re: [Qemu-devel] [PATCH v2 3/3] hostmem-file: make option 'size' optional
Date: Fri, 28 Oct 2016 10:06:40 +0800	[thread overview]
Message-ID: <20161028020640.6dlpah37fkyxpr3u@hz-desktop> (raw)
In-Reply-To: <20161027145522.GK5057@thinpad.lan.raisama.net>

On 10/27/16 12:55 -0200, Eduardo Habkost wrote:
>On Thu, Oct 27, 2016 at 12:23:00PM +0800, Haozhong Zhang wrote:
>> If 'size' option is not given, Qemu will use the file size of 'mem-path'
>> instead. If an empty file, a non-existing file or a directory is specified
>> by option 'mem-path', a non-zero option 'size' is still needed.
>>
>> Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
>> ---
>>  backends/hostmem-file.c | 28 ++++++++++++++++++++--------
>>  exec.c                  | 33 ++++++++++++++++++++-------------
>>  2 files changed, 40 insertions(+), 21 deletions(-)
>>
>> diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
>> index 42efb2f..6ee4352 100644
>> --- a/backends/hostmem-file.c
>> +++ b/backends/hostmem-file.c
>> @@ -39,17 +39,14 @@ static void
>>  file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
>>  {
>>      HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
>> +    Error *local_err = NULL;
>>
>> -    if (!backend->size) {
>> -        error_setg(errp, "can't create backend with size 0");
>> -        return;
>> -    }
>>      if (!fb->mem_path) {
>> -        error_setg(errp, "mem-path property not set");
>> -        return;
>> +        error_setg(&local_err, "mem-path property not set");
>> +        goto out;
>>      }
>>  #ifndef CONFIG_LINUX
>> -    error_setg(errp, "-mem-path not supported on this host");
>> +    error_setg(&local_err, "-mem-path not supported on this host");
>>  #else
>>      if (!memory_region_size(&backend->mr)) {
>>          gchar *path;
>> @@ -58,10 +55,25 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
>>          memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
>>                                   path,
>>                                   backend->size, fb->share,
>> -                                 fb->mem_path, errp);
>> +                                 fb->mem_path, &local_err);
>>          g_free(path);
>> +
>> +        if (local_err) {
>> +            goto out;
>> +        }
>> +
>> +        if (!backend->size) {
>> +            backend->size = memory_region_size(&backend->mr);
>> +        }
>>      }
>>  #endif
>> +
>> +    if (!backend->size) {
>> +        error_setg(&local_err, "can't create backend with size 0");
>> +    }
>
>You need to move this check before the #endif line, as an error
>is already unconditionally set in local_err in the !CONFIG_LINUX
>path, and a second error_setg() call would trigger an assert()
>inside error_setv().
>

will change

>> +
>> + out:
>> +    error_propagate(errp, local_err);
>>  }
>>
>>  static char *get_mem_path(Object *o, Error **errp)
>> diff --git a/exec.c b/exec.c
>> index 264a25f..89065bd 100644
>> --- a/exec.c
>> +++ b/exec.c
>> @@ -1234,7 +1234,7 @@ static int64_t get_file_size(int fd)
>>  }
>>
>>  static void *file_ram_alloc(RAMBlock *block,
>> -                            ram_addr_t memory,
>> +                            ram_addr_t *memory,
>>                              const char *path,
>>                              Error **errp)
>>  {
>> @@ -1245,6 +1245,7 @@ static void *file_ram_alloc(RAMBlock *block,
>>      void *area = MAP_FAILED;
>>      int fd = -1;
>>      int64_t file_size;
>> +    ram_addr_t mem_size = *memory;
>>
>>      if (kvm_enabled() && !kvm_has_sync_mmu()) {
>>          error_setg(errp,
>> @@ -1309,21 +1310,27 @@ static void *file_ram_alloc(RAMBlock *block,
>>
>>      file_size = get_file_size(fd);
>>
>> -    if (memory < block->page_size) {
>> +    if (!mem_size && file_size > 0) {
>> +        mem_size = file_size;
>
>Maybe we should set *memory here and not below?
>

Qemu currently sets the memory region size to the file size, and block
length to the aligned file size, so the code here can be changed as below:

            memory_region_set_size(block->mr, mem_size);
            mem_size = HOST_PAGE_ALIGN(mem_size);
            *memory = mem_size;

The second line is necessary because Qemu currently passes the aligned
file size to file_ram_alloc().

>> +        memory_region_set_size(block->mr, mem_size);
>
>This could be simplified (and made safer) if the memory region
>got initialized by memory_region_init_ram_from_file() after we
>already mapped/allocated the file (so we avoid surprises in case
>other code does something weird because of the temporarily
>zero-sized MemoryRegion). But it would probably be an intrusive
>change, so I guess changing the memory size here is OK. Paolo,
>what do you think?
>

I will add a check to ensure that the size of block->mr is either 0 or
mem_size, and only set the region size in the former case. The former
corresponds to the case that 'size' option is not given or 0. The
latter corresponds to the case that 'size' option is given.

>> +    }
>> +
>> +    if (mem_size < block->page_size) {
>>          error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
>>                     "or larger than page size 0x%zx",
>> -                   memory, block->page_size);
>> +                   mem_size, block->page_size);
>>          goto error;
>>      }
>>
>> -    if (file_size > 0 && file_size < memory) {
>> +    if (file_size > 0 && file_size < mem_size) {
>>          error_setg(errp, "backing store %s size %"PRId64
>>                     " does not match 'size' option %"PRIu64,
>> -                   path, file_size, memory);
>> +                   path, file_size, mem_size);
>>          goto error;
>>      }
>>
>> -    memory = ROUND_UP(memory, block->page_size);
>> +    mem_size = ROUND_UP(mem_size, block->page_size);
>> +    *memory = mem_size;
>
>Why exactly did you choose to set *memory to the rounded-up size
>and not file_size? Changing *memory to the rounded-up value would
>be additional behavior that is not described in the commit
>message. I believe we should change *memory only if *memory == 0,
>and avoid touching it otherwise.
>

Setting *memory here is buggy. I'll move it as above.

Thanks,
Haozhong

>>
>>      /*
>>       * ftruncate is not supported by hugetlbfs in older
>> @@ -1339,11 +1346,11 @@ static void *file_ram_alloc(RAMBlock *block,
>>       * those labels. Therefore, extending the non-empty backend file
>>       * is disabled as well.
>>       */
>> -    if (!file_size && ftruncate(fd, memory)) {
>> +    if (!file_size && ftruncate(fd, mem_size)) {
>>          perror("ftruncate");
>>      }
>>
>> -    area = qemu_ram_mmap(fd, memory, block->mr->align,
>> +    area = qemu_ram_mmap(fd, mem_size, block->mr->align,
>>                           block->flags & RAM_SHARED);
>>      if (area == MAP_FAILED) {
>>          error_setg_errno(errp, errno,
>> @@ -1352,7 +1359,7 @@ static void *file_ram_alloc(RAMBlock *block,
>>      }
>>
>>      if (mem_prealloc) {
>> -        os_mem_prealloc(fd, area, memory, errp);
>> +        os_mem_prealloc(fd, area, mem_size, errp);
>>          if (errp && *errp) {
>>              goto error;
>>          }
>> @@ -1363,7 +1370,7 @@ static void *file_ram_alloc(RAMBlock *block,
>>
>>  error:
>>      if (area != MAP_FAILED) {
>> -        qemu_ram_munmap(area, memory);
>> +        qemu_ram_munmap(area, mem_size);
>>      }
>>      if (unlink_on_error) {
>>          unlink(path);
>> @@ -1690,15 +1697,15 @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
>>      size = HOST_PAGE_ALIGN(size);
>>      new_block = g_malloc0(sizeof(*new_block));
>>      new_block->mr = mr;
>> -    new_block->used_length = size;
>> -    new_block->max_length = size;
>>      new_block->flags = share ? RAM_SHARED : 0;
>> -    new_block->host = file_ram_alloc(new_block, size,
>> +    new_block->host = file_ram_alloc(new_block, &size,
>>                                       mem_path, errp);
>>      if (!new_block->host) {
>>          g_free(new_block);
>>          return NULL;
>>      }
>> +    new_block->used_length = size;
>> +    new_block->max_length = size;
>>
>>      ram_block_add(new_block, &local_err);
>>      if (local_err) {
>> --
>> 2.10.1
>>
>
>-- 
>Eduardo

  reply	other threads:[~2016-10-28  2:06 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-27  4:22 [Qemu-devel] [PATCH v2 0/3] Improve truncation behavior of memory-backend-file Haozhong Zhang
2016-10-27  4:22 ` [Qemu-devel] [PATCH v2 1/3] exec.c: do not truncate non-empty memory backend file Haozhong Zhang
2016-10-27 14:31   ` Eduardo Habkost
2016-10-28  2:07     ` Haozhong Zhang
2016-10-31 17:21       ` Eduardo Habkost
2016-10-27  4:22 ` [Qemu-devel] [PATCH v2 2/3] exec.c: check memory backend file size with 'size' option Haozhong Zhang
2016-10-27 14:32   ` Eduardo Habkost
2016-10-31 17:23   ` Eduardo Habkost
2016-10-31 17:56     ` Paolo Bonzini
2016-11-02  1:05   ` [Qemu-devel] [RESEND PATCH " Haozhong Zhang
2016-10-27  4:23 ` [Qemu-devel] [PATCH v2 3/3] hostmem-file: make option 'size' optional Haozhong Zhang
2016-10-27 14:55   ` Eduardo Habkost
2016-10-28  2:06     ` Haozhong Zhang [this message]
2016-10-28  5:57       ` Haozhong Zhang
2016-10-31 18:18       ` Eduardo Habkost
2016-11-02  2:08         ` Haozhong Zhang
2016-10-27 12:03 ` [Qemu-devel] [PATCH v2 0/3] Improve truncation behavior of memory-backend-file Paolo Bonzini

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=20161028020640.6dlpah37fkyxpr3u@hz-desktop \
    --to=haozhong.zhang@intel.com \
    --cc=crosthwaite.peter@gmail.com \
    --cc=ehabkost@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /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.