[libvirt] [PATCH] qemu: Add support for overriding max threads per process limit

2019-06-06 Thread Jim Fehlig
Some VM configurations may result in a large number of threads created by
the associated qemu process which can exceed the system default limit. The
maximum number of threads allowed per process is controlled by the pids
cgroup controller and is set to 16k when creating VMs with systemd's
machined service. The maximum number of threads per process is recorded
in the pids.max file under the machine's pids controller cgroup hierarchy,
e.g.

$cgrp-mnt/pids/machine.slice/machine-qemu\\x2d1\\x2dtest.scope/pids.max

Maximum threads per process is controlled with the TasksMax property of
the systemd scope for the machine. This patch adds an option to qemu.conf
which can be used to override the maximum number of threads allowed per
qemu process. If the value of option is greater than zero, it will be set
in the TasksMax property of the machine's scope after creating the machine.

Signed-off-by: Jim Fehlig 
---
 src/lxc/lxc_cgroup.c   |  1 +
 src/qemu/libvirtd_qemu.aug |  1 +
 src/qemu/qemu.conf | 10 ++
 src/qemu/qemu_cgroup.c |  1 +
 src/qemu/qemu_conf.c   |  2 ++
 src/qemu/qemu_conf.h   |  1 +
 src/qemu/test_libvirtd_qemu.aug.in |  1 +
 src/util/vircgroup.c   |  6 +-
 src/util/vircgroup.h   |  1 +
 src/util/virsystemd.c  | 24 +++-
 src/util/virsystemd.h  |  3 ++-
 tests/virsystemdtest.c | 12 ++--
 12 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index d93a19d684..76014f3bfd 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -455,6 +455,7 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def,
 nnicindexes, nicindexes,
 def->resource->partition,
 -1,
+0,
 &cgroup) < 0)
 goto cleanup;
 
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index b311f02da6..c70b903fed 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -94,6 +94,7 @@ module Libvirtd_qemu =
  | limits_entry "max_core"
  | bool_entry "dump_guest_core"
  | str_entry "stdio_handler"
+ | int_entry "max_threads_per_process"
 
let device_entry = bool_entry "mac_filter"
  | bool_entry "relaxed_acs_check"
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 5a85789d81..ab044c9cf3 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -608,6 +608,16 @@
 #max_processes = 0
 #max_files = 0
 
