[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

synchronous RPCs vs. asynchronous RPCs

From: Marcus Brinkmann
Subject: synchronous RPCs vs. asynchronous RPCs
Date: Fri, 5 Sep 2003 01:44:52 +0200
User-agent: Mutt/1.5.4i


here is food for thought.

Heretic claim of the day:

"We should only do synchronous RPCs, and implement all asynchronous RPCs as
 synchronous RPCs performed by a helper thread."

This applies to select()/poll(), asynchronous msync() and other operations
like that.  I don't think it should apply to notifications like task death
notifications (although... I am still considering it!  If we can restrict it
to task death notifications, we only need one thread.  Object death
notifications for other capabilities can (from the servers point of view)
safely deferred until the client actually tries to use the capability the
next time - I have to check the Hurd code if other object death
notifications are needed).


* An RPC consists of a send and a reply phase.  The only way for a client
  to make sure it will reliably receive the reply is to go from the send to
  the receive operation atomically _and block_.  The server just can
  sensibly assume that if the client doesn't care about the reply, it might be
  malicious and not sincere.
* Consequence:  This allows for a simple way to aviod DoS attacks on
  servers, without using redirectors for clients: Every client thread is
  only allowed to perform one RPC in any server at the same time.  This
  means that if a server is processing an RPC by client thread T, then any
  further RPC from that thread is rejected until the first one completed.
  This makes sure that no more worker threads are created in the server than
  there are client threads, and thus provides an easy to enforce upper limit
  on the number of required threads.  (Note: this is not a strict limit:
  Circular calls like Client -> Server S -> Server R -> S -> R -> S ->R...
  can increase the number of threads in the servers.  But such a setup would
  eventually terminate, and doesn't cause real world problems because of trust
  restrictions and resource limits).
* Further consequence: Easy RPC interruption! If an RPC in a server is
  interrupted by the client (by the signal thread, usually), it can simply
  and uniquely be identified by the client's thread ID.  No sequence numbers
  are needed to distinguish RPCs.
* Good resource tracking: The client pays all costs associated with the RPC.
  This is not obvious, so here is an example: an asynchronous msync means
  that the client continues to run after the msync() invocation.  But that
  means that the filesystem would have to pay for a copy of the synced page
  until the page is actually written back.  This opens a DoS attack.  By
  requiring the client to provide the page in a container with a synchronous
  msync(), the filesystem does not need to pay for a copy and can work on the
  client's resources.
I strongly believe in these advantages, so I am going to radically consider
synchronous requirements for the Hurd interfaces.  This is not a dogma, but
it will be a strong paradigm.  If object death notifications are unnecessary
except for the task server case, we might be able to completely eliminate
the need for notifications entirely (and just have the client poll

This is of course open to discussion.  But it solves a lot of otherwise
complicated problems.


`Rhubarb is no Egyptian god.' GNU      http://www.gnu.org    address@hidden
Marcus Brinkmann              The Hurd http://www.gnu.org/software/hurd/

reply via email to

[Prev in Thread] Current Thread [Next in Thread]