Checkpointing dataspaces in core

Stefan Kalkowski stefan.kalkowski at ...1...
Tue Aug 2 11:20:23 CEST 2016

Hello Denis,

On 07/29/2016 12:15 PM, Denis Huber wrote:
> Dear Genode community,
> I want to implement a new service (class Cr_session) residing in core 
> which provides an Rpc method to checkpoint the state of a specific 
> component (given its label string). I am using Genode 16.05 and the foc 
> kernel (pbxa9 build). The first step is to store the content of the 
> address space of the compoent. My approach is the following:
> 1) First a test component is created which shall be checkpointed. The 
> component counts an integer every second.
> In base/src/test/cr_service/counter/ (newly created file):
> !void Component::construct(Genode::Env &env)
> !{
> !    unsigned int n = 0;
> !    Timer::Connection timer(env);
> !
> !    while(1)
> !    {
> !        Genode::log(n);
> !        n++;
> !        timer.msleep(1000);
> !    }
> !}
> 2) To realize the CR service in core, I want to find the specific PD 
> session of the test component. Therefore a separate Sliced_heap 
> exclusively for Pd_session_component objects is created in core's main 
> function.
> In base/src/core/
> !static Sliced_heap pd_sliced_heap(env()->ram_session(), 
> env()->rm_session());
> ![...]
> !static Pd_root pd_root(e, e, pager_ep, &pd_sliced_heap);
> 2) The CR service is registered and the special Sliced_heap is passed to 
> the Root_component<Cr_session_component> object.
> In base/src/core/
> !static Cr_root cr_root(e, &sliced_heap, &pd_sliced_heap);
> ![...]
> !static Local_service ls[] = {
> !    Local_service(Cr_session::service_name(), &cr_root),
> ![...]
> !}
> 3) In the implementation of the checkpoint method the Sliced_heap 
> (stored in _alloced_pds) is searched for a Pd_session_component with a 
> specific label string. The class implementing the Cr service 
> (Genode::Cr_session_component : Rpc_object<Cr_session>) is a friend 
> class in Sliced_heap and is allowed to access the _blocks member 
> variable containing the Pd_session_component objects.
> In base/src/core/include/cr_session_component.h (newly created file):
> !bool checkpoint(String<64> label)
> !{
> !    Pd_session_component *pd = nullptr;
> !    bool found = false;
> !    Sliced_heap::Block *b = _alloced_pds->_blocks.first();
> !    for(; (b != 0) && !found; b = b->next())
> !    {
> !        pd = reinterpret_cast<Pd_session_component*>(b + 1);
> !        if(label == pd->_label.string) found = true;
> !    }

I would strongly recommend to not use the heap abstraction for
retrieving any objects. Your implementation is extremely error-prone
when depending on internals of the Sliced_heap implementation, and
indiscriminately casting to some objects. It would be much better to
retrieve the PD object either by running through the object pool where
they reside in, or if you do not want that for some reason, register
them in a special data-structure to retrieve them more easily, e.g., a list.

> 4) The Pd_session_component object is known and now it shall be used to 
> access the test component's address space content. To retrieve the 
> content I want to attach the Dataspace of the component's Region_map to 
> core's Region_map.
> In base/src/core/include/cr_session_component.h (newly created file):
> !    Capability<Region_map> rm_cap = pd->address_space();
> !    Region_map_client rm_client(rm_cap);
> !    void* addr = core_env()->rm_session()->attach(rm_client.dataspace());
> !    return true;
> !}
> 5) After invoking rm_client.dataspace() the Rpc method never returns and 
> the test scenario times out.
> What am I doing wrong? I compared the source code of other core services 
> with the CR service and found no usage of classes derived from 
> Rpc_client belonging to other core services. Is it not possible to use 
> Rpc methods in core?

In general, it is possible to use RPC functions within core, but if you
call a core-service itself within the execution context that provides
these services you fall into a deadlock. Your new service probably uses
the same entrypoint (thereby execution context) like for instance the RM
service. So then it is not possible to invoke this service via RPC calls
from your context.

> I tested another solution where I only use Rpc_objects directly. I used 
> pd_session_component::address_space_region_map() to access the 
> address_space directly, where I think to find the memory content of the 
> test component (Please correct me, if I am wrong).
> The following listing replaces the listing in step 4.
> In base/src/core/include/cr_session_component.h (newly created file):
> !    Dataspace_capability ds_cap = 
> pd->address_space_region_map().dataspace();
> !    char* addr = core_env()->rm_session()->attach(ds_cap);
> !    log("Attaching dataspace: Returned pointer: ", addr);
> !
> !    Dataspace_component *ds_comp = 
> pd->address_space_region_map().dataspace_component();
> !    log("Reading dataspace component");
> !    log("phys_addr = ", ds_comp->phys_addr(), " size = ", 
> ds_comp->size(), " writable = ", ds_comp->writable() ? "true" : "false");
> The output of the log function was the following:
> Attaching dataspace: Returned pointer: 0x00000000
> Reading dataspace component
> phys_addr = 0 size = 3221221376 writable = false
> Now I got a null pointer and cannot read the content of the Region_map 
> of the test component.
> Can someone help me to answer the following questions:
> * Can I use Capability invokation in core, where the Rpc_object belongs 
> to another core service? If yes, how? Perhaps, my problem is the correct 
> retrieval of the Pd_session_component, thus I can invalid Capabilities.
> * Why do I get an invalid pointer from the attach method of core's 
> Region_map? Is it not allowed to attach dataspaces in core? Are they 
> already attached in core, and I only need the pointer to the memory? Is 
> the Dataspace_capability invalid?

As already mentioned, you can call core services within core, but only
from a different execution context than the entrypoint itself, which
implements the core services. Anyway this is not recommended in general,
because you can easily produce circular dependencies.

The correct retrieval of PD components indeed is a problem given your
example. As already explained it is not recommended at all to use the
memory allocator to find objects. This practice is not related to Genode

You can of course attach dataspaces in core. This is used for instance
before core hands out a dataspace when clearing its content.
Nevertheless, when it comes to non-physical dataspaces, which means not
simple dataspaces representing only physical memory, e.g., the
representation of a region-map, you cannot simply attach them within
core. The reason is that core's RM service implementation is much
simpler than the one core provides for all other components, again due
to possible circular dependencies. When you attach a dataspace in core,
the corresponding memory mappings are established immediately. For all
other components than core, a pager service within core resolves
page-faults lazily when they occur. Thereby, more complex dataspaces
like the region map representation are identified too.

I would strongly recommend to you to *not* implement your
checkpoint-service within core. It is far more easy to write an extra
component, which wraps the relevant core services, e.g. PD, RM etc..
That component can hold the capabilities to the relevant core services
in a data-structure that matches your demands. You won't run into
trouble of circular dependencies. You can easily attach region map
representations to its region map, etc..
You can route all relevant services to that component instead of core.
If you really want to target all components you could even place your
component underneath of the init component. Thereby, you can use most
currently available run-scripts with minor changes only.

Best regards

> Kind regards
> Denis
> ------------------------------------------------------------------------------
> _______________________________________________
> genode-main mailing list
> genode-main at

Stefan Kalkowski
Genode Labs ยท

More information about the users mailing list