Patchwork [v2] Add option to mlock qemu and guest memory

login
register
mail settings
Submitter Satoru Moriya
Date Feb. 14, 2013, 8:21 p.m.
Message ID <8631DC5930FA9E468F04F3FD3A5D007214B0C1F2@USINDEM103.corp.hds.com>
Download mbox | patch
Permalink /patch/220496/
State New
Headers show

Comments

Satoru Moriya - Feb. 14, 2013, 8:21 p.m.
We have some plans to migrate legacy enterprise systems which require
low latency (10 msec order) to kvm virtualized environment. In our
usecase, the system runs with other untrusted guests and so locking
memory which is used by the system is needed to avoid latency
impacts from other guests' memory activity.

ChangeLog:
v2
 - Change the option name from -mlock to -realtime mlock=on|off
 - Rebase qemu version 1.3.91
 - Update patch description

---
In certain scenario, latency induced by paging is significant and
memory locking is needed. Also, in the scenario with untrusted
guests, latency improvement due to mlock is desired.

This patch introduces a following new option to mlock guest and
qemu memory:

-realtime mlock=on|off

Signed-off-by: Satoru Moriya <satoru.moriya@hds.com>
---
 include/sysemu/os-posix.h |  1 +
 include/sysemu/os-win32.h |  1 +
 os-posix.c                |  8 ++++++++
 qemu-options.hx           | 13 +++++++++++++
 vl.c                      | 31 +++++++++++++++++++++++++++++++
 5 files changed, 54 insertions(+)
Michael Tokarev - Feb. 14, 2013, 8:39 p.m.
15.02.2013 00:21, Satoru Moriya wrote:
> We have some plans to migrate legacy enterprise systems which require
> low latency (10 msec order) to kvm virtualized environment. In our
> usecase, the system runs with other untrusted guests and so locking
> memory which is used by the system is needed to avoid latency
> impacts from other guests' memory activity.

Not a patch review, but maybe using (explicit) huge pages will solve
this issue already?  Huge pages aren't swappable...

Thanks,

/mjt
Satoru Moriya - Feb. 14, 2013, 9:05 p.m.
On 02/14/2013 03:39 PM, Michael Tokarev wrote:
> 15.02.2013 00:21, Satoru Moriya wrote:

>> We have some plans to migrate legacy enterprise systems which require 

>> low latency (10 msec order) to kvm virtualized environment. In our 

>> usecase, the system runs with other untrusted guests and so locking 

>> memory which is used by the system is needed to avoid latency impacts 

>> from other guests' memory activity.

> 

> Not a patch review, but maybe using (explicit) huge pages will solve 

> this issue already?  Huge pages aren't swappable...


For some scenarios, you're right.

But, I think, -mem-prealloc/-mem-path uses huge pages only for
guest RAM and it doesn't for qemu itself. It may cause latency impact.

Also using huge page reduces flexibility/usability because if
we do live migration, we have to allocate huge pages before
live migration (basically we don't use live migration for the
guest which needs low latency but sometimes we need to do it).

Regards,
Satoru
Satoru Moriya - March 2, 2013, 12:11 a.m.
Ping?

On 02/14/2013 03:21 PM, Satoru Moriya wrote:
> We have some plans to migrate legacy enterprise systems which require 

> low latency (10 msec order) to kvm virtualized environment. In our 

> usecase, the system runs with other untrusted guests and so locking 

> memory which is used by the system is needed to avoid latency impacts 

> from other guests' memory activity.

> 

> ChangeLog:

> v2

>  - Change the option name from -mlock to -realtime mlock=on|off

>  - Rebase qemu version 1.3.91

>  - Update patch description

> 

> ---

> In certain scenario, latency induced by paging is significant and 

> memory locking is needed. Also, in the scenario with untrusted guests, 

> latency improvement due to mlock is desired.

> 

> This patch introduces a following new option to mlock guest and qemu 

> memory:

> 

> -realtime mlock=on|off

> 

> Signed-off-by: Satoru Moriya <satoru.moriya@hds.com>

> ---

>  include/sysemu/os-posix.h |  1 +

>  include/sysemu/os-win32.h |  1 +

>  os-posix.c                |  8 ++++++++

>  qemu-options.hx           | 13 +++++++++++++

>  vl.c                      | 31 +++++++++++++++++++++++++++++++

>  5 files changed, 54 insertions(+)

> 

> diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h 

> index 7f198e4..2f2ead6 100644

> --- a/include/sysemu/os-posix.h

> +++ b/include/sysemu/os-posix.h

> @@ -31,6 +31,7 @@ void os_set_proc_name(const char *s);  void 

> os_setup_signal_handling(void);  void os_daemonize(void);  void 

> os_setup_post(void);

> +void os_mlock(void);

>  

>  typedef struct timeval qemu_timeval;

>  #define qemu_gettimeofday(tp) gettimeofday(tp, NULL) diff --git 

