We have just received this comment on github, which I think merits some 
explanation:

> There are times when IPC needs to happen, but a sending process cannot wait 
> around for another process to be receiving. seL4_NBSend is basically the 
> system call for this, but it never provides any feedback whether or not IPC 
> took place.

Summary: I accept that this is a valid use case, but the suggested solution is 
not the right one.

There are two reasons why I’m saying this:
1) the current behaviour of send-only IPC is correct and cannot be changed,
2) send-only IPC is the wrong way to address this use case.

Re (1): Anyone who tried to use seL4_Send() or seL4_NBSend() will likely have 
noticed that they are of very little use, because you don’t know whether the 
message was transferred. So, why can't we return at least a boolean value, 
indicating whether a message has been delivered or it was dropped on the floor? 

It’s simple: this would violate the dataflow guarantees provided by seL4. 
Send-only IPC is there to enable one-way information flow, and consequently can 
be invoked using a send-only cap. But a send-only cap must not allow any 
information flow from the receiver to the sender (or else all our isolation 
proofs would break down). Basically, a return status that can be influenced by 
the receiver constitutes a back channel that is not authorised by a cap, and as 
such is verboten. This means that send-only IPC is of very little practical 
use, except where you really want one-way information transfer, or you have a 
higher-level protocol that lets you get away with not knowing whether the 
message was lost. (Eg if the receiver being not ready is a protocol violation 
by the receiver, and it has only itself to blame for losing the message.)

So, could we make send-only IPC a bit more useful by changing the semantics 
slightly? For example, we could have a return value that indicates successful 
message delivery if the send was invoked with a send+receive cap, but will 
always return false if the invocation used a send-only cap?

In principle that would be doable without violating security requirements. The 
cost would be extra checking. It would also be somewhat unsystematic if the 
semantics of a send-only operation would depend on whether your cap has receive 
rights as well. It’d be arguably misleading, as you’re doing more than sending.

This gets me to (2): send-only IPC is the wrong way to solve the problem.

The above use case is clearly one where info flow is inherently two-way: you 
send something and need an acknowledgment of receipt. This means call-type IPC 
is the right mechanism, it does exactly that. And on top of that it is more 
efficient than separate send-receiver, and avoids (thanks to reply caps) the 
need to set up a separate reply channel. 

The problem, of course, is that seL4_Call() is always blocking, there is no 
polling variant of this syscall. 

Should there be an seL4_NBCall()? Arguably yes, just as the RT branch already 
provides a seL4 SignalRecv() syscall, which is the non-blocking equivalent of 
seL4_ReplyRecv(). Will it happen? Possibly, but not in mainline the near 
future. The reason is that to add this (fairly simple) feature to the mainline 
kernel will require verifying it, and our verification engineers are presently 
very busy delivering on contracted milestones.

We’ll discuss this internally. In the meantime I’ve added some explanation of 
the semantics of seL4_Send()/seL4NBSend() to the FAQ on the seL4 wiki.

Gernot
_______________________________________________
Devel mailing list
Devel@sel4.systems
https://sel4.systems/lists/listinfo/devel

Reply via email to