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.:

! <vfs>
!   <rump fs="ext2fs" ram="64M" writeabl="yes"/>
! </vfs>

Fixes #2783.
This commit is contained in:
Josef Söntgen 2018-04-20 10:54:45 +02:00 committed by Christian Helmuth
parent a6760efc14
commit 1d6d6966a1
11 changed files with 83 additions and 23 deletions

View File

@ -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_ */

View File

@ -55,7 +55,7 @@ append config {
<resource name="RAM" quantum="10M"/>
<provides><service name="File_system"/></provides>
<config>
<vfs> <rump fs="ext2fs"/> </vfs>
<vfs> <rump fs="ext2fs" ram="8M"/> </vfs>
<policy label_prefix="rom_to_file" root="/" writeable="yes"/>
<policy label_prefix="fs_rom" root="/" writeable="no"/>
</config>

View File

@ -3,7 +3,7 @@ set mkfs_opts "-F"
set test_build_components "lib/vfs/rump"
set test_vfs_config "<rump fs=\"ext2fs\" writeable=\"yes\"/>"
set test_vfs_config "<rump fs=\"ext2fs\" ram=\"7M\" writeable=\"yes\"/>"
set test_boot_modules {
rump_fs.lib.so

View File

@ -3,7 +3,7 @@ set mkfs_opts "-F"
set test_build_components "lib/vfs/rump"
set test_vfs_config "<rump fs=\"ext2fs\" writeable=\"yes\"/>"
set test_vfs_config "<rump fs=\"ext2fs\" ram=\"7M\" writeable=\"yes\"/>"
set test_boot_modules {
rump_fs.lib.so

View File

@ -58,7 +58,7 @@ append config {
<config file="ext2.raw" block_size="512"/>
</start>
<start name="rump_fs" caps="200">
<resource name="RAM" quantum="8M" />
<resource name="RAM" quantum="16M" />
<provides><service name="File_system"/></provides>
<config fs="ext2fs"><policy label_prefix="test-libc_vfs" root="/" writeable="yes"/></config>
</start>

View File

@ -47,7 +47,7 @@ install_config {
<start name="vfs_stress" caps="200">
<resource name="RAM" quantum="32M"/>
<config depth="8">
<vfs> <rump fs="ext2fs" writeable="yes"/> </vfs>
<vfs> <rump fs="ext2fs" ram="30M" writeable="yes"/> </vfs>
</config>
</start>
</config>

View File

@ -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 */

View File

@ -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 <rump> 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.
number of <rump> 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.

View File

@ -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);
}
};

View File

@ -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);

View File

@ -72,7 +72,7 @@ append config {
<resource name="RAM" quantum="100M" />
<provides> <service name="File_system"/> </provides>
<config>
<vfs> <rump fs="ext2fs" writeable="yes"/> </vfs>
<vfs> <rump fs="ext2fs" ram="64M" writeable="yes"/> </vfs>
<default-policy root="/" writeable="yes"/>
</config>
</start>