> a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h index 

> bf9edeb..a74ca13 100644

> --- a/include/sysemu/os-win32.h

> +++ b/include/sysemu/os-win32.h

> @@ -80,6 +80,7 @@ static inline void os_daemonize(void) {}  static 

> inline void os_setup_post(void) {}  void os_set_line_buffering(void);  

> static inline void os_set_proc_name(const char *dummy) {}

> +static inline void os_mlock(void) {}

>  

>  #if !defined(EPROTONOSUPPORT)

>  # define EPROTONOSUPPORT EINVAL

> diff --git a/os-posix.c b/os-posix.c

> index 5c64518..1304b0e 100644

> --- a/os-posix.c

> +++ b/os-posix.c

> @@ -363,3 +363,11 @@ bool is_daemonized(void)  {

>      return daemonize;

>  }

> +

> +void os_mlock(void)

> +{

> +    if (mlockall(MCL_CURRENT | MCL_FUTURE)) {

> +        perror("mlockall");

> +        exit(1);

> +    }

> +}

> diff --git a/qemu-options.hx b/qemu-options.hx index 9d7131a..843fcb4 

> 100644

> --- a/qemu-options.hx

> +++ b/qemu-options.hx

> @@ -2464,6 +2464,19 @@ STEXI

>  Do not start CPU at startup (you must type 'c' in the monitor).

>  ETEXI

>  

> +DEF("realtime", HAS_ARG, QEMU_OPTION_realtime,

> +    "-realtime [mlock=on|off]\n"

> +    "                run qemu with realtime features\n"

> +    "                mlock=on|off controls mlock support (default: on)\n",

> +    QEMU_ARCH_ALL)

> +STEXI

> +@item -realtime mlock=on|off

> +@findex -realtime

> +Run qemu with realtime features.

> +mlocking qemu and guest memory can be enabled via @option{mlock=on} 

> +(enabled by default).

> +ETEXI

> +

>  DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \

>      "-gdb dev        wait for gdb connection on 'dev'\n", QEMU_ARCH_ALL)

>  STEXI

> diff --git a/vl.c b/vl.c

> index 1355f69..c16c8ad 100644

> --- a/vl.c

> +++ b/vl.c

> @@ -491,6 +491,18 @@ static QemuOptsList qemu_object_opts = {

>      },

>  };

>  

> +static QemuOptsList qemu_realtime_opts = {

> +    .name = "realtime",

> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),

> +    .desc = {

> +        {

> +            .name = "mlock",

> +            .type = QEMU_OPT_BOOL,

> +        },

> +        { /* end of list */ }

> +    },

> +};

> +

>  const char *qemu_get_vm_name(void)

>  {

>      return qemu_name;

> @@ -1384,6 +1396,17 @@ static void smp_parse(const char *optarg)

>          max_cpus = smp_cpus;

>  }

>  

> +static void configure_realtime(QemuOpts *opts) {

> +    bool is_mlock;

> +

> +    is_mlock = qemu_opt_get_bool(opts, "mlock", true);

> +

> +    if (is_mlock) {

> +        os_mlock();

> +    }

> +}

> +

>  /***********************************************************/

>  /* USB devices */

>  

> @@ -2860,6 +2883,7 @@ int main(int argc, char **argv, char **envp)

>      qemu_add_opts(&qemu_sandbox_opts);

>      qemu_add_opts(&qemu_add_fd_opts);

>      qemu_add_opts(&qemu_object_opts);

> +    qemu_add_opts(&qemu_realtime_opts);

>  

>      runstate_init();

>  

> @@ -3806,6 +3830,13 @@ int main(int argc, char **argv, char **envp)

>                      exit(1);

>                  }

>                  break;

> +            case QEMU_OPTION_realtime:

> +                opts = qemu_opts_parse(qemu_find_opts("realtime"), optarg, 0);

> +                if (!opts) {

> +                    exit(1);

> +                }

> +                configure_realtime(opts);

> +                break;

>              default:

>                  os_parse_cmd_args(popt->index, optarg);

>              }

>
Paolo Bonzini - March 12, 2013, 9:40 a.m.
Il 14/02/2013 21:21, Satoru Moriya ha scritto:
> We have some plans to migrate legacy enterprise systems which require
> low latency (10 msec order) to kvm virtualized environment. In our
> usecase, the system runs with other untrusted guests and so locking
> memory which is used by the system is needed to avoid latency
> impacts from other guests' memory activity.
> 
> ChangeLog:
> v2
>  - Change the option name from -mlock to -realtime mlock=on|off
>  - Rebase qemu version 1.3.91
>  - Update patch description
> 
> ---
> In certain scenario, latency induced by paging is significant and
> memory locking is needed. Also, in the scenario with untrusted
> guests, latency improvement due to mlock is desired.
> 
> This patch introduces a following new option to mlock guest and
> qemu memory:
> 
> -realtime mlock=on|off
> 
> Signed-off-by: Satoru Moriya <satoru.moriya@hds.com>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

