Hi Roman,
I agree. Making the preservation configurable makes the memory reservations more transparent, i.e. everything that requires memory is visible in init's configuration - well, at least if init is used in a static way. Or are there still other memory 'pools' one might not be aware of?
on NOVA, the most important one is the kernel's memory pool, which has a fixed size that is defined in the kernel's linker script. The linker script is located in nova/src/hypervisor.ld (look for '_mempool_f').
Another limited resource is core's capability space, in particular the meta data required to manage the lifetime of capabilities. The details differ from kernel to kernel. On most base platforms, those information are kept in statically allocated arrays, which are dimensioned to accommodate the current scenarios. Core is in a special position because it has to keep track of all capabilities in the system (capabilities are allocated via core's PD service). Since the capability space of core is limited, we should apply Genode's resource-trading concept to capabilities too. In fact, I plan to implement this idea sometime next year. Until then, we have to life with the situation that capability allocations are not properly accounted (which is a potential denial-of-service issue).
One last question: how do I calculate the required memory preservation for init on nova_x86_64, based on the number of children?
I cannot give you a precise formula. My previously reported experiment where I started over 70 children with the default preservation of 128 KiB suggests that 2 KiB per child should suffice. Make it 16 KiB per child and you should be really fine. ;-)
Cheers Norman