mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 15:18:20 +00:00
lib/ldso: coalesce RPC calls for ROM dataspaces
A dataspace capability request to a ROM service may invalidate any previously issued dataspace. Therefor no requests should be made while a session dataspace is mapped. Reducing calls to the session also improves performance where servicing a ROM request has a significant cost. Fix #2418
This commit is contained in:
committed by
Christian Helmuth
parent
5f27c7b9eb
commit
419da32ee3
@ -77,13 +77,13 @@ struct Linker::Elf_file : File
|
|||||||
{
|
{
|
||||||
Env &env;
|
Env &env;
|
||||||
Constructible<Rom_connection> rom_connection;
|
Constructible<Rom_connection> rom_connection;
|
||||||
Rom_session_client rom;
|
Rom_dataspace_capability rom_cap;
|
||||||
Ram_dataspace_capability ram_cap[Phdr::MAX_PHDR];
|
Ram_dataspace_capability ram_cap[Phdr::MAX_PHDR];
|
||||||
bool const loaded;
|
bool const loaded;
|
||||||
|
|
||||||
typedef String<64> Name;
|
typedef String<64> Name;
|
||||||
|
|
||||||
Rom_session_capability _rom_cap(Name const &name)
|
Rom_dataspace_capability _rom_dataspace(Name const &name)
|
||||||
{
|
{
|
||||||
/* request the linker and binary from the component environment */
|
/* request the linker and binary from the component environment */
|
||||||
Session_capability cap;
|
Session_capability cap;
|
||||||
@ -91,16 +91,18 @@ struct Linker::Elf_file : File
|
|||||||
cap = env.parent().session_cap(Parent::Env::binary());
|
cap = env.parent().session_cap(Parent::Env::binary());
|
||||||
if (name == linker_name())
|
if (name == linker_name())
|
||||||
cap = env.parent().session_cap(Parent::Env::linker());
|
cap = env.parent().session_cap(Parent::Env::linker());
|
||||||
if (cap.valid())
|
if (cap.valid()) {
|
||||||
return reinterpret_cap_cast<Rom_session>(cap);
|
Rom_session_client client(reinterpret_cap_cast<Rom_session>(cap));
|
||||||
|
return client.dataspace();
|
||||||
|
}
|
||||||
|
|
||||||
rom_connection.construct(env, name.string());
|
rom_connection.construct(env, name.string());
|
||||||
return *rom_connection;
|
return rom_connection->dataspace();
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf_file(Env &env, Allocator &md_alloc, char const *name, bool load)
|
Elf_file(Env &env, Allocator &md_alloc, char const *name, bool load)
|
||||||
:
|
:
|
||||||
env(env), rom(_rom_cap(name)), loaded(load)
|
env(env), rom_cap(_rom_dataspace(name)), loaded(load)
|
||||||
{
|
{
|
||||||
load_phdr();
|
load_phdr();
|
||||||
|
|
||||||
@ -150,7 +152,7 @@ struct Linker::Elf_file : File
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
/* temporary map the binary to read the program header */
|
/* temporary map the binary to read the program header */
|
||||||
Attached_dataspace ds(env.rm(), rom.dataspace());
|
Attached_dataspace ds(env.rm(), rom_cap);
|
||||||
|
|
||||||
Elf::Ehdr const &ehdr = *ds.local_addr<Elf::Ehdr>();
|
Elf::Ehdr const &ehdr = *ds.local_addr<Elf::Ehdr>();
|
||||||
|
|
||||||
@ -242,7 +244,7 @@ struct Linker::Elf_file : File
|
|||||||
*/
|
*/
|
||||||
void load_segment_rx(Elf::Phdr const &p)
|
void load_segment_rx(Elf::Phdr const &p)
|
||||||
{
|
{
|
||||||
Region_map::r()->attach_executable(rom.dataspace(),
|
Region_map::r()->attach_executable(rom_cap,
|
||||||
trunc_page(p.p_vaddr) + reloc_base,
|
trunc_page(p.p_vaddr) + reloc_base,
|
||||||
round_page(p.p_memsz),
|
round_page(p.p_memsz),
|
||||||
trunc_page(p.p_offset));
|
trunc_page(p.p_offset));
|
||||||
@ -253,7 +255,7 @@ struct Linker::Elf_file : File
|
|||||||
*/
|
*/
|
||||||
void load_segment_rw(Elf::Phdr const &p, int nr)
|
void load_segment_rw(Elf::Phdr const &p, int nr)
|
||||||
{
|
{
|
||||||
void *src = env.rm().attach(rom.dataspace(), 0, p.p_offset);
|
void *src = env.rm().attach(rom_cap, 0, p.p_offset);
|
||||||
addr_t dst = p.p_vaddr + reloc_base;
|
addr_t dst = p.p_vaddr + reloc_base;
|
||||||
|
|
||||||
ram_cap[nr] = env.ram().alloc(p.p_memsz);
|
ram_cap[nr] = env.ram().alloc(p.p_memsz);
|
||||||
|
Reference in New Issue
Block a user