As a follow up it would be nice to move -mem-prealloc/-mem-path under
-realtime as well.

Paolo

> ---
>  include/sysemu/os-posix.h |  1 +
>  include/sysemu/os-win32.h |  1 +
>  os-posix.c                |  8 ++++++++
>  qemu-options.hx           | 13 +++++++++++++
>  vl.c                      | 31 +++++++++++++++++++++++++++++++
>  5 files changed, 54 insertions(+)
> 
> diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
> index 7f198e4..2f2ead6 100644
> --- a/include/sysemu/os-posix.h
> +++ b/include/sysemu/os-posix.h
> @@ -31,6 +31,7 @@ void os_set_proc_name(const char *s);
>  void os_setup_signal_handling(void);
>  void os_daemonize(void);
>  void os_setup_post(void);
> +void os_mlock(void);
>  
>  typedef struct timeval qemu_timeval;
>  #define qemu_gettimeofday(tp) gettimeofday(tp, NULL)
> diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
> index bf9edeb..a74ca13 100644
> --- a/include/sysemu/os-win32.h
> +++ b/include/sysemu/os-win32.h
> @@ -80,6 +80,7 @@ static inline void os_daemonize(void) {}
>  static inline void os_setup_post(void) {}
>  void os_set_line_buffering(void);
>  static inline void os_set_proc_name(const char *dummy) {}
> +static inline void os_mlock(void) {}
>  
>  #if !defined(EPROTONOSUPPORT)
>  # define EPROTONOSUPPORT EINVAL
> diff --git a/os-posix.c b/os-posix.c
> index 5c64518..1304b0e 100644
> --- a/os-posix.c
> +++ b/os-posix.c
> @@ -363,3 +363,11 @@ bool is_daemonized(void)
>  {
>      return daemonize;
>  }
> +
> +void os_mlock(void)
> +{
> +    if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
> +        perror("mlockall");
> +        exit(1);
> +    }
> +}
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 9d7131a..843fcb4 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2464,6 +2464,19 @@ STEXI
>  Do not start CPU at startup (you must type 'c' in the monitor).
>  ETEXI
>  
> +DEF("realtime", HAS_ARG, QEMU_OPTION_realtime,
> +    "-realtime [mlock=on|off]\n"
> +    "                run qemu with realtime features\n"
> +    "                mlock=on|off controls mlock support (default: on)\n",
> +    QEMU_ARCH_ALL)
> +STEXI
> +@item -realtime mlock=on|off
> +@findex -realtime
> +Run qemu with realtime features.
> +mlocking qemu and guest memory can be enabled via @option{mlock=on}
> +(enabled by default).
> +ETEXI
> +
>  DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \
>      "-gdb dev        wait for gdb connection on 'dev'\n", QEMU_ARCH_ALL)
>  STEXI
> diff --git a/vl.c b/vl.c
> index 1355f69..c16c8ad 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -491,6 +491,18 @@ static QemuOptsList qemu_object_opts = {
>      },
>  };
>  
> +static QemuOptsList qemu_realtime_opts = {
> +    .name = "realtime",
> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),
> +    .desc = {
> +        {
> +            .name = "mlock",
> +            .type = QEMU_OPT_BOOL,
> +        },
> +        { /* end of list */ }
> +    },
> +};
> +
>  const char *qemu_get_vm_name(void)
>  {
>      return qemu_name;
> @@ -1384,6 +1396,17 @@ static void smp_parse(const char *optarg)
>          max_cpus = smp_cpus;
>  }
>  
> +static void configure_realtime(QemuOpts *opts)
> +{
> +    bool is_mlock;
> +
> +    is_mlock = qemu_opt_get_bool(opts, "mlock", true);
> +
> +    if (is_mlock) {
> +        os_mlock();
> +    }
> +}
> +
>  /***********************************************************/
>  /* USB devices */
>  
> @@ -2860,6 +2883,7 @@ int main(int argc, char **argv, char **envp)
>      qemu_add_opts(&qemu_sandbox_opts);
>      qemu_add_opts(&qemu_add_fd_opts);
>      qemu_add_opts(&qemu_object_opts);
> +    qemu_add_opts(&qemu_realtime_opts);
>  
>      runstate_init();
>  
> @@ -3806,6 +3830,13 @@ int main(int argc, char **argv, char **envp)
>                      exit(1);
>                  }
>                  break;
> +            case QEMU_OPTION_realtime:
> +                opts = qemu_opts_parse(qemu_find_opts("realtime"), optarg, 0);
> +                if (!opts) {
> +                    exit(1);
> +                }
> +                configure_realtime(opts);
> +                break;
>              default:
>                  os_parse_cmd_args(popt->index, optarg);
>              }
>
Satoru Moriya - March 15, 2013, 5:21 p.m.
Ping.

