Add support of the memtune's hard_limit configuration: <memtune> <hard_limit ... > </memtune> to the bhyve driver. Just like in the block I/O tuning case, memory limits are set using the rctl(8) tool. Syntax for that is: rctl -a process:<pid>:memoryuse:deny=1073741824 Extend bhyveSetResourceLimits() to execute this command if it's requested by the domain XML. Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/bhyve/bhyve_domain.c | 8 ++++++ src/bhyve/bhyve_process.c | 26 +++++++++++------ ...vexml2argv-memtune-unsupported-params.args | 10 +++++++ ...xml2argv-memtune-unsupported-params.ldargs | 4 +++ ...yvexml2argv-memtune-unsupported-params.xml | 28 +++++++++++++++++++ .../x86_64/bhyvexml2argv-memtune.args | 10 +++++++ .../x86_64/bhyvexml2argv-memtune.ldargs | 4 +++ .../x86_64/bhyvexml2argv-memtune.xml | 26 +++++++++++++++++ tests/bhyvexml2argvtest.c | 2 ++ 9 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.args create mode 100644 tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.ldargs create mode 100644 tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.xml create mode 100644 tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.args create mode 100644 tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.ldargs create mode 100644 tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.xml diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c index 6367985efc..86e4de1fd8 100644 --- a/src/bhyve/bhyve_domain.c +++ b/src/bhyve/bhyve_domain.c @@ -541,6 +541,14 @@ bhyveDomainDefValidate(const virDomainDef *def, } } + if (virMemoryLimitIsSet(def->mem.soft_limit) || + virMemoryLimitIsSet(def->mem.swap_hard_limit) || + def->mem.min_guarantee) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only 'hard_limit' memory tuning parameter is supported by bhyve")); + return -1; + } + if (!def->os.loader) return 0; diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c index 7652a998e5..7baefeb63b 100644 --- a/src/bhyve/bhyve_process.c +++ b/src/bhyve/bhyve_process.c @@ -53,6 +53,7 @@ #include "virnetdevbridge.h" #include "virnetdevtap.h" #include "virtime.h" +#include "virutil.h" #define VIR_FROM_THIS VIR_FROM_BHYVE @@ -138,7 +139,8 @@ bhyveSetResourceLimits(struct _bhyveConn *driver, virDomainObj *vm) { virBlkioDevice *device; - if (vm->def->blkio.ndevices != 1) + if ((vm->def->blkio.ndevices != 1) && + !virMemoryLimitIsSet(vm->def->mem.hard_limit)) return 0; if ((bhyveDriverGetBhyveCaps(driver) & BHYVE_CAP_RCTL) == 0) { @@ -147,24 +149,30 @@ bhyveSetResourceLimits(struct _bhyveConn *driver, virDomainObj *vm) return -1; } - device = &vm->def->blkio.devices[0]; - -#define BHYVE_APPLY_RCTL_RULE(field, type, format) \ +#define BHYVE_APPLY_RCTL_RULE(field, type, action, format) \ do { \ if ((field)) { \ g_autofree char *rule = NULL; \ g_autoptr(virCommand) cmd = virCommandNewArgList("rctl", "-a", NULL); \ - virCommandAddArgFormat(cmd, "process:%d:" type ":throttle=" format, \ + virCommandAddArgFormat(cmd, "process:%d:" type ":" action "=" format, \ vm->pid, (field)); \ if (virCommandRun(cmd, NULL) < 0) \ return -1; \ } \ } while (0) - BHYVE_APPLY_RCTL_RULE(device->riops, "readiops", "%u"); - BHYVE_APPLY_RCTL_RULE(device->wiops, "writeiops", "%u"); - BHYVE_APPLY_RCTL_RULE(device->rbps, "readbps", "%llu"); - BHYVE_APPLY_RCTL_RULE(device->wbps, "writebps", "%llu"); + if (vm->def->blkio.ndevices == 1) { + device = &vm->def->blkio.devices[0]; + + BHYVE_APPLY_RCTL_RULE(device->riops, "readiops", "throttle", "%u"); + BHYVE_APPLY_RCTL_RULE(device->wiops, "writeiops", "throttle", "%u"); + BHYVE_APPLY_RCTL_RULE(device->rbps, "readbps", "throttle", "%llu"); + BHYVE_APPLY_RCTL_RULE(device->wbps, "writebps", "throttle", "%llu"); + } + + /* rctl(8) uses bytes for these values and def->mem.* uses kibibytes */ + if (virMemoryLimitIsSet(vm->def->mem.hard_limit)) + BHYVE_APPLY_RCTL_RULE(vm->def->mem.hard_limit * 1024, "memoryuse", "deny", "%llu"); #undef BHYVE_APPLY_RCTL_RULE diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.args b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.args new file mode 100644 index 0000000000..507e0be668 --- /dev/null +++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.args @@ -0,0 +1,10 @@ +bhyve \ +-c 1 \ +-m 214 \ +-u \ +-H \ +-P \ +-s 0:0,hostbridge \ +-s 2:0,ahci,hd:/tmp/freebsd.img \ +-s 3:0,virtio-net,faketapdev,mac=52:54:00:b9:94:02 \ +bhyve diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.ldargs b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.ldargs new file mode 100644 index 0000000000..5905f4b3e6 --- /dev/null +++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.ldargs @@ -0,0 +1,4 @@ +bhyveload \ +-m 214 \ +-d /tmp/freebsd.img \ +bhyve diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.xml b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.xml new file mode 100644 index 0000000000..af1e25805d --- /dev/null +++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune-unsupported-params.xml @@ -0,0 +1,28 @@ +<domain type='bhyve'> + <name>bhyve</name> + <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid> + <memory>219136</memory> + <memtune> + <soft_limit unit='M'>512</soft_limit> + <swap_hard_limit unit='G'>1</swap_hard_limit> + <min_guarantee unit='M'>128</min_guarantee> + </memtune> + <vcpu>1</vcpu> + <os> + <type>hvm</type> + </os> + <devices> + <disk type='file'> + <driver name='file' type='raw'/> + <source file='/tmp/freebsd.img'/> + <target dev='hda' bus='sata'/> + <address type='drive' controller='0' bus='0' target='2' unit='0'/> + </disk> + <interface type='bridge'> + <mac address='52:54:00:b9:94:02'/> + <model type='virtio'/> + <source bridge="virbr0"/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + </devices> +</domain> diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.args b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.args new file mode 100644 index 0000000000..507e0be668 --- /dev/null +++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.args @@ -0,0 +1,10 @@ +bhyve \ +-c 1 \ +-m 214 \ +-u \ +-H \ +-P \ +-s 0:0,hostbridge \ +-s 2:0,ahci,hd:/tmp/freebsd.img \ +-s 3:0,virtio-net,faketapdev,mac=52:54:00:b9:94:02 \ +bhyve diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.ldargs b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.ldargs new file mode 100644 index 0000000000..5905f4b3e6 --- /dev/null +++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.ldargs @@ -0,0 +1,4 @@ +bhyveload \ +-m 214 \ +-d /tmp/freebsd.img \ +bhyve diff --git a/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.xml b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.xml new file mode 100644 index 0000000000..f8bcd23296 --- /dev/null +++ b/tests/bhyvexml2argvdata/x86_64/bhyvexml2argv-memtune.xml @@ -0,0 +1,26 @@ +<domain type='bhyve'> + <name>bhyve</name> + <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid> + <memory>219136</memory> + <memtune> + <hard_limit unit='M'>512</hard_limit> + </memtune> + <vcpu>1</vcpu> + <os> + <type>hvm</type> + </os> + <devices> + <disk type='file'> + <driver name='file' type='raw'/> + <source file='/tmp/freebsd.img'/> + <target dev='hda' bus='sata'/> + <address type='drive' controller='0' bus='0' target='2' unit='0'/> + </disk> + <interface type='bridge'> + <mac address='52:54:00:b9:94:02'/> + <model type='virtio'/> + <source bridge="virbr0"/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + </devices> +</domain> diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c index eb2c1d33b8..818b51e178 100644 --- a/tests/bhyvexml2argvtest.c +++ b/tests/bhyvexml2argvtest.c @@ -301,6 +301,8 @@ mymain(void) DO_TEST_FAILURE("virtio-console-too-many-ports"); DO_TEST_FAILURE("virtio-console-invalid-name"); DO_TEST_FAILURE("virtio-console-invalid-path"); + DO_TEST("memtune"); + DO_TEST_FAILURE("memtune-unsupported-params"); /* Address allocation tests */ DO_TEST("addr-single-sata-disk"); -- 2.52.0