MsgBuf has to keep the number of received capabilities in order
to free/know correctly unused and unwanted capabilities. Explicitly
call rcv_msg->post_ipc to store this information in a MsgBuf.
Don't reset rcv_msg in ipc.cc, since this is used during
un-marshalling of caps in ipc.h afterwards. The MsgBuf is reseted when its
de-constructor is called.
With this patch solely the local ids are used, no global unique ids
are transfered anymore during IPC.
demo.run, signal.run, noux_tool_chain.run works up to the same
point as before the patches for issue #268.
Fixes#268
Unfortunately, another kernel patch is required for Genode/NOVA to get rid
of global unique ids for objects (issue #268).
Kernel patch:
If a translate of a object capability item inside the same PD
(receiver/sender in same PD) is not successful then he very same item is
returned instead of the null item.
Genode:
Some code in Genode try to map/translate the "root" (the first instance of a)
object capability within the same PD. The translate fails since it is the
first cap and was not delegated beforehand. Instead the cap gets mapped to a
new capability index due to xlt_rcv kernel item patch.
The new local object capability index is used to lookup manged objects
in lists, which however fails because the object is only known by the original
object capability index.
Unfortunately, this happens not only once. Below one example trace and
description is attached.
There are several possible solutions possible:
* Find all places in Genode and replace normal function calls between objects
with IPC calls, such that all capabilities can be translated during IPC.
** Time consuming to find all spots
** Rather platform specific issue requires re-adjustments in generic Genode
code
** Not trivial to ever remember this fact during development of new components
[other platforms have not such a issue, however have global object ids]
** Neither good in terms of performance.
* Use some special system call to the kernel to be able to translate a given
capability index as long until you find the requested original index.
(Obviously ... no comment).
* Kernel patch as this one.
* <your proposal>
Example trace + code description showing the behavior above:
int main(): --- create local services ---
int main(): --- start init ---
[0] DEL OBJ PD:0xc000aa80->0xc000aa80 SB:0x000000aa RB:0x000000ac O:0x00 A:0x1f
int main(): transferred 42 MB to init
[0] DEL OBJ PD:0xc000aa80->0xc000aa80 SB:0x00000120 RB:0x0000013c O:0x00 A:0x1f
[0] DEL OBJ PD:0xc000aa80->0xc000aa80 SB:0x0000016c RB:0x00000168 O:0x00 A:0x1f
Setup ELF failed
[0] XLT OBJ PD:0xc000aa80->0xc000aa80 SB:0x00000168 RB:0x0000016c O:0x00
unknown exception?
int main(): --- init created, waiting for exit condition ---
thread - file - line - text
-------------------------------------------------------------------------------
thread A - [ 0] - 228 - new Core_child(... rom_session.dataspace() ...)
thread A - [ 1] - 27 - IPC call - ask for dataspace cap
thread B - [ 2] - 49 - function - return dataspace cap index 0x120
thread A - [ 1] - 27 - IPC returned - map 0x120 -> 0x13c, translate failed
thread A - ...
thread A - [ 3] - 231 - call _setup_elf()
thread A - [ 3] - 60 - call env->rm_session()->attach()
thread A - [ 4] - 35 - do dataspace object lookup (0x13c)
thread A - [ 4] - 36 - lookup failed (object known as 0x120), throw Exception
thread A - [ 3] - 61 - catch Exception -> return error code "0"
thread A - [ 3] - 233 - "Setup ELF failed" - because error code "0"
File legend:
[0] base/src/core/main.cc
[1] base/include/rom_session/client.h
[2] base-nova/src/core/include/core_rm_session.h
[3] base/src/base/process/process.cc
[4] base-nova/src/core/core_rm_session.cc
Kernel patch:
Introduce a transfer item type to express that a cap should be translated
and if this fails to map it instead.
It would be possible without this combined transfer item type however
with additional overhead. In this case Genode/NOVA would
have to map and translate all caps used as parameter in IPC. It would look
like this:
* If the map and translation succeed, the cap at the new cap index
would have to be revoked. Then the translated cap index can be used.
* If the map succeeds and the translation fails then the mapped cap index
can be used.
* It would become complicated when multiple caps are mapped and translated
and only some of the translation succeed. In such cases Genode would have
to figure out the right relation of translated/mapped and not
translated/mapped caps. It would require to make some assumption about the
order how translated/mapped caps are reported at the UTCB by the kernel.
All the points above lead to the decision to create a separate transfer item
type for that.
Genode:
Most the times the translation succeeds, mapping of caps happens either
seldom. This takes now a bit the pressure of not enough aligned receive
cap windows as described in issue #247.
The patch mainly adds adjustments to handle the
translated and mapped caps correctly especially during freeing of the
receive window (don't free translated cap indexes).
Fixes#268
The additional quota is needed because of the recent performance
optimizations of the USB/networking code, e.g., to support the
increased NIC packet-stream buffer size.
Added SKB bitmap allocator, use Nic::Packet_allocator in packet stream, use slab
allocators on top of back-end AVL allocator, split allocators in cached/uncached
for general purpose/DMA allocation, added patch to original code to distinguish
cached or uncached memory requests, take advantage of and implement TX bursts
(or SKB batching), call interrupt handlers until they return unhandled.
Make calls using IPCs IRQ safe, handle packet exhaustion, removed
'Packet_pool', tweak TCP rmem and wmem buffer sizes to show better performance
results, use 'Net::Packet_allocator, fix 'update-patch' Makefile command
Avoid the use of deprecated 'MASK' enum in CPU register 'Asid'.
Enable the use of the 'K' bit in MMU translations.
Treat any try to modify existing valid entries in section- and
pagetables when doing 'insert_translation' as error.
Beautify concerned files.