Can anyone else review this patch?

Regards,
Satoru

On 03/12/2013 05:40 AM, Paolo Bonzini wrote:
> Il 14/02/2013 21:21, Satoru Moriya ha scritto:

>> We have some plans to migrate legacy enterprise systems which require 

>> low latency (10 msec order) to kvm virtualized environment. In our 

>> usecase, the system runs with other untrusted guests and so locking 

>> memory which is used by the system is needed to avoid latency impacts 

>> from other guests' memory activity.

>>

>> ChangeLog:

>> v2

>>  - Change the option name from -mlock to -realtime mlock=on|off

>>  - Rebase qemu version 1.3.91

>>  - Update patch description

>>

>> ---

>> In certain scenario, latency induced by paging is significant and 

>> memory locking is needed. Also, in the scenario with untrusted 

>> guests, latency improvement due to mlock is desired.

>>

>> This patch introduces a following new option to mlock guest and qemu 

>> memory:

>>

>> -realtime mlock=on|off

>>

>> Signed-off-by: Satoru Moriya <satoru.moriya@hds.com>

> 

> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

> 

> As a follow up it would be nice to move -mem-prealloc/-mem-path under 

> -realtime as well.

> 

> Paolo

> 

>> ---

>>  include/sysemu/os-posix.h |  1 +

>>  include/sysemu/os-win32.h |  1 +

>>  os-posix.c                |  8 ++++++++

>>  qemu-options.hx           | 13 +++++++++++++

>>  vl.c                      | 31 +++++++++++++++++++++++++++++++

>>  5 files changed, 54 insertions(+)

>>

>> diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h 

>> index 7f198e4..2f2ead6 100644

>> --- a/include/sysemu/os-posix.h

>> +++ b/include/sysemu/os-posix.h

>> @@ -31,6 +31,7 @@ void os_set_proc_name(const char *s);  void 

>> os_setup_signal_handling(void);  void os_daemonize(void);  void 

>> os_setup_post(void);

>> +void os_mlock(void);

>>  

>>  typedef struct timeval qemu_timeval;  #define qemu_gettimeofday(tp) 

>> gettimeofday(tp, NULL) diff --git a/include/sysemu/os-win32.h 

>> b/include/sysemu/os-win32.h index bf9edeb..a74ca13 100644

>> --- a/include/sysemu/os-win32.h

>> +++ b/include/sysemu/os-win32.h

>> @@ -80,6 +80,7 @@ static inline void os_daemonize(void) {}  static 

>> inline void os_setup_post(void) {}  void os_set_line_buffering(void);  

>> static inline void os_set_proc_name(const char *dummy) {}

>> +static inline void os_mlock(void) {}

>>  

>>  #if !defined(EPROTONOSUPPORT)

>>  # define EPROTONOSUPPORT EINVAL

>> diff --git a/os-posix.c b/os-posix.c

>> index 5c64518..1304b0e 100644

>> --- a/os-posix.c

>> +++ b/os-posix.c

>> @@ -363,3 +363,11 @@ bool is_daemonized(void)  {

>>      return daemonize;

>>  }

>> +

>> +void os_mlock(void)

>> +{

>> +    if (mlockall(MCL_CURRENT | MCL_FUTURE)) {

>> +        perror("mlockall");

>> +        exit(1);

>> +    }

>> +}

>> diff --git a/qemu-options.hx b/qemu-options.hx index 9d7131a..843fcb4 

>> 100644

>> --- a/qemu-options.hx

>> +++ b/qemu-options.hx

>> @@ -2464,6 +2464,19 @@ STEXI

>>  Do not start CPU at startup (you must type 'c' in the monitor).

>>  ETEXI

>>  

>> +DEF("realtime", HAS_ARG, QEMU_OPTION_realtime,

>> +    "-realtime [mlock=on|off]\n"

>> +    "                run qemu with realtime features\n"

>> +    "                mlock=on|off controls mlock support (default: on)\n",

>> +    QEMU_ARCH_ALL)

>> +STEXI

>> +@item -realtime mlock=on|off

>> +@findex -realtime

>> +Run qemu with realtime features.

>> +mlocking qemu and guest memory can be enabled via @option{mlock=on} 

>> +(enabled by default).

>> +ETEXI

>> +

>>  DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \

>>      "-gdb dev        wait for gdb connection on 'dev'\n", QEMU_ARCH_ALL)

>>  STEXI

>> diff --git a/vl.c b/vl.c

>> index 1355f69..c16c8ad 100644

>> --- a/vl.c

>> +++ b/vl.c

>> @@ -491,6 +491,18 @@ static QemuOptsList qemu_object_opts = {

>>      },

>>  };

>>  

>> +static QemuOptsList qemu_realtime_opts = {

>> +    .name = "realtime",

>> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),

>> +    .desc = {

>> +        {

>> +            .name = "mlock",

>> +            .type = QEMU_OPT_BOOL,

>> +        },

>> +        { /* end of list */ }

>> +    },