+# If max_threads_per_process is set to a positive integer, libvirt
+# will use it to set the maximum number of threads that can be
+# created by a qemu process. Some VM configurations can result in
+# qemu processes with tens of thousands of threads. systemd-based
+# systems typically limit the number of threads per process to
+# 16k. max_threads_per_process can be used to override default
+# limits in the host OS.
+#
+#max_threads_per_process = 0
+
 # If max_core is set to a non-zero integer, then QEMU will be
 # permitted to create core dumps when it crashes, provided its
 # RAM size is smaller than the limit set.
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index ca76c4fdfa..9603f33e8a 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -930,6 +930,7 @@ qemuInitCgroup(virDomainObjPtr vm,
 nnicindexes, nicindexes,
 vm->def->resource->partition,
 cfg->cgroupControllers,
+cfg->maxThreadsPerProc,
 &priv->cgroup) < 0) {
 if (virCgroupNewIgnoreError())
 goto done;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index daea11dacb..8ac2dc92b5 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -687,6 +687,8 @@ virQEMUDriverConfigLoadProcessEntry(virQEMUDriverConfigPtr 
cfg,
 return -1;
 if (virConfGetValueUInt(conf, "max_files", &cfg->maxFiles) < 0)
 return -1;
+if (virConfGetValueUInt(conf, "max_threads_per_process", 
&cfg->maxThreadsPerProc) < 0)
+return -1;
 
 if (virConfGetValueType(conf, "max_core") == VIR_CONF_STRING) {
 if (virConfGetValueString(conf, "max_core", &corestr) < 0)
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 983e74a3cf..48b8711cbd 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -171,6 +171,7 @@ struct _virQEMUDriverConfig {
 
 unsigned int maxProcesses;
 unsigned int maxFiles;
+unsigned int maxThreadsPerProc;
 unsigned long long maxCore;
 bool dumpGuestCore;
 
diff --git a/src/qemu/test_libvirtd_qemu.aug.in 
b/src/qemu/test_libvirtd_qemu.aug.in
index fea1d308b7..ac7ad59ba8 100644
--- a/src/qemu/test_libvirtd_qemu.aug.in
+++ b/src/qemu/

Re: [libvirt] [PATCH] qemu: Add support for overriding max threads per process limit

2019-06-12 Thread Jim Fehlig

On 6/6/19 11:40 AM, Jim Fehlig wrote:

Some VM configurations may result in a large number of threads created by
the associated qemu process which can exceed the system default limit. The
maximum number of threads allowed per process is controlled by the pids
cgroup controller and is set to 16k when creating VMs with systemd's
machined service. The maximum number of threads per process is recorded
in the pids.max file under the machine's pids controller cgroup hierarchy,
e.g.

$cgrp-mnt/pids/machine.slice/machine-qemu\\x2d1\\x2dtest.scope/pids.max

Maximum threads per process is controlled with the TasksMax property of
the systemd scope for the machine. This patch adds an option to qemu.conf
which can be used to override the maximum number of threads allowed per
qemu process. If the value of option is greater than zero, it will be set
in the TasksMax property of the machine's scope after creating the machine.

Signed-off-by: Jim Fehlig 
---
  src/lxc/lxc_cgroup.c   |  1 +
  src/qemu/libvirtd_qemu.aug |  1 +
  src/qemu/qemu.conf | 10 ++
  src/qemu/qemu_cgroup.c |  1 +
  src/qemu/qemu_conf.c   |  2 ++
  src/qemu/qemu_conf.h   |  1 +
  src/qemu/test_libvirtd_qemu.aug.in |  1 +
  src/util/vircgroup.c   |  6 +-
  src/util/vircgroup.h   |  1 +
  src/util/virsystemd.c  | 24 +++-
  src/util/virsystemd.h  |  3 ++-
  tests/virsystemdtest.c | 12 ++--
  12 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index d93a19d684..76014f3bfd 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -455,6 +455,7 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def,
  nnicindexes, nicindexes,
  def->resource->partition,
  -1,
+0,
  &cgroup) < 0)
  goto cleanup;
  
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug

index b311f02da6..c70b903fed 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -94,6 +94,7 @@ module Libvirtd_qemu =
   | limits_entry "max_core"
   | bool_entry "dump_guest_core"
   | str_entry "stdio_handler"
+ | int_entry "max_threads_per_process"
  
 let device_entry = bool_entry "mac_filter"

   | bool_entry "relaxed_acs_check"
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 5a85789d81..ab044c9cf3 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -608,6 +608,16 @@
  #max_processes = 0
  #max_files = 0
  
+# If max_threads_per_process is set to a positive integer, libvirt

+# will use it to set the maximum number of threads that can be
+# created by a qemu process. Some VM configurations can result in
+# qemu processes with tens of thousands of threads. systemd-based
+# systems typically limit the number of threads per process to
+# 16k. max_threads_per_process can be used to override default
+# limits in the host OS.
+#
+#max_threads_per_process = 0
+
  # If max_core is set to a non-zero integer, then QEMU will be
  # permitted to create core dumps when it crashes, provided its
  # RAM size is smaller than the limit set.
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index ca76c4fdfa..9603f33e8a 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -930,6 +930,7 @@ qemuInitCgroup(virDomainObjPtr vm,
  nnicindexes, nicindexes,
  vm->def->resource->partition,
  cfg->cgroupControllers,
+cfg->maxThreadsPerProc,
  &priv->cgroup) < 0) {
  if (virCgroupNewIgnoreError())
  goto done;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index daea11dacb..8ac2dc92b5 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -687,6 +687,8 @@ virQEMUDriverConfigLoadProcessEntry(virQEMUDriverConfigPtr 
cfg,
  return -1;
  if (virConfGetValueUInt(conf, "max_files", &cfg->maxFiles) < 0)
  return -1;
+if (virConfGetValueUInt(conf, "max_threads_per_process", 
&cfg->maxThreadsPerProc) < 0)
+return -1;
  
  if (virConfGetValueType(conf, "max_core") == VIR_CONF_STRING) {

  if (virConfGetValueString(conf, "max_core", &corestr) < 0)
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 983e74a3cf..48b8711cbd 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -171,6 +171,7 @@ struct _virQEMUDriverConfig {
  
  unsigned int maxProcesses;

  unsigned int maxFiles;
+unsigned int maxThreadsPerProc;
  unsigned long long maxCore;
  bool dumpGuestCore;
  
diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in