529 |
\constant{CONT\_MAP\_FORCE\_WRITE} will only be respected if |
\constant{CONT\_MAP\_FORCE\_WRITE} will only be respected if |
530 |
\constant{CONT\_MAP\_WRITE} is also set. |
\constant{CONT\_MAP\_WRITE} is also set. |
531 |
|
|
532 |
|
\paragraph{Doing It All At Once} |
533 |
|
|
534 |
|
When reading to or writing data from a server, the task will normally: |
535 |
|
allocate a new container, fill it with memory and share the container |
536 |
|
with the server. Since this is such a common operation, short cuts |
537 |
|
are provided to reduce the required number of rpcs: |
538 |
|
|
539 |
|
\begin{code} |
540 |
|
error\_t pm\_container\_create\_with (out container\_t container, in |
541 |
|
in int frame\_count, out container\_t weak\_ref) |
542 |
|
\end{code} |
543 |
|
|
544 |
|
\begin{code} |
545 |
|
error\_t pm\_container\_create\_from (out container\_t container, in |
546 |
|
container\_t source, in frame\_t start, in int count, out container\_t |
547 |
|
weak\_ref) |
548 |
|
\end{code} |
549 |
|
|
550 |
|
\begin{code} |
551 |
|
error\_t pm\_container\_create\_grather (out container\_t container, |
552 |
|
in container\_t source, in frame\_t [] frames, out container\_t |
553 |
|
weak\_ref) |
554 |
|
\end{code} |
555 |
|
|
556 |
\paragraph{Copying Data Into or Out of Containers} |
\paragraph{Copying Data Into or Out of Containers} |
557 |
|
|
558 |
It is possible to copy data into containers by mapping the frames in |
It is possible to copy data into containers by mapping the frames in |
564 |
|
|
565 |
\begin{code} |
\begin{code} |
566 |
error\_t pm\_container\_copy (in container\_t src, in frame\_t |
error\_t pm\_container\_copy (in container\_t src, in frame\_t |
567 |
src\_start, in src\_count, in countainer\_t dest, in frame\_t |
src\_start, in countainer\_t dest, in frame\_t dest\_start, in int |
568 |
dest\_start, in int dest\_count, out frame\_t frame\_error) |
frame\_count, out frame\_t frame\_error) |
569 |
\end{code} |
\end{code} |
570 |
|
|
571 |
\begin{code} |
\begin{code} |
572 |
error\_t pm\_container\_copy\_scatter (in container\_t src, in frame\_t |
error\_t pm\_container\_copy\_scatter (in container\_t src, in |
573 |
src\_start, in src\_count, in countainer\_t dest, in frame\_t [] |
frame\_t src\_start, in countainer\_t dest, in frame\_t [] |
574 |
dest\_frames, out frame\_t frame\_error) |
dest\_frames, out frame\_t frame\_error) |
575 |
\end{code} |
\end{code} |
576 |
|
|
577 |
\begin{code} |
\begin{code} |
578 |
error\_t pm\_container\_copy\_gather (in container\_t src, in frame\_t |
error\_t pm\_container\_copy\_gather (in container\_t src, in frame\_t |
579 |
[] src\_frames, in countainer\_t dest, in frame\_t dest\_start, in int |
[] src\_frames, in countainer\_t dest, in frame\_t dest\_start, out |
580 |
dest\_count, out frame\_t frame\_error) |
frame\_t frame\_error) |
581 |
\end{code} |
\end{code} |
582 |
|
|
583 |
\begin{code} |
\begin{code} |
830 |
|
|
831 |
\section{Self Paging} |
\section{Self Paging} |
832 |
|
|
833 |
Tasks multiplex guaranteed frames. Must manage their own memory. How |
As already explained, tasks are self-paged. The default |
834 |
to get data (e.g. extend malloc via the slab mechanism, extend fopen). |
implementation provided with the hurd has each thread in a task set |
835 |
|
its pager (i.e. its fault handler) to a common pager thread in the |
836 |
Multiplexing guaranteed frames: say the contents of a frame are sent |
same address space. This thread maintains a mapping database which |
837 |
to swap in order to reuse the frame for something else. The frame |
associates virtual addresses with either a frame of memory in a |
838 |
itself must be cleared, i.e. disassocitated with any logical copies. |
container or information on how to retrieve the data, e.g. from swap |
839 |
This is done using: |
or a file server. |
840 |
|
|
841 |
|
Normally, there is a single primary container for virtual frames that |
842 |
|
is created at start up. A task may choose to use more containers and |
843 |
|
generally will for short periods of time (for instance, for reading to |
844 |
|
and writing from servers). The pager must always be able to handle |
845 |
|
multiple containers. When using additional containers, frames need to |
846 |
|
be added to them to be shared with the server. The pager must provide |
847 |
|
a mechanism to allow the caller to steal guaranteed frames for this |
848 |
|
purpose and return them upon deallocation of the container. |
849 |
|
|
850 |
|
\subsection{The Pager} |
851 |
|
|
852 |
|
The pager itself may require a fair amount of memory for its database |
853 |
|
and all of the code and supporting libraries. This presents a |
854 |
|
problem: if the pager handles page faults, who will handle its faults? |
855 |
|
One of two solutions are possible: either all of the text and data |
856 |
|
must be wired into memory (thereby reducing the number of frames |
857 |
|
available for multiplexing application memory) or the pager is itself |
858 |
|
paged. The default self-pager implementation uses the latter option: |
859 |
|
the pager, now referred to as the primary pager, is backed by a final |
860 |
|
pager. The final pager only maps the pagers text and data thus it has |
861 |
|
a significantly smaller memory footprint. Care must be taken to be |
862 |
|
sure that the primary pager does not accidently allocate memory from |
863 |
|
common memory pools: in the very least it needs its own private |
864 |
|
\function{malloc} arena. As the primary pager will call, for |
865 |
|
instance, routines to manipulate capabilities, this text must be |
866 |
|
backed by the final pager. Other code can also, however, makes calls |
867 |
|
to the capability library. This means that the primary pager must |
868 |
|
also have a copy of these mappings in its database. |
869 |
|
|
870 |
|
The purpose of the final pager is to allow the data and some of the |
871 |
|
text of the primary pager to be swapped. As such, the final pager |
872 |
|
must be able to at least read data from file servers and retrieve data |
873 |
|
from backing store. This may imply significant overlap of the text |
874 |
|
for the primary and final pagers. In some case, however, it may be |
875 |
|
useful to have a second implementation of a function only for the |
876 |
|
final pager which is optimized for size or avoids making calls to |
877 |
|
certain libraries. |
878 |
|
|
879 |
|
\subsubsection{Managing Mappings} |
880 |
|
|
881 |
|
Mappings are normally made via calls to \function{mmap}. Unlike in |
882 |
|
Unix, this is not a system trap: instead it is almost always |
883 |
|
implemented locally. \function{mmap} must associate a region with |
884 |
|
either anonymous memory or with a file on disk. This is only a matter |
885 |
|
of creating a few entries in the mapping database so that faults will |
886 |
|
brings the data in lazily. |
887 |
|
|
888 |
|
Rather than have the caller manipulate the mapping database directly, |
889 |
|
instead, a local ipc sent to the primary pager. If there is only ever |
890 |
|
a single thread which manipulates the mapping database, there will be |
891 |
|
locking requirements. If the pager thread is busy, then the local ipc |
892 |
|
call blocks in the kernel. |
893 |
|
|
894 |
|
It is not always useful to fault memory in lazily: when a task has |
895 |
|
received data from a server, it will normally be in a container from |
896 |
|
where it must be consumed. The task will generally map the container |
897 |
|
into memory and then proceed to use or at least copy the data to some |
898 |
|
other location. Clearly, the faulting the pages in is a waste. As |
899 |
|
such, the pager should provide a mechanism which allows the caller to |
900 |
|
not only establish a mapping from a container but also to map the |
901 |
|
pages immediately in the address space. |
902 |
|
|
903 |
|
\subsection{Reusing Virtual Frames} |
904 |
|
|
905 |
|
Multiplexing frames: say the contents of a frame are sent to swap in |
906 |
|
order to reuse the frame for something else. The frame itself must be |
907 |
|
cleared, i.e. disassocitated with any logical copies. This is done |
908 |
|
using: |
909 |
|
|
910 |
\begin{code} |
\begin{code} |
911 |
error\_t pm\_release\_data (in pm\_container\_t container, in pm\_frame\_t[] frames) |
error\_t pm\_release\_data (in pm\_container\_t container, in pm\_frame\_t[] frames) |
912 |
\end{code} |
\end{code} |
913 |
|
|
914 |
|
\subsection{Taking Advantage of Self-Paging} |
915 |
|
|
916 |
|
extend malloc via e.g. the slab mechanism, extend fopen (how a file is |
917 |
|
used). |
918 |
|
|
919 |
% Traditionally, monolithical kernels, but even kernels like Mach, |
% Traditionally, monolithical kernels, but even kernels like Mach, |
920 |
% provide a virtual memory management system in the kernel. All paging |
% provide a virtual memory management system in the kernel. All paging |