>> +};

>> +

>>  const char *qemu_get_vm_name(void)

>>  {

>>      return qemu_name;

>> @@ -1384,6 +1396,17 @@ static void smp_parse(const char *optarg)

>>          max_cpus = smp_cpus;

>>  }

>>  

>> +static void configure_realtime(QemuOpts *opts) {

>> +    bool is_mlock;

>> +

>> +    is_mlock = qemu_opt_get_bool(opts, "mlock", true);

>> +

>> +    if (is_mlock) {

>> +        os_mlock();

>> +    }

>> +}

>> +

>>  /***********************************************************/

>>  /* USB devices */

>>  

>> @@ -2860,6 +2883,7 @@ int main(int argc, char **argv, char **envp)

>>      qemu_add_opts(&qemu_sandbox_opts);

>>      qemu_add_opts(&qemu_add_fd_opts);

>>      qemu_add_opts(&qemu_object_opts);

>> +    qemu_add_opts(&qemu_realtime_opts);

>>  

>>      runstate_init();

>>  

>> @@ -3806,6 +3830,13 @@ int main(int argc, char **argv, char **envp)

>>                      exit(1);

>>                  }

>>                  break;

>> +            case QEMU_OPTION_realtime:

>> +                opts = qemu_opts_parse(qemu_find_opts("realtime"), optarg, 0);

>> +                if (!opts) {

>> +                    exit(1);

>> +                }

>> +                configure_realtime(opts);

>> +                break;

>>              default:

>>                  os_parse_cmd_args(popt->index, optarg);

>>              }

>>

> 

