This patch adds ipc_sendrecv() and opens the way for client/server communication.

ipc_sendrecv() replaces ipc_sendwait() which was flawed. See ipc_sendrecv() for
how client/server communication works. Tested with page faults where the kernel
does an ipc_sendrecv() to faulty thread's pager and the pager successfully handles
the request, and returns back the result, which effectively restarts the faulty
thread.
This commit is contained in:
Bahadir Balban
2008-02-04 21:03:51 +00:00
parent 13ee470a33
commit 70d5ff33cd
5 changed files with 29 additions and 34 deletions

View File

@@ -154,28 +154,31 @@ int ipc_sendwait(l4id_t to)
}
/*
* We currently only support send-receiving from the same task. The receive
* stage is initiated with the special L4_IPC_TAG_IPCRETURN. This tag is used by
* client tasks for receiving returned ipc results back. This is by far the most
* common ipc pattern between client tasks and servers since every such ipc
* request expects a result.
* Both sends and receives mregs in the same call. This is mainly by user
* tasks for client server communication with system servers.
*
* Timeline of client/server communication using ipc_sendrecv():
*
* (1) User task (client) calls ipc_sendrecv();
* (2) System task (server) calls ipc_recv() with from == ANYTHREAD.
* (3) Rendezvous occurs. Both tasks exchange mrs and leave rendezvous.
* (4,5) User task, immediately calls ipc_recv(), expecting a reply from server.
* (4,5) System task handles the request in userspace.
* (6) System task calls ipc_send() sending the return result.
* (7) Rendezvous occurs. Both tasks exchange mrs and leave rendezvous.
*/
int ipc_sendrecv(l4id_t to, l4id_t from)
{
int ret = 0;
if (to == from) {
/* IPC send request stage */
/* Send ipc request */
ipc_send(to);
/*
* IPC result return stage.
*
* If the receiving task is scheduled here, (likely to be a
* server which shouldn't block too long) it would only block
* for a fixed amount of time between these send and receive
* calls.
* Get reply.
* A client would block its server only very briefly
* between these calls.
*/
ipc_recv(from);
} else {

View File

@@ -59,7 +59,7 @@ void fault_ipc_to_pager(u32 faulty_pc, u32 fsr, u32 far)
offsetof(syscall_args_t, r3));
/* Send ipc to the task's pager */
ipc_sendwait(current->pagerid);
ipc_sendrecv(current->pagerid, current->pagerid);
/*
* Pager is now notified and handling the fault. We now sleep on