This is an old revision of the document!
Memory grants is a inter-procedure communication mechanism to allow processes to transfer large amounts of data. An alternative name of this IPC mechanism is safecopies, as the low-kernel kernel system calls related to using memory grants all contain “safe” in their name.
User-mode processes cannot escape their virtual address space, i.e. they cannot read or write the memory of other processes ; they have to use kernel-provided IPC functionality to exchange data with them. Traditional POSIX solutions to this problem are pipe, sockets, shared memory, signals and others.
The Minix micro-kernel provides fixed-size 64 bytes message passing, but transferring large amounts of data with those messages would be very inefficient. One POSIX IPC could have been implemented in the micro-kernel, however the needs and goals of Minix makes them unsuited for the task, as such an IPC has to satisfy all following criteria at the same time :
Memory grants were created to address the need of IPC provided by the micro-kernel for large amounts of data. This mechanism allows processes to grant access to a well defined region of their memory to another process.
There are three types of memory grants. All share common attributes :
By convention, the granter is the process that created and owns the grant ; the grantee is the process to which the memory grant was granted.
Granters maintain their array of grants in their memory space, the micro-kernel is informed of this array by the SYS_SETGRANT kernel system call. Grantees can, depending on which operations are allowed, read and/or write (copy or set bytes) to the specified memory region of the granter through the relevant kernel system calls.
Those kernel calls are wrapped by higher-level functions in the libsys library (the cpf_* family of functions). Protocol abstraction libraries can provide higher-level semantics to memory grants : an example is directory listing inside a file server, where fsdriver collects directories entries through a callback function and sends them to VFS through a memory grant.
Memory grants are identified by a memory grant credential (an integer of type cp_grant_id_t). Those credentials are transmitted to grantees by message passing.
There are three types of memory grants, depending on whether the grant was transferred from a process to another or not.
Direct grants are the simplest type of grants. They specify that a memory region of the granter is accessible by the grantee. They are direct in the sense that they haven't been transferred : the granter is the owner of the memory region, there is no middleman between the two.
Indirect grants are grants that have been transferred by a grantee : the grantee delegates its grant to another process. The grantee becomes a granter and then pass a newly created memory grant credential to the new grantee. The memory grant thus forms a linked list of indirect grants, with a direct grant at the start.
Indirect grant can themselves be transferred to another grantee by creating a new indirect grant.
TODO: explain magic grants