>
Marcelo Tosatti - March 16, 2013, 1:44 a.m.
On Thu, Feb 14, 2013 at 08:21:51PM +0000, Satoru Moriya wrote:
> We have some plans to migrate legacy enterprise systems which require
> low latency (10 msec order) to kvm virtualized environment. In our
> usecase, the system runs with other untrusted guests and so locking
> memory which is used by the system is needed to avoid latency
> impacts from other guests' memory activity.
> 
> ChangeLog:
> v2
>  - Change the option name from -mlock to -realtime mlock=on|off
>  - Rebase qemu version 1.3.91
>  - Update patch description
> 
> ---
> In certain scenario, latency induced by paging is significant and
> memory locking is needed. Also, in the scenario with untrusted
> guests, latency improvement due to mlock is desired.
> 
> This patch introduces a following new option to mlock guest and
> qemu memory:
> 
> -realtime mlock=on|off
> 
> Signed-off-by: Satoru Moriya <satoru.moriya@hds.com>
> ---
>  include/sysemu/os-posix.h |  1 +
>  include/sysemu/os-win32.h |  1 +
>  os-posix.c                |  8 ++++++++
>  qemu-options.hx           | 13 +++++++++++++
>  vl.c                      | 31 +++++++++++++++++++++++++++++++
>  5 files changed, 54 insertions(+)
> 
> diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
> index 7f198e4..2f2ead6 100644
> --- a/include/sysemu/os-posix.h
> +++ b/include/sysemu/os-posix.h
> @@ -31,6 +31,7 @@ void os_set_proc_name(const char *s);
>  void os_setup_signal_handling(void);
>  void os_daemonize(void);
>  void os_setup_post(void);
> +void os_mlock(void);
>  
>  typedef struct timeval qemu_timeval;
>  #define qemu_gettimeofday(tp) gettimeofday(tp, NULL)
> diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
> index bf9edeb..a74ca13 100644
> --- a/include/sysemu/os-win32.h
> +++ b/include/sysemu/os-win32.h
> @@ -80,6 +80,7 @@ static inline void os_daemonize(void) {}
>  static inline void os_setup_post(void) {}
>  void os_set_line_buffering(void);
>  static inline void os_set_proc_name(const char *dummy) {}
> +static inline void os_mlock(void) {}
>  
>  #if !defined(EPROTONOSUPPORT)
>  # define EPROTONOSUPPORT EINVAL
> diff --git a/os-posix.c b/os-posix.c
> index 5c64518..1304b0e 100644
> --- a/os-posix.c
> +++ b/os-posix.c
> @@ -363,3 +363,11 @@ bool is_daemonized(void)
>  {
>      return daemonize;
>  }
> +
> +void os_mlock(void)
> +{
> +    if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
> +        perror("mlockall");
> +        exit(1);
> +    }
> +}
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 9d7131a..843fcb4 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2464,6 +2464,19 @@ STEXI
>  Do not start CPU at startup (you must type 'c' in the monitor).
>  ETEXI
>  
> +DEF("realtime", HAS_ARG, QEMU_OPTION_realtime,
> +    "-realtime [mlock=on|off]\n"
> +    "                run qemu with realtime features\n"
> +    "                mlock=on|off controls mlock support (default: on)\n",
> +    QEMU_ARCH_ALL)
> +STEXI
> +@item -realtime mlock=on|off
> +@findex -realtime
> +Run qemu with realtime features.
> +mlocking qemu and guest memory can be enabled via @option{mlock=on}
> +(enabled by default).
> +ETEXI
> +
>  DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \
>      "-gdb dev        wait for gdb connection on 'dev'\n", QEMU_ARCH_ALL)
>  STEXI
> diff --git a/vl.c b/vl.c
> index 1355f69..c16c8ad 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -491,6 +491,18 @@ static QemuOptsList qemu_object_opts = {
>      },
>  };
>  
> +static QemuOptsList qemu_realtime_opts = {
> +    .name = "realtime",
> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),
> +    .desc = {
> +        {
> +            .name = "mlock",
> +            .type = QEMU_OPT_BOOL,
> +        },
> +        { /* end of list */ }
> +    },
> +};
> +
>  const char *qemu_get_vm_name(void)
>  {
>      return qemu_name;
> @@ -1384,6 +1396,17 @@ static void smp_parse(const char *optarg)
>          max_cpus = smp_cpus;
>  }
>  
> +static void configure_realtime(QemuOpts *opts)
> +{
> +    bool is_mlock;
> +
> +    is_mlock = qemu_opt_get_bool(opts, "mlock", true);
> +
> +    if (is_mlock) {
> +        os_mlock();
> +    }
> +}
> +
>  /***********************************************************/
>  /* USB devices */
>  
> @@ -2860,6 +2883,7 @@ int main(int argc, char **argv, char **envp)
>      qemu_add_opts(&qemu_sandbox_opts);
>      qemu_add_opts(&qemu_add_fd_opts);
>      qemu_add_opts(&qemu_object_opts);
> +    qemu_add_opts(&qemu_realtime_opts);
>  
>      runstate_init();
>  
> @@ -3806,6 +3830,13 @@ int main(int argc, char **argv, char **envp)
>                      exit(1);
>                  }
>                  break;
> +            case QEMU_OPTION_realtime:
> +                opts = qemu_opts_parse(qemu_find_opts("realtime"), optarg, 0);
> +                if (!opts) {
> +                    exit(1);
> +                }
> +                configure_realtime(opts);
> +                break;
>              default:
>                  os_parse_cmd_args(popt->index, optarg);
>              }
> -- 
> 1.7.11.7
> 

Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Jan Kiszka - March 21, 2013, 9:08 a.m.
On 2013-02-14 21:21, Satoru Moriya wrote:
> We have some plans to migrate legacy enterprise systems which require
> low latency (10 msec order) to kvm virtualized environment. In our
> usecase, the system runs with other untrusted guests and so locking
> memory which is used by the system is needed to avoid latency
> impacts from other guests' memory activity.
> 
> ChangeLog:
> v2
>  - Change the option name from -mlock to -realtime mlock=on|off
>  - Rebase qemu version 1.3.91
>  - Update patch description
> 
> ---
> In certain scenario, latency induced by paging is significant and
> memory locking is needed. Also, in the scenario with untrusted
> guests, latency improvement due to mlock is desired.
> 
> This patch introduces a following new option to mlock guest and
> qemu memory:
> 
> -realtime mlock=on|off
> 
> Signed-off-by: Satoru Moriya <satoru.moriya@hds.com>
> ---
>  include/sysemu/os-posix.h |  1 +
>  include/sysemu/os-win32.h |  1 +
>  os-posix.c                |  8 ++++++++
>  qemu-options.hx           | 13 +++++++++++++
>  vl.c                      | 31 +++++++++++++++++++++++++++++++
>  5 files changed, 54 insertions(+)
> 
> diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
> index 7f198e4..2f2ead6 100644
> --- a/include/sysemu/os-posix.h
> +++ b/include/sysemu/os-posix.h
> @@ -31,6 +31,7 @@ void os_set_proc_name(const char *s);
>  void os_setup_signal_handling(void);
>  void os_daemonize(void);
>  void os_setup_post(void);
> +void os_mlock(void);
>  
>  typedef struct timeval qemu_timeval;
>  #define qemu_gettimeofday(tp) gettimeofday(tp, NULL)
> diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
> index bf9edeb..a74ca13 100644
> --- a/include/sysemu/os-win32.h
> +++ b/include/sysemu/os-win32.h
> @@ -80,6 +80,7 @@ static inline void os_daemonize(void) {}
>  static inline void os_setup_post(void) {}
>  void os_set_line_buffering(void);
>  static inline void os_set_proc_name(const char *dummy) {}
> +static inline void os_mlock(void) {}

Let's  return an error code from os_mlock, a permanent failure like
-ENOSYS on Win32, the result of mlock() on POSIX. Requesting to lock the
memory should not silently fail on Windows.

