From 1d6d6966a1a9d6e722835ba166626fe6e354edb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Fri, 20 Apr 2018 10:54:45 +0200 Subject: [PATCH] rump: add knob to set memlimit By now, rump would query its available RAM quota to determine the memory limit minus some RAM reserved for Genode meta-data. This does not work when the VFS rump plugin is used as the available quota belongs to the VFS server. In this case the memlimit should be set by specifing the RAM in the plugin's config, e.g.: ! ! ! Fixes #2783. --- repos/dde_rump/include/rump/env.h | 7 +++ repos/dde_rump/run/fs_rom_update_ext2.run | 2 +- repos/dde_rump/run/libc_vfs_ext2.run | 2 +- repos/dde_rump/run/libc_vfs_fs_ext2.run | 2 +- repos/dde_rump/run/rump_ext2.run | 2 +- repos/dde_rump/run/vfs_stress_ext2.run | 2 +- repos/dde_rump/src/lib/rump/hypercall.cc | 54 +++++++++++++++---- repos/dde_rump/src/lib/vfs/rump/README | 8 +-- repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc | 19 +++++-- .../src/server/rump_fs/file_system.cc | 6 ++- repos/ports/run/noux_fs.run | 2 +- 11 files changed, 83 insertions(+), 23 deletions(-) diff --git a/repos/dde_rump/include/rump/env.h b/repos/dde_rump/include/rump/env.h index e6fb485404..31d8b8ac6d 100644 --- a/repos/dde_rump/include/rump/env.h +++ b/repos/dde_rump/include/rump/env.h @@ -44,4 +44,11 @@ class Rump::Env Genode::Attached_rom_dataspace &config_rom() { return _config; } }; +/** + * Set rump MEMLIMIT + * + * In case limit is zero, the available RAM quota will be used. + */ +void rump_set_memlimit(Genode::size_t limit); + #endif /* _INCLUDE__RUMP__ENV_H_ */ diff --git a/repos/dde_rump/run/fs_rom_update_ext2.run b/repos/dde_rump/run/fs_rom_update_ext2.run index d0d60d0adf..ff5647aedd 100644 --- a/repos/dde_rump/run/fs_rom_update_ext2.run +++ b/repos/dde_rump/run/fs_rom_update_ext2.run @@ -55,7 +55,7 @@ append config { - + diff --git a/repos/dde_rump/run/libc_vfs_ext2.run b/repos/dde_rump/run/libc_vfs_ext2.run index b520c3f56c..7812dc7dc7 100644 --- a/repos/dde_rump/run/libc_vfs_ext2.run +++ b/repos/dde_rump/run/libc_vfs_ext2.run @@ -3,7 +3,7 @@ set mkfs_opts "-F" set test_build_components "lib/vfs/rump" -set test_vfs_config "" +set test_vfs_config "" set test_boot_modules { rump_fs.lib.so diff --git a/repos/dde_rump/run/libc_vfs_fs_ext2.run b/repos/dde_rump/run/libc_vfs_fs_ext2.run index 0569bb1c6c..0e549eac5e 100644 --- a/repos/dde_rump/run/libc_vfs_fs_ext2.run +++ b/repos/dde_rump/run/libc_vfs_fs_ext2.run @@ -3,7 +3,7 @@ set mkfs_opts "-F" set test_build_components "lib/vfs/rump" -set test_vfs_config "" +set test_vfs_config "" set test_boot_modules { rump_fs.lib.so diff --git a/repos/dde_rump/run/rump_ext2.run b/repos/dde_rump/run/rump_ext2.run index 510890e5e1..1a98deb31e 100644 --- a/repos/dde_rump/run/rump_ext2.run +++ b/repos/dde_rump/run/rump_ext2.run @@ -58,7 +58,7 @@ append config { - + diff --git a/repos/dde_rump/run/vfs_stress_ext2.run b/repos/dde_rump/run/vfs_stress_ext2.run index c5ac9be1ee..4910f06645 100644 --- a/repos/dde_rump/run/vfs_stress_ext2.run +++ b/repos/dde_rump/run/vfs_stress_ext2.run @@ -47,7 +47,7 @@ install_config { - + diff --git a/repos/dde_rump/src/lib/rump/hypercall.cc b/repos/dde_rump/src/lib/rump/hypercall.cc index b8e8e38c42..d09e70d629 100644 --- a/repos/dde_rump/src/lib/rump/hypercall.cc +++ b/repos/dde_rump/src/lib/rump/hypercall.cc @@ -144,12 +144,23 @@ int rumpuser_init(int version, const struct rumpuser_hyperup *hyp) ** Parameter retrieval ** *************************/ +static size_t _rump_memlimit = 0; + + +void rump_set_memlimit(Genode::size_t limit) +{ + _rump_memlimit = limit; +} + + int rumpuser_getparam(const char *name, void *buf, size_t buflen) { - enum { RESERVE_MEM = 2U * 1024 * 1024 }; + enum { + MIN_RESERVE_MEM = 1U << 20, + MIN_RUMP_MEM = 6U << 20, + }; /* support one cpu */ - Genode::log(name); if (!Genode::strcmp(name, "_RUMPUSER_NCPU")) { Genode::strncpy((char *)buf, "1", 2); return 0; @@ -163,16 +174,39 @@ int rumpuser_getparam(const char *name, void *buf, size_t buflen) if (!Genode::strcmp(name, "RUMP_MEMLIMIT")) { - /* leave 2 MB for the Genode */ - size_t rump_ram = Rump::env().env().ram().avail_ram().value; - - if (rump_ram <= RESERVE_MEM) { - Genode::error("insufficient quota left: ", - rump_ram, " < ", (long)RESERVE_MEM, " bytes"); - return -1; + if (!_rump_memlimit) { + Genode::error("no RAM limit set"); + throw -1; + } + + /* + * Set RAM limit and reserve a 10th or at least 1MiB for + * Genode meta-data. + */ + Genode::size_t rump_ram = _rump_memlimit; + size_t const reserve = Genode::max((size_t)MIN_RESERVE_MEM, rump_ram / 10); + + if (reserve < MIN_RESERVE_MEM) { + Genode::error("could not reserve enough RAM for meta-data, need at least ", + (size_t)MIN_RESERVE_MEM >> 20, " MiB"); + throw -1; + } + + rump_ram -= reserve; + + /* check RAM limit is enough... */ + if (rump_ram < MIN_RUMP_MEM) { + Genode::error("RAM limit too small, need at least ", + (size_t)MIN_RUMP_MEM >> 20, " MiB"); + throw -1; + } + + /* ... and is in valid range (overflow) */ + if (rump_ram >= _rump_memlimit) { + Genode::error("rump RAM limit invalid"); + throw -1; } - rump_ram -= RESERVE_MEM; rump_ram = Genode::min((unsigned long)MAX_VIRTUAL_MEMORY, rump_ram); /* convert to string */ diff --git a/repos/dde_rump/src/lib/vfs/rump/README b/repos/dde_rump/src/lib/vfs/rump/README index c8490ca1bb..1413fed502 100644 --- a/repos/dde_rump/src/lib/vfs/rump/README +++ b/repos/dde_rump/src/lib/vfs/rump/README @@ -1,5 +1,7 @@ The vfs_rump plugin enables access to block device backed file systems supported by the rump kernel. A single rump kernel is in use for any -number of nodes. The configuration node takes two arguments: -'fs' specifies the file system type, and 'writeable' specifies if the -mount is read only or writeable, 'writeable' defaults to true. \ No newline at end of file +number of nodes. The configuration node needs two mandatory arguments: + +The 'fs' attribute specifies the file system type, and 'ram' limits the memory +the plugin will use internally. The optional attribute 'writeable' specifies if +the mount is read only or writeable; 'writeable' defaults to true. diff --git a/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc b/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc index b8d571e5b6..4d7e182988 100644 --- a/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc +++ b/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc @@ -795,7 +795,8 @@ class Rump_factory : public Vfs::File_system_factory public: - Rump_factory(Genode::Env &env, Genode::Allocator &alloc) + Rump_factory(Genode::Env &env, Genode::Allocator &alloc, + Genode::Xml_node config) : _timer(env, "rump-sync"), _sync_handler(env.ep(), *this, &Rump_factory::_sync) { @@ -803,8 +804,20 @@ class Rump_factory : public Vfs::File_system_factory rump_io_backend_init(); + /* limit RAM consumption */ + try { + Genode::Number_of_bytes memlimit; + config.attribute("ram").value(&memlimit); + + rump_set_memlimit(memlimit); + } catch (...) { + Genode::error("mandatory 'ram' attribute missing"); + throw Genode::Exception(); + } + /* start rump kernel */ - rump_init(); + try { rump_init(); } + catch (...) { throw Genode::Exception(); } /* register block device */ rump_pub_etfs_register( @@ -843,7 +856,7 @@ extern "C" Vfs::File_system_factory *vfs_file_system_factory(void) { Vfs::File_system *create(Vfs::Env &env, Genode::Xml_node node) override { - static Rump_factory factory(env.env(), env.alloc()); + static Rump_factory factory(env.env(), env.alloc(), node); return factory.create(env, node); } }; diff --git a/repos/dde_rump/src/server/rump_fs/file_system.cc b/repos/dde_rump/src/server/rump_fs/file_system.cc index f2183defed..ba09fd4ace 100644 --- a/repos/dde_rump/src/server/rump_fs/file_system.cc +++ b/repos/dde_rump/src/server/rump_fs/file_system.cc @@ -89,8 +89,12 @@ void File_system::init() Genode::log("Using ", fs_type, " as file system"); + size_t const avail = Rump::env().env().ram().avail_ram().value; + rump_set_memlimit(avail); + /* start rump kernel */ - rump_init(); + try { rump_init(); } + catch (...) { throw Genode::Exception(); } /* register block device */ rump_pub_etfs_register(GENODE_DEVICE, GENODE_BLOCK_SESSION, RUMP_ETFS_BLK); diff --git a/repos/ports/run/noux_fs.run b/repos/ports/run/noux_fs.run index eaad3d8cd3..4b8cf5bf04 100644 --- a/repos/ports/run/noux_fs.run +++ b/repos/ports/run/noux_fs.run @@ -72,7 +72,7 @@ append config { - +