Layers are realized by procedures in the task's process, and moving up and down the layers is achieved using procedure calls. Communication between tasks is done by asynchronous messages. With upcalls, there is no need to buffer between layers, since going between layers is simply a procedure call. Procedure calls are easier to understand and much cheaper than message passing. Because a task is self-contained inside of a process, instead of spread out among layers, decisions on how a task is structured can be made later.
Layers often perform poorly because of a lack of communication between layers.
Through upcalls, lower layers can get information from upper layers, which can help them perform more efficiently. One of the problems with upcalls is handling a failure in an upcalled layer. Once a lower layer has determined that an upcalled layer has failed, it must be able to free any resources that the upcalled layer was using, and the entire task must be either recoverable or expendable. Another problem with upcalls is handling indirect recursive calls , where an upcalled layer calls back down to the layer that called it. This is cumbersome.