Consolidate RM service into PD session

This patch integrates three region maps into each PD session to
reduce the session overhead and to simplify the PD creation procedure.
Please refer to the issue cited below for an elaborative discussion.

Note the API change:

With this patch, the semantics of core's RM service have changed. Now,
the service is merely a tool for creating and destroying managed
dataspaces, which are rarely needed. Regular components no longer need a
RM session. For this reason, the corresponding argument for the
'Process' and 'Child' constructors has been removed.

The former interface of the 'Rm_session' is not named 'Region_map'. As a
minor refinement, the 'Fault_type' enum values are now part of the
'Region_map::State' struct.

Issue #1938
This commit is contained in:
Norman Feske
2016-04-15 15:19:22 +02:00
committed by Christian Helmuth
parent e20bbe7002
commit 511acad507
189 changed files with 3314 additions and 2934 deletions

View File

@ -11,13 +11,17 @@
* under the terms of the GNU General Public License version 2.
*/
/* local includes */
#include <linker.h>
#include <base/internal/page_size.h>
#include <base/allocator_avl.h>
#include <os/attached_rom_dataspace.h>
#include <rm_session/connection.h>
/* Genode includes */
#include <util/construct_at.h>
#include <base/allocator_avl.h>
#include <base/env.h>
#include <os/attached_rom_dataspace.h>
#include <region_map/client.h>
#include <util/retry.h>
char const *Linker::ELFMAG = "\177ELF";
@ -33,12 +37,16 @@ namespace Linker
/**
* Managed dataspace for ELF files (singelton)
*/
class Linker::Rm_area : public Rm_connection
class Linker::Rm_area
{
public:
typedef Region_map_client::Local_addr Local_addr;
typedef Region_map_client::Region_conflict Region_conflict;
private:
/* size of dataspace */
enum { RESERVATION = 160 * 1024 * 1024 };
Region_map_client _rm;
addr_t _base; /* base address of dataspace */
Allocator_avl _range; /* VM range allocator */
@ -46,12 +54,10 @@ class Linker::Rm_area : public Rm_connection
protected:
Rm_area(addr_t base)
: Rm_connection(0, RESERVATION), _range(env()->heap())
: _rm(env()->pd_session()->linker_area()), _range(env()->heap())
{
on_destruction(KEEP_OPEN);
_base = (addr_t) env()->rm_session()->attach_at(dataspace(), base);
_range.add_range(base, RESERVATION);
_base = (addr_t) env()->rm_session()->attach_at(_rm.dataspace(), base);
_range.add_range(base, Pd_session::LINKER_AREA_SIZE);
}
public:
@ -96,21 +102,32 @@ class Linker::Rm_area : public Rm_connection
void free_region(addr_t vaddr) { _range.free((void *)vaddr); }
/**
* Overwritten from 'Rm_connection'
* Overwritten from 'Region_map_client'
*/
Local_addr attach_at(Dataspace_capability ds, addr_t local_addr,
size_t size = 0, off_t offset = 0) {
return Rm_connection::attach_at(ds, local_addr - _base, size, offset); }
size_t size = 0, off_t offset = 0)
{
return retry<Region_map::Out_of_metadata>(
[&] () {
return _rm.attach_at(ds, local_addr - _base, size, offset);
},
[&] () { env()->parent()->upgrade(env()->pd_session_cap(), "ram_quota=8K"); });
}
/**
* Overwritten from 'Rm_connection'
* Overwritten from 'Region_map_client'
*/
Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr,
size_t size = 0, off_t offset = 0) {
return Rm_connection::attach_executable(ds, local_addr - _base, size, offset); }
size_t size = 0, off_t offset = 0)
{
return retry<Region_map::Out_of_metadata>(
[&] () {
return _rm.attach_executable(ds, local_addr - _base, size, offset);
},
[&] () { env()->parent()->upgrade(env()->pd_session_cap(), "ram_quota=8K"); });
}
void detach(Local_addr local_addr) {
Rm_connection::detach((addr_t)local_addr - _base); }
void detach(Local_addr local_addr) { _rm.detach((addr_t)local_addr - _base); }
};
@ -306,7 +323,7 @@ File const *Linker::load(char const *path, bool load)
if (verbose_loading)
PDBG("loading: %s (PHDRS only: %s)", path, load ? "no" : "yes");
Elf_file *file = new(env()->heap()) Elf_file(Linker::file(path), load);
Elf_file *file = new (env()->heap()) Elf_file(Linker::file(path), load);
return file;
}

View File

@ -25,7 +25,7 @@ addr_t init_main_thread_result;
extern void init_exception_handling();
namespace Genode { extern Rm_session * const env_stack_area_rm_session; }
namespace Genode { extern Region_map * const env_stack_area_region_map; }
void prepare_init_main_thread();