>  
>  #if !defined(EPROTONOSUPPORT)
>  # define EPROTONOSUPPORT EINVAL
> diff --git a/os-posix.c b/os-posix.c
> index 5c64518..1304b0e 100644
> --- a/os-posix.c
> +++ b/os-posix.c
> @@ -363,3 +363,11 @@ bool is_daemonized(void)
>  {
>      return daemonize;
>  }
> +
> +void os_mlock(void)
> +{
> +    if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
> +        perror("mlockall");
> +        exit(1);
> +    }
> +}
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 9d7131a..843fcb4 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2464,6 +2464,19 @@ STEXI
>  Do not start CPU at startup (you must type 'c' in the monitor).
>  ETEXI
>  
> +DEF("realtime", HAS_ARG, QEMU_OPTION_realtime,
> +    "-realtime [mlock=on|off]\n"

Hmm, an argument to -realtime is actually not optional but mandatory.
But we cannot express this. So this is just a comment, not a to-do.

> +    "                run qemu with realtime features\n"
> +    "                mlock=on|off controls mlock support (default: on)\n",
> +    QEMU_ARCH_ALL)
> +STEXI
> +@item -realtime mlock=on|off
> +@findex -realtime
> +Run qemu with realtime features.
> +mlocking qemu and guest memory can be enabled via @option{mlock=on}
> +(enabled by default).
> +ETEXI
> +
>  DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \
>      "-gdb dev        wait for gdb connection on 'dev'\n", QEMU_ARCH_ALL)
>  STEXI
> diff --git a/vl.c b/vl.c
> index 1355f69..c16c8ad 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -491,6 +491,18 @@ static QemuOptsList qemu_object_opts = {
>      },
>  };
>  
> +static QemuOptsList qemu_realtime_opts = {
> +    .name = "realtime",
> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),
> +    .desc = {
> +        {
> +            .name = "mlock",
> +            .type = QEMU_OPT_BOOL,
> +        },
> +        { /* end of list */ }
> +    },
> +};
> +
>  const char *qemu_get_vm_name(void)
>  {
>      return qemu_name;
> @@ -1384,6 +1396,17 @@ static void smp_parse(const char *optarg)
>          max_cpus = smp_cpus;
>  }
>  
> +static void configure_realtime(QemuOpts *opts)
> +{
> +    bool is_mlock;

"enable_mlock" or just "mlock".

> +
> +    is_mlock = qemu_opt_get_bool(opts, "mlock", true);
> +
> +    if (is_mlock) {
> +        os_mlock();
> +    }
> +}
> +
>  /***********************************************************/
>  /* USB devices */
>  
> @@ -2860,6 +2883,7 @@ int main(int argc, char **argv, char **envp)
>      qemu_add_opts(&qemu_sandbox_opts);
>      qemu_add_opts(&qemu_add_fd_opts);
>      qemu_add_opts(&qemu_object_opts);
> +    qemu_add_opts(&qemu_realtime_opts);
>  
>      runstate_init();
>  
> @@ -3806,6 +3830,13 @@ int main(int argc, char **argv, char **envp)
>                      exit(1);
>                  }
>                  break;
> +            case QEMU_OPTION_realtime:
> +                opts = qemu_opts_parse(qemu_find_opts("realtime"), optarg, 0);
> +                if (!opts) {
> +                    exit(1);
> +                }
> +                configure_realtime(opts);
> +                break;
>              default:
>                  os_parse_cmd_args(popt->index, optarg);
>              }
> 

Otherwise I'm fine with it.

Thanks,
Jan
Satoru Moriya - March 21, 2013, 7:08 p.m.
Hi Jan,

Thank you for reviewing.

On 03/21/2013 05:08 AM, Jan Kiszka wrote:
> On 2013-02-14 21:21, Satoru Moriya wrote:

>> @@ -31,6 +31,7 @@ void os_set_proc_name(const char *s);  void 

>> os_setup_signal_handling(void);  void os_daemonize(void);  void 

>> os_setup_post(void);

>> +void os_mlock(void);

>>  

>>  typedef struct timeval qemu_timeval;  #define qemu_gettimeofday(tp) 

>> gettimeofday(tp, NULL) diff --git a/include/sysemu/os-win32.h 

>> b/include/sysemu/os-win32.h index bf9edeb..a74ca13 100644

>> --- a/include/sysemu/os-win32.h

>> +++ b/include/sysemu/os-win32.h

>> @@ -80,6 +80,7 @@ static inline void os_daemonize(void) {}  static 

>> inline void os_setup_post(void) {}  void os_set_line_buffering(void);  

>> static inline void os_set_proc_name(const char *dummy) {}

>> +static inline void os_mlock(void) {}

> 

> Let's  return an error code from os_mlock, a permanent failure like 

> -ENOSYS on Win32, the result of mlock() on POSIX. Requesting to lock 

> the memory should not silently fail on Windows.


OK. I'll update it.
 
>> diff --git a/vl.c b/vl.c

>> index 1355f69..c16c8ad 100644

>> --- a/vl.c

>> +++ b/vl.c

>> @@ -491,6 +491,18 @@ static QemuOptsList qemu_object_opts = {

>>      },

>>  };

>>  

>> +static QemuOptsList qemu_realtime_opts = {

>> +    .name = "realtime",

>> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),

>> +    .desc = {

>> +        {

>> +            .name = "mlock",

>> +            .type = QEMU_OPT_BOOL,

>> +        },

>> +        { /* end of list */ }

>> +    },

>> +};

>> +

>>  const char *qemu_get_vm_name(void)

>>  {

>>      return qemu_name;

>> @@ -1384,6 +1396,17 @@ static void smp_parse(const char *optarg)

>>          max_cpus = smp_cpus;

>>  }

>>  

>> +static void configure_realtime(QemuOpts *opts) {

>> +    bool is_mlock;

> 

> "enable_mlock" or just "mlock".


will do.

Regards,
Satoru

Patch

diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
index 7f198e4..2f2ead6 100644
--- a/include/sysemu/os-posix.h
+++ b/include/sysemu/os-posix.h
@@ -31,6 +31,7 @@  void os_set_proc_name(const char *s);
 void os_setup_signal_handling(void);
 void os_daemonize(void);
 void os_setup_post(void);
+void os_mlock(void);
 
 typedef struct timeval qemu_timeval;
 #define qemu_gettimeofday(tp) gettimeofday(tp, NULL)
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
index bf9edeb..a74ca13 100644
--- a/include/sysemu/os-win32.h
+++ b/include/sysemu/os-win32.h
@@ -80,6 +80,7 @@  static inline void os_daemonize(void) {}
 static inline void os_setup_post(void) {}
 void os_set_line_buffering(void);
 static inline void os_set_proc_name(const char *dummy) {}
+static inline void os_mlock(void) {}
 
 #if !defined(EPROTONOSUPPORT)
 # define EPROTONOSUPPORT EINVAL
diff --git a/os-posix.c b/os-posix.c
index 5c64518..1304b0e 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -363,3 +363,11 @@  bool is_daemonized(void)
 {
     return daemonize;
 }
+
+void os_mlock(void)
+{
+    if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
+        perror("mlockall");
+        exit(1);
+    }
+}
diff --git a/qemu-options.hx b/qemu-options.hx
index 9d7131a..843fcb4 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2464,6 +2464,19 @@  STEXI
 Do not start CPU at startup (you must type 'c' in the monitor).
 ETEXI
 
+DEF("realtime", HAS_ARG, QEMU_OPTION_realtime,
+    "-realtime [mlock=on|off]\n"
+    "                run qemu with realtime features\n"
+    "                mlock=on|off controls mlock support (default: on)\n",
+    QEMU_ARCH_ALL)
+STEXI
+@item -realtime mlock=on|off
+@findex -realtime
+Run qemu with realtime features.
+mlocking qemu and guest memory can be enabled via @option{mlock=on}
+(enabled by default).
+ETEXI
+
 DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \
     "-gdb dev        wait for gdb connection on 'dev'\n", QEMU_ARCH_ALL)
 STEXI
diff --git a/vl.c b/vl.c
index 1355f69..c16c8ad 100644
--- a/vl.c
+++ b/vl.c
@@ -491,6 +491,18 @@  static QemuOptsList qemu_object_opts = {
     },
 };
 
+static QemuOptsList qemu_realtime_opts = {
+    .name = "realtime",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),
+    .desc = {
+        {
+            .name = "mlock",
+            .type = QEMU_OPT_BOOL,
+        },
+        { /* end of list */ }
+    },
+};
+
 const char *qemu_get_vm_name(void)
 {
     return qemu_name;
@@ -1384,6 +1396,17 @@  static void smp_parse(const char *optarg)
         max_cpus = smp_cpus;
 }
 
+static void configure_realtime(QemuOpts *opts)
+{
+    bool is_mlock;
+
+    is_mlock = qemu_opt_get_bool(opts, "mlock", true);
+
+    if (is_mlock) {
+        os_mlock();
+    }
+}
+
 /***********************************************************/
 /* USB devices */
 
@@ -2860,6 +2883,7 @@  int main(int argc, char **argv, char **envp)
     qemu_add_opts(&qemu_sandbox_opts);
     qemu_add_opts(&qemu_add_fd_opts);
     qemu_add_opts(&qemu_object_opts);
+    qemu_add_opts(&qemu_realtime_opts);
 
     runstate_init();
 
@@ -3806,6 +3830,13 @@  int main(int argc, char **argv, char **envp)
                     exit(1);
                 }
                 break;
+            case QEMU_OPTION_realtime:
+                opts = qemu_opts_parse(qemu_find_opts("realtime"), optarg, 0);
+                if (!opts) {
+                    exit(1);
+                }
+                configure_realtime(opts);
+                break;
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }