diff mbox

[RFC,1/3] memory: add -disable-mem-merge command-line option

Message ID 1340643332-5653-2-git-send-email-lcapitulino@redhat.com
State New
Headers show

Commit Message

Luiz Capitulino June 25, 2012, 4:55 p.m. UTC
Allow for disabling memory merge support (KSM on Linux), which is
enabled by default otherwise.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 cpu-all.h       |  1 +
 exec-obsolete.h |  1 +
 exec.c          | 25 +++++++++++++++++++++----
 memory.c        |  5 +++++
 memory.h        |  5 +++++
 qemu-options.hx |  7 +++++++
 vl.c            |  3 +++
 7 files changed, 43 insertions(+), 4 deletions(-)

Comments

Jan Kiszka June 25, 2012, 8:26 p.m. UTC | #1
On 2012-06-25 18:55, Luiz Capitulino wrote:
> Allow for disabling memory merge support (KSM on Linux), which is
> enabled by default otherwise.

-machine mem_merge=on|off?

Jan

> 
> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
> ---
>  cpu-all.h       |  1 +
>  exec-obsolete.h |  1 +
>  exec.c          | 25 +++++++++++++++++++++----
>  memory.c        |  5 +++++
>  memory.h        |  5 +++++
>  qemu-options.hx |  7 +++++++
>  vl.c            |  3 +++
>  7 files changed, 43 insertions(+), 4 deletions(-)
> 
> diff --git a/cpu-all.h b/cpu-all.h
> index 9dc249a..429c1c3 100644
> --- a/cpu-all.h
> +++ b/cpu-all.h
> @@ -484,6 +484,7 @@ typedef struct RAMBlock {
>  } RAMBlock;
>  
>  typedef struct RAMList {
> +    bool merge_memory;
>      uint8_t *phys_dirty;
>      QLIST_HEAD(, RAMBlock) blocks;
>  } RAMList;
> diff --git a/exec-obsolete.h b/exec-obsolete.h
> index 792c831..71faf81 100644
> --- a/exec-obsolete.h
> +++ b/exec-obsolete.h
> @@ -30,6 +30,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
>  ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
>  void qemu_ram_free(ram_addr_t addr);
>  void qemu_ram_free_from_ptr(ram_addr_t addr);
> +void qemu_set_mem_merge(bool value);
>  
>  struct MemoryRegion;
>  struct MemoryRegionSection;
> diff --git a/exec.c b/exec.c
> index 8244d54..c003789 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -112,7 +112,10 @@ static uint8_t *code_gen_ptr;
>  int phys_ram_fd;
>  static int in_migration;
>  
> -RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) };
> +RAMList ram_list = {
> +    .merge_memory = true,
> +    .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks)
> +};
>  
>  static MemoryRegion *system_memory;
>  static MemoryRegion *system_io;
> @@ -2499,6 +2502,20 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
>      }
>  }
>  
> +void qemu_set_mem_merge(bool value)
> +{
> +    ram_list.merge_memory = value;
> +}
> +
> +static int madvise_mergeable(void *addr, size_t len)
> +{
> +    if (ram_list.merge_memory) {
> +        return qemu_madvise(addr, len, QEMU_MADV_MERGEABLE);
> +    }
> +
> +    return -1;
> +}
> +
>  ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
>                                     MemoryRegion *mr)
>  {
> @@ -2518,7 +2535,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
>              new_block->host = file_ram_alloc(new_block, size, mem_path);
>              if (!new_block->host) {
>                  new_block->host = qemu_vmalloc(size);
> -                qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
> +                madvise_mergeable(new_block->host, size);
>              }
>  #else
>              fprintf(stderr, "-mem-path option unsupported\n");
> @@ -2545,7 +2562,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
>                  new_block->host = qemu_vmalloc(size);
>              }
>  #endif
> -            qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
> +            madvise_mergeable(new_block->host, size);
>          }
>      }
>      new_block->length = size;
> @@ -2672,7 +2689,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
>                              length, addr);
>                      exit(1);
>                  }
> -                qemu_madvise(vaddr, length, QEMU_MADV_MERGEABLE);
> +                madvise_mergeable(vaddr, length);
>              }
>              return;
>          }
> diff --git a/memory.c b/memory.c
> index aab4a31..71789ab 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1439,6 +1439,11 @@ void memory_global_dirty_log_stop(void)
>      MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse);
>  }
>  
> +void memory_global_set_merge(bool value)
> +{
> +    qemu_set_mem_merge(value);
> +}
> +
>  static void listener_add_address_space(MemoryListener *listener,
>                                         AddressSpace *as)
>  {
> diff --git a/memory.h b/memory.h
> index 740c48e..ac224d4 100644
> --- a/memory.h
> +++ b/memory.h
> @@ -746,6 +746,11 @@ void memory_global_dirty_log_start(void);
>   */
>  void memory_global_dirty_log_stop(void);
>  
> +/**
> + * memory_global_set_merge: enable/disable memory merging done by the host
> + */
> +void memory_global_set_merge(bool value);
> +
>  void mtree_info(fprintf_function mon_printf, void *f);
>  
>  #endif
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 8b66264..324cc97 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -409,6 +409,13 @@ Preallocate memory when using -mem-path.
>  ETEXI
>  #endif
>  
> +DEF("disable-mem-merge", 0, QEMU_OPTION_disable_mem_merge,
> +    "-disable-mem-merge  disable memory merging.", QEMU_ARCH_ALL)
> +STEXI
> +@item -disable-mem-merge
> +Disable memory merging. On Linux systems this disables KSM support.
> +ETEXI
> +
>  DEF("k", HAS_ARG, QEMU_OPTION_k,
>      "-k language     use keyboard layout (for example 'fr' for French)\n",
>      QEMU_ARCH_ALL)
> diff --git a/vl.c b/vl.c
> index 1329c30..f81aadf 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -2676,6 +2676,9 @@ int main(int argc, char **argv, char **envp)
>                  mem_prealloc = 1;
>                  break;
>  #endif
> +            case QEMU_OPTION_disable_mem_merge:
> +                memory_global_set_merge(false);
> +                break;
>              case QEMU_OPTION_d:
>                  log_mask = optarg;
>                  break;
>
Luiz Capitulino June 25, 2012, 8:39 p.m. UTC | #2
On Mon, 25 Jun 2012 22:26:58 +0200
Jan Kiszka <jan.kiszka@web.de> wrote:

> On 2012-06-25 18:55, Luiz Capitulino wrote:
> > Allow for disabling memory merge support (KSM on Linux), which is
> > enabled by default otherwise.
> 
> -machine mem_merge=on|off?

That's possible. But if we do this, then I think that the set-memory-merge QMP
command should be dropped in favor of doing the same thing via machine
properties, which should be possible once we convert machine types to QOM?
Anthony Liguori June 25, 2012, 10:02 p.m. UTC | #3
On 06/25/2012 03:26 PM, Jan Kiszka wrote:
> On 2012-06-25 18:55, Luiz Capitulino wrote:
>> Allow for disabling memory merge support (KSM on Linux), which is
>> enabled by default otherwise.
>
> -machine mem_merge=on|off?

Ack.

But any reason not to call it ksm=on|off?

Regards,

Anthony Liguori

>
> Jan
>
>>
>> Signed-off-by: Luiz Capitulino<lcapitulino@redhat.com>
>> ---
>>   cpu-all.h       |  1 +
>>   exec-obsolete.h |  1 +
>>   exec.c          | 25 +++++++++++++++++++++----
>>   memory.c        |  5 +++++
>>   memory.h        |  5 +++++
>>   qemu-options.hx |  7 +++++++
>>   vl.c            |  3 +++
>>   7 files changed, 43 insertions(+), 4 deletions(-)
>>
>> diff --git a/cpu-all.h b/cpu-all.h
>> index 9dc249a..429c1c3 100644
>> --- a/cpu-all.h
>> +++ b/cpu-all.h
>> @@ -484,6 +484,7 @@ typedef struct RAMBlock {
>>   } RAMBlock;
>>
>>   typedef struct RAMList {
>> +    bool merge_memory;
>>       uint8_t *phys_dirty;
>>       QLIST_HEAD(, RAMBlock) blocks;
>>   } RAMList;
>> diff --git a/exec-obsolete.h b/exec-obsolete.h
>> index 792c831..71faf81 100644
>> --- a/exec-obsolete.h
>> +++ b/exec-obsolete.h
>> @@ -30,6 +30,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
>>   ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
>>   void qemu_ram_free(ram_addr_t addr);
>>   void qemu_ram_free_from_ptr(ram_addr_t addr);
>> +void qemu_set_mem_merge(bool value);
>>
>>   struct MemoryRegion;
>>   struct MemoryRegionSection;
>> diff --git a/exec.c b/exec.c
>> index 8244d54..c003789 100644
>> --- a/exec.c
>> +++ b/exec.c
>> @@ -112,7 +112,10 @@ static uint8_t *code_gen_ptr;
>>   int phys_ram_fd;
>>   static int in_migration;
>>
>> -RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) };
>> +RAMList ram_list = {
>> +    .merge_memory = true,
>> +    .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks)
>> +};
>>
>>   static MemoryRegion *system_memory;
>>   static MemoryRegion *system_io;
>> @@ -2499,6 +2502,20 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
>>       }
>>   }
>>
>> +void qemu_set_mem_merge(bool value)
>> +{
>> +    ram_list.merge_memory = value;
>> +}
>> +
>> +static int madvise_mergeable(void *addr, size_t len)
>> +{
>> +    if (ram_list.merge_memory) {
>> +        return qemu_madvise(addr, len, QEMU_MADV_MERGEABLE);
>> +    }
>> +
>> +    return -1;
>> +}
>> +
>>   ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
>>                                      MemoryRegion *mr)
>>   {
>> @@ -2518,7 +2535,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
>>               new_block->host = file_ram_alloc(new_block, size, mem_path);
>>               if (!new_block->host) {
>>                   new_block->host = qemu_vmalloc(size);
>> -                qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
>> +                madvise_mergeable(new_block->host, size);
>>               }
>>   #else
>>               fprintf(stderr, "-mem-path option unsupported\n");
>> @@ -2545,7 +2562,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
>>                   new_block->host = qemu_vmalloc(size);
>>               }
>>   #endif
>> -            qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
>> +            madvise_mergeable(new_block->host, size);
>>           }
>>       }
>>       new_block->length = size;
>> @@ -2672,7 +2689,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
>>                               length, addr);
>>                       exit(1);
>>                   }
>> -                qemu_madvise(vaddr, length, QEMU_MADV_MERGEABLE);
>> +                madvise_mergeable(vaddr, length);
>>               }
>>               return;
>>           }
>> diff --git a/memory.c b/memory.c
>> index aab4a31..71789ab 100644
>> --- a/memory.c
>> +++ b/memory.c
>> @@ -1439,6 +1439,11 @@ void memory_global_dirty_log_stop(void)
>>       MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse);
>>   }
>>
>> +void memory_global_set_merge(bool value)
>> +{
>> +    qemu_set_mem_merge(value);
>> +}
>> +
>>   static void listener_add_address_space(MemoryListener *listener,
>>                                          AddressSpace *as)
>>   {
>> diff --git a/memory.h b/memory.h
>> index 740c48e..ac224d4 100644
>> --- a/memory.h
>> +++ b/memory.h
>> @@ -746,6 +746,11 @@ void memory_global_dirty_log_start(void);
>>    */
>>   void memory_global_dirty_log_stop(void);
>>
>> +/**
>> + * memory_global_set_merge: enable/disable memory merging done by the host
>> + */
>> +void memory_global_set_merge(bool value);
>> +
>>   void mtree_info(fprintf_function mon_printf, void *f);
>>
>>   #endif
>> diff --git a/qemu-options.hx b/qemu-options.hx
>> index 8b66264..324cc97 100644
>> --- a/qemu-options.hx
>> +++ b/qemu-options.hx
>> @@ -409,6 +409,13 @@ Preallocate memory when using -mem-path.
>>   ETEXI
>>   #endif
>>
>> +DEF("disable-mem-merge", 0, QEMU_OPTION_disable_mem_merge,
>> +    "-disable-mem-merge  disable memory merging.", QEMU_ARCH_ALL)
>> +STEXI
>> +@item -disable-mem-merge
>> +Disable memory merging. On Linux systems this disables KSM support.
>> +ETEXI
>> +
>>   DEF("k", HAS_ARG, QEMU_OPTION_k,
>>       "-k language     use keyboard layout (for example 'fr' for French)\n",
>>       QEMU_ARCH_ALL)
>> diff --git a/vl.c b/vl.c
>> index 1329c30..f81aadf 100644
>> --- a/vl.c
>> +++ b/vl.c
>> @@ -2676,6 +2676,9 @@ int main(int argc, char **argv, char **envp)
>>                   mem_prealloc = 1;
>>                   break;
>>   #endif
>> +            case QEMU_OPTION_disable_mem_merge:
>> +                memory_global_set_merge(false);
>> +                break;
>>               case QEMU_OPTION_d:
>>                   log_mask = optarg;
>>                   break;
>>
>
Jan Kiszka June 26, 2012, 6:14 a.m. UTC | #4
On 2012-06-26 00:02, Anthony Liguori wrote:
> On 06/25/2012 03:26 PM, Jan Kiszka wrote:
>> On 2012-06-25 18:55, Luiz Capitulino wrote:
>>> Allow for disabling memory merge support (KSM on Linux), which is
>>> enabled by default otherwise.
>>
>> -machine mem_merge=on|off?
> 
> Ack.
> 
> But any reason not to call it ksm=on|off?

In theory, there could be other OSes that implement a similar feature
under a different name.

Jan
Avi Kivity June 26, 2012, 7:47 a.m. UTC | #5
On 06/25/2012 11:26 PM, Jan Kiszka wrote:
> On 2012-06-25 18:55, Luiz Capitulino wrote:
>> Allow for disabling memory merge support (KSM on Linux), which is
>> enabled by default otherwise.
> 
> -machine mem_merge=on|off?

It's a host property, not a guest property.

For devices we have a pretty good separation, -device gives the guest
properties and -netdev/-blockdev gives the host properties.  We should
either do the same for -machine, or mark host properties as such.  For
example, when we migrate the qom forest, we shouldn't migrate host
properties, only guest properties.
Luiz Capitulino June 26, 2012, 12:51 p.m. UTC | #6
On Tue, 26 Jun 2012 10:47:07 +0300
Avi Kivity <avi@redhat.com> wrote:

> On 06/25/2012 11:26 PM, Jan Kiszka wrote:
> > On 2012-06-25 18:55, Luiz Capitulino wrote:
> >> Allow for disabling memory merge support (KSM on Linux), which is
> >> enabled by default otherwise.
> > 
> > -machine mem_merge=on|off?
> 
> It's a host property, not a guest property.
> 
> For devices we have a pretty good separation, -device gives the guest
> properties and -netdev/-blockdev gives the host properties.  We should
> either do the same for -machine, or mark host properties as such.  For
> example, when we migrate the qom forest, we shouldn't migrate host
> properties, only guest properties.

Can you be more specific on how you think we could do it?

I can only think of having -host, then maybe the -mem options should be
moved there too.
Jan Kiszka June 26, 2012, 12:53 p.m. UTC | #7
On 2012-06-26 09:47, Avi Kivity wrote:
> On 06/25/2012 11:26 PM, Jan Kiszka wrote:
>> On 2012-06-25 18:55, Luiz Capitulino wrote:
>>> Allow for disabling memory merge support (KSM on Linux), which is
>>> enabled by default otherwise.
>>
>> -machine mem_merge=on|off?
> 
> It's a host property, not a guest property.

I don't think we have this differentiation in -machine. E.g.
kernel_irqchip is a host property as well.

Jan
Andreas Färber June 29, 2012, 2:18 p.m. UTC | #8
Am 25.06.2012 22:39, schrieb Luiz Capitulino:
> On Mon, 25 Jun 2012 22:26:58 +0200
> Jan Kiszka <jan.kiszka@web.de> wrote:
> 
>> On 2012-06-25 18:55, Luiz Capitulino wrote:
>>> Allow for disabling memory merge support (KSM on Linux), which is
>>> enabled by default otherwise.
>>
>> -machine mem_merge=on|off?
> 
> That's possible. But if we do this, then I think that the set-memory-merge QMP
> command should be dropped in favor of doing the same thing via machine
> properties, which should be possible once we convert machine types to QOM?

Machine QOM'ification has been requested to be postponed by Anthony, so
that we can do it really cleanly when we do it.

I don't think we have any official guidelines for QOM naming, but it
seemed to me an unwritten rule that we use the dash for separating name
components whereas command line options coming from KVM seem to use
underscore. For the CPU those were written in stone already so I
manually "translated" '_' to '-' there. Might be worth thinking about
for this and future command line / property additions.

Andreas
Luiz Capitulino June 29, 2012, 2:24 p.m. UTC | #9
On Fri, 29 Jun 2012 16:18:14 +0200
Andreas Färber <afaerber@suse.de> wrote:

> Am 25.06.2012 22:39, schrieb Luiz Capitulino:
> > On Mon, 25 Jun 2012 22:26:58 +0200
> > Jan Kiszka <jan.kiszka@web.de> wrote:
> > 
> >> On 2012-06-25 18:55, Luiz Capitulino wrote:
> >>> Allow for disabling memory merge support (KSM on Linux), which is
> >>> enabled by default otherwise.
> >>
> >> -machine mem_merge=on|off?
> > 
> > That's possible. But if we do this, then I think that the set-memory-merge QMP
> > command should be dropped in favor of doing the same thing via machine
> > properties, which should be possible once we convert machine types to QOM?
> 
> Machine QOM'ification has been requested to be postponed by Anthony, so
> that we can do it really cleanly when we do it.

We've decided to drop enabling/disabling merging on the fly, so we don't
need the property for now.

> I don't think we have any official guidelines for QOM naming, but it
> seemed to me an unwritten rule that we use the dash for separating name
> components whereas command line options coming from KVM seem to use
> underscore. For the CPU those were written in stone already so I
> manually "translated" '_' to '-' there. Might be worth thinking about
> for this and future command line / property additions.

I'll use a underscore for the cmd-line option because it's what the current
properties use.
Anthony Liguori June 29, 2012, 2:25 p.m. UTC | #10
On 06/29/2012 09:18 AM, Andreas Färber wrote:
> Am 25.06.2012 22:39, schrieb Luiz Capitulino:
>> On Mon, 25 Jun 2012 22:26:58 +0200
>> Jan Kiszka<jan.kiszka@web.de>  wrote:
>>
>>> On 2012-06-25 18:55, Luiz Capitulino wrote:
>>>> Allow for disabling memory merge support (KSM on Linux), which is
>>>> enabled by default otherwise.
>>>
>>> -machine mem_merge=on|off?
>>
>> That's possible. But if we do this, then I think that the set-memory-merge QMP
>> command should be dropped in favor of doing the same thing via machine
>> properties, which should be possible once we convert machine types to QOM?
>
> Machine QOM'ification has been requested to be postponed by Anthony, so
> that we can do it really cleanly when we do it.
>
> I don't think we have any official guidelines for QOM naming, but it
> seemed to me an unwritten rule that we use the dash for separating name
> components whereas command line options coming from KVM seem to use
> underscore. For the CPU those were written in stone already so I
> manually "translated" '_' to '-' there. Might be worth thinking about
> for this and future command line / property additions.

Yes, it would be better to use '-'s instead of '_'s.

Regards,

Anthony Liguori

>
> Andreas
>
Jan Kiszka June 29, 2012, 2:30 p.m. UTC | #11
On 2012-06-29 16:25, Anthony Liguori wrote:
> On 06/29/2012 09:18 AM, Andreas Färber wrote:
>> Am 25.06.2012 22:39, schrieb Luiz Capitulino:
>>> On Mon, 25 Jun 2012 22:26:58 +0200
>>> Jan Kiszka<jan.kiszka@web.de>  wrote:
>>>
>>>> On 2012-06-25 18:55, Luiz Capitulino wrote:
>>>>> Allow for disabling memory merge support (KSM on Linux), which is
>>>>> enabled by default otherwise.
>>>>
>>>> -machine mem_merge=on|off?
>>>
>>> That's possible. But if we do this, then I think that the
>>> set-memory-merge QMP
>>> command should be dropped in favor of doing the same thing via machine
>>> properties, which should be possible once we convert machine types to
>>> QOM?
>>
>> Machine QOM'ification has been requested to be postponed by Anthony, so
>> that we can do it really cleanly when we do it.
>>
>> I don't think we have any official guidelines for QOM naming, but it
>> seemed to me an unwritten rule that we use the dash for separating name
>> components whereas command line options coming from KVM seem to use
>> underscore. For the CPU those were written in stone already so I
>> manually "translated" '_' to '-' there. Might be worth thinking about
>> for this and future command line / property additions.
> 
> Yes, it would be better to use '-'s instead of '_'s.

Either let machine options accept both styles or keep the current '_'.
No mixture please.

Jan
Luiz Capitulino June 29, 2012, 2:31 p.m. UTC | #12
On Fri, 29 Jun 2012 09:25:36 -0500
Anthony Liguori <aliguori@us.ibm.com> wrote:

> On 06/29/2012 09:18 AM, Andreas Färber wrote:
> > Am 25.06.2012 22:39, schrieb Luiz Capitulino:
> >> On Mon, 25 Jun 2012 22:26:58 +0200
> >> Jan Kiszka<jan.kiszka@web.de>  wrote:
> >>
> >>> On 2012-06-25 18:55, Luiz Capitulino wrote:
> >>>> Allow for disabling memory merge support (KSM on Linux), which is
> >>>> enabled by default otherwise.
> >>>
> >>> -machine mem_merge=on|off?
> >>
> >> That's possible. But if we do this, then I think that the set-memory-merge QMP
> >> command should be dropped in favor of doing the same thing via machine
> >> properties, which should be possible once we convert machine types to QOM?
> >
> > Machine QOM'ification has been requested to be postponed by Anthony, so
> > that we can do it really cleanly when we do it.
> >
> > I don't think we have any official guidelines for QOM naming, but it
> > seemed to me an unwritten rule that we use the dash for separating name
> > components whereas command line options coming from KVM seem to use
> > underscore. For the CPU those were written in stone already so I
> > manually "translated" '_' to '-' there. Might be worth thinking about
> > for this and future command line / property additions.
> 
> Yes, it would be better to use '-'s instead of '_'s.

You mean we should start doing this right now (then my new option
would be mem-merge) or for future QOM work?
Luiz Capitulino June 29, 2012, 2:41 p.m. UTC | #13
On Fri, 29 Jun 2012 16:30:19 +0200
Jan Kiszka <jan.kiszka@siemens.com> wrote:

> On 2012-06-29 16:25, Anthony Liguori wrote:
> > On 06/29/2012 09:18 AM, Andreas Färber wrote:
> >> Am 25.06.2012 22:39, schrieb Luiz Capitulino:
> >>> On Mon, 25 Jun 2012 22:26:58 +0200
> >>> Jan Kiszka<jan.kiszka@web.de>  wrote:
> >>>
> >>>> On 2012-06-25 18:55, Luiz Capitulino wrote:
> >>>>> Allow for disabling memory merge support (KSM on Linux), which is
> >>>>> enabled by default otherwise.
> >>>>
> >>>> -machine mem_merge=on|off?
> >>>
> >>> That's possible. But if we do this, then I think that the
> >>> set-memory-merge QMP
> >>> command should be dropped in favor of doing the same thing via machine
> >>> properties, which should be possible once we convert machine types to
> >>> QOM?
> >>
> >> Machine QOM'ification has been requested to be postponed by Anthony, so
> >> that we can do it really cleanly when we do it.
> >>
> >> I don't think we have any official guidelines for QOM naming, but it
> >> seemed to me an unwritten rule that we use the dash for separating name
> >> components whereas command line options coming from KVM seem to use
> >> underscore. For the CPU those were written in stone already so I
> >> manually "translated" '_' to '-' there. Might be worth thinking about
> >> for this and future command line / property additions.
> > 
> > Yes, it would be better to use '-'s instead of '_'s.
> 
> Either let machine options accept both styles or keep the current '_'.
> No mixture please.

I think we could allow both, but document only '-' (at least for existing
options). But doing that is unrelated to this patch.
diff mbox

Patch

diff --git a/cpu-all.h b/cpu-all.h
index 9dc249a..429c1c3 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -484,6 +484,7 @@  typedef struct RAMBlock {
 } RAMBlock;
 
 typedef struct RAMList {
+    bool merge_memory;
     uint8_t *phys_dirty;
     QLIST_HEAD(, RAMBlock) blocks;
 } RAMList;
diff --git a/exec-obsolete.h b/exec-obsolete.h
index 792c831..71faf81 100644
--- a/exec-obsolete.h
+++ b/exec-obsolete.h
@@ -30,6 +30,7 @@  ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
 ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
 void qemu_ram_free(ram_addr_t addr);
 void qemu_ram_free_from_ptr(ram_addr_t addr);
+void qemu_set_mem_merge(bool value);
 
 struct MemoryRegion;
 struct MemoryRegionSection;
diff --git a/exec.c b/exec.c
index 8244d54..c003789 100644
--- a/exec.c
+++ b/exec.c
@@ -112,7 +112,10 @@  static uint8_t *code_gen_ptr;
 int phys_ram_fd;
 static int in_migration;
 
-RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) };
+RAMList ram_list = {
+    .merge_memory = true,
+    .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks)
+};
 
 static MemoryRegion *system_memory;
 static MemoryRegion *system_io;
@@ -2499,6 +2502,20 @@  void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
     }
 }
 
+void qemu_set_mem_merge(bool value)
+{
+    ram_list.merge_memory = value;
+}
+
+static int madvise_mergeable(void *addr, size_t len)
+{
+    if (ram_list.merge_memory) {
+        return qemu_madvise(addr, len, QEMU_MADV_MERGEABLE);
+    }
+
+    return -1;
+}
+
 ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                    MemoryRegion *mr)
 {
@@ -2518,7 +2535,7 @@  ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
             new_block->host = file_ram_alloc(new_block, size, mem_path);
             if (!new_block->host) {
                 new_block->host = qemu_vmalloc(size);
-                qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
+                madvise_mergeable(new_block->host, size);
             }
 #else
             fprintf(stderr, "-mem-path option unsupported\n");
@@ -2545,7 +2562,7 @@  ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                 new_block->host = qemu_vmalloc(size);
             }
 #endif
-            qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);
+            madvise_mergeable(new_block->host, size);
         }
     }
     new_block->length = size;
@@ -2672,7 +2689,7 @@  void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
                             length, addr);
                     exit(1);
                 }
-                qemu_madvise(vaddr, length, QEMU_MADV_MERGEABLE);
+                madvise_mergeable(vaddr, length);
             }
             return;
         }
diff --git a/memory.c b/memory.c
index aab4a31..71789ab 100644
--- a/memory.c
+++ b/memory.c
@@ -1439,6 +1439,11 @@  void memory_global_dirty_log_stop(void)
     MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse);
 }
 
+void memory_global_set_merge(bool value)
+{
+    qemu_set_mem_merge(value);
+}
+
 static void listener_add_address_space(MemoryListener *listener,
                                        AddressSpace *as)
 {
diff --git a/memory.h b/memory.h
index 740c48e..ac224d4 100644
--- a/memory.h
+++ b/memory.h
@@ -746,6 +746,11 @@  void memory_global_dirty_log_start(void);
  */
 void memory_global_dirty_log_stop(void);
 
+/**
+ * memory_global_set_merge: enable/disable memory merging done by the host
+ */
+void memory_global_set_merge(bool value);
+
 void mtree_info(fprintf_function mon_printf, void *f);
 
 #endif
diff --git a/qemu-options.hx b/qemu-options.hx
index 8b66264..324cc97 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -409,6 +409,13 @@  Preallocate memory when using -mem-path.
 ETEXI
 #endif
 
+DEF("disable-mem-merge", 0, QEMU_OPTION_disable_mem_merge,
+    "-disable-mem-merge  disable memory merging.", QEMU_ARCH_ALL)
+STEXI
+@item -disable-mem-merge
+Disable memory merging. On Linux systems this disables KSM support.
+ETEXI
+
 DEF("k", HAS_ARG, QEMU_OPTION_k,
     "-k language     use keyboard layout (for example 'fr' for French)\n",
     QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index 1329c30..f81aadf 100644
--- a/vl.c
+++ b/vl.c
@@ -2676,6 +2676,9 @@  int main(int argc, char **argv, char **envp)
                 mem_prealloc = 1;
                 break;
 #endif
+            case QEMU_OPTION_disable_mem_merge:
+                memory_global_set_merge(false);
+                break;
             case QEMU_OPTION_d:
                 log_mask = optarg;
                 break;