314 |
|
|
315 |
\section{Containers} |
\section{Containers} |
316 |
|
|
317 |
|
In a monolithic kernel, other than through pipes, little data is |
318 |
|
exchanged between tasks: all services are provided by the kernel, a |
319 |
|
trusted entity which is able to directly access tasks' address space. |
320 |
|
In a multiserver system, most data acquisitions come from user space |
321 |
|
servers. As such, powerful primatives for moving memory around is an |
322 |
|
absolute necessity: physical copying must be kept to an absolute |
323 |
|
minimum and there must be a way to use and preserve copy on write |
324 |
|
pages. |
325 |
|
|
326 |
Containers are the basic abstraction used for allocating, addressing |
Containers are the basic abstraction used for allocating, addressing |
327 |
and sharing memory. Conceptually, containers contain a set of |
and sharing memory. Conceptually, containers contain a set of |
328 |
integers identifying \keyword{virtual frame}s in the physical memory |
integers identifying \keyword{virtual frame}s in the physical memory |
373 |
dies before the client, the mappings in the client's address space |
dies before the client, the mappings in the client's address space |
374 |
will suddenly disappear. Similarly, if the server is malicious, it |
will suddenly disappear. Similarly, if the server is malicious, it |
375 |
may revoke the mappings at some inconvenient (i.e. unrecoverable) time |
may revoke the mappings at some inconvenient (i.e. unrecoverable) time |
376 |
for the client causing it to crash. If a server allocates resources |
causing the client to crash or unable to inform the user of the |
377 |
on behalf of the the client it becomes impossible to do system wide |
change. Also, if a server allocates resources on behalf of the the |
378 |
resource accounting as many servers are not trusted by the system. |
client it becomes impossible to do system wide resource accounting as |
379 |
All of these problems are solved by containers. When a client needs |
many servers are not trusted by the system. All of these problems are |
380 |
to read data from a server, it creates a container, adds the number of |
solved by containers. When a client needs to read data from a server, |
381 |
frames that the server will require for the operation to it and |
it creates a container, adds the number of frames that the server will |
382 |
finally shares the container with the server. After sending a request |
require for the operation to it and finally shares the container with |
383 |
to the server, the server copies the data into the provided container. |
the server. After sending a request to the server, the server copies |
384 |
It is important to understand that the server does not ``fill'' the |
the data into the provided container. It is important to understand |
385 |
container: the number of frames remains constant; the state of the |
that the server does not ``fill'' the container: the number of frames |
386 |
bits changes. When the server returns to the client, the client |
remains constant; the state of the bits changes. When the server |
387 |
unshares the container and is now able to map the frames into its |
returns to the client, the client revokes the share and is now able to |
388 |
address space by contacting the physical memory server. Should the |
map the frames into its address space by contacting the physical |
389 |
server die, the client remains uneffected as the data is cached in the |
memory server. Should the server die, the client remains uneffected |
390 |
physical memory server. The physical memory server is also trusted |
as the data lives in the physical memory server. The physical memory |
391 |
thus if a task is malicious, it can only be malicious during the |
server is also trusted thus if a task is malicious, it can only be |
392 |
initial copy of the data into the container, i.e. before the client |
malicious during the initial copy of the data into the container, |
393 |
starts using the data. Finally, as the resources are allocated by the |
i.e. before the client starts using the data and thereby giving the |
394 |
client via system servers, resource accounting is possible. |
client the opportunity to report an inconsistencies to the caller. |
395 |
|
Finally, as the resources are allocated by the client via system |
396 |
|
servers, global resource accounting is possible. |
397 |
|
|
398 |
\subsection{The Container Interface} |
\subsection{The Container Interface} |
399 |
|
|
417 |
access to the container to the remote task: trust between a client and |
access to the container to the remote task: trust between a client and |
418 |
a server must exist, however, that trust is typically limited in both |
a server must exist, however, that trust is typically limited in both |
419 |
directions (neither the client trusts the server fully nor does the |
directions (neither the client trusts the server fully nor does the |
420 |
server fully trust the client). Since clients provide the resources |
server fully trust the client). Since clients provide server with the |
421 |
to server to servers, servers need to a guarantee that the client will |
resources for the operation, servers need a guarantee that the client |
422 |
not touch the resources while it is in a critical section (for example |
will not touch the resources while it is in a critical section. |
423 |
while performing a DMA operation). Likewise, clients need to have the |
Horrific results can emerge if this happens during a DMA operation. |
424 |
ability to cancel an exant request and reclaim shared resources if the |
Likewise, clients need to have the ability to cancel an exant request |
425 |
server does not answer in a timely manner thereby also preventing the |
and reclaim shared resources if the server does not answer in a timely |
426 |
server from being able to steal resources. In both of these cases, |
manner thereby also preventing the server from being able to steal |
427 |
the physical memory server acts as the trusted third party. The |
resources. In both of these cases, the physical memory server acts as |
428 |
physical memory server allows a server to lock a container for a |
the trusted third party. The physical memory server allows a server |
429 |
limited amount of time during which the client may not access or |
to lock a container for a limited amount of time during which the |
430 |
destroy the resource. At any other time, the client can cancel the |
client may not access or destroy the resource. At any other time, the |
431 |
server's access to the shared resource. |
client can cancel the server's access to the shared resource. |
432 |
|
|
433 |
To facility this, a second class capability is provided to access |
To facility this, a second class capability is provided to access |
434 |
containers. Using this capability, clients may not allocate or |
containers. Using this capability, clients may not allocate or |
436 |
|
|
437 |
\begin{code} |
\begin{code} |
438 |
error\_t pm\_container\_share (in container\_t container, in task\_t |
error\_t pm\_container\_share (in container\_t container, in task\_t |
439 |
remote, out container\_t weak_ref) |
remote, out container\_t weak\_ref) |
440 |
\end{code} |
\end{code} |
441 |
|
|
442 |
\noindent |
\noindent |
443 |
\variable{weak\_ref} can be passed to the sharee using the normal |
\variable{weak\_ref} can be passed to the sharee using the normal |
444 |
capability passing protocol. |
capability passing protocol. |
445 |
|
|
446 |
\paragraph{Allocating Memory} |
\paragraph{Allocating and Deallocating Memory} |
447 |
|
|
448 |
Virtual frames may be allocated into a container using: |
Virtual frames may be allocated into a container using: |
449 |
|
|
458 |
allocated in the subsequent $count - 1$ frame identifiers. The number |
allocated in the subsequent $count - 1$ frame identifiers. The number |
459 |
of frames actually allocated is returned in \variable{count}. If an |
of frames actually allocated is returned in \variable{count}. If an |
460 |
identifier already references a virtual frame, \errno{EEXIST} is |
identifier already references a virtual frame, \errno{EEXIST} is |
461 |
returned. \variable{flags} is a bitwise or of: CONT_ALLOC_PARTIAL, |
returned. \variable{flags} is a bitwise or of: |
462 |
CONT_ALLOC_SQUASH and CONT_ALLOC_EXTRA. If CONT_ALLOC_PARTIAL is set |
\constant{CONT\_ALLOC\_PARTIAL}, \constant{CONT\_ALLOC\_SQUASH} and |
463 |
and the number of frames which can be allocated before a memory |
\constant{CONT\_ALLOC\_EXTRA}. If \constant{CONT\_ALLOC\_PARTIAL} is |
464 |
|
set and the number of frames which can be allocated before a memory |
465 |
allocation error occurs is greater than one but less than |
allocation error occurs is greater than one but less than |
466 |
\variable{count} then the maximum number of frames is allocated, count |
\variable{count} then the maximum number of frames is allocated, count |
467 |
is set to that number and the error is returned. If |
is set to that number and the error is returned. If |
468 |
CONT_ALLOC_PARTIAL is not set then partial allocations will fail, |
\constant{CONT\_ALLOC\_PARTIAL} is not set then partial allocations |
469 |
count will be set to 0 and an error will be returned. If |
will fail, count will be set to 0 and an error will be returned. If |
470 |
CONT_ALLOC_SQUASH is set and a frame identifier already references a |
\constant{CONT\_ALLOC\_SQUASH} is set and a frame identifier already |
471 |
frame, the virtual frame will be dropped and its contents lost. Using |
references a frame, the virtual frame will be dropped and its contents |
472 |
this flag is dangerous and be a sign of internal inconsistencies in |
lost. Using this flag is dangerous and be a sign of internal |
473 |
the task! All virtual frames should be accounted for by the task and |
inconsistencies in the task! All virtual frames should be accounted |
474 |
deallocated explicitly. If CONT_ALLOC_EXTRA is set then extra frames |
for by the task and deallocated explicitly. If |
475 |
may be allocated otherwise the physical memory server will only |
\constant{CONT\_ALLOC\_EXTRA} is set then extra frames may be |
476 |
allocate up to the guaranteed virtual frame limit. This flag should |
allocated otherwise the physical memory server will only allocate up |
477 |
only be used by tasks able to handle the added complexity of the extra |
to the guaranteed virtual frame limit. This flag should only be used |
478 |
frame protocol. The contents of allocated frames is undefined. |
by tasks able to handle the added complexity of the extra frame |
479 |
|
protocol. The contents of allocated frames is undefined. |
480 |
|
|
481 |
% When obtaining data from a server (e.g. reading from a file), tasks |
% When obtaining data from a server (e.g. reading from a file), tasks |
482 |
% will: create a container, fill it with anonymous memory and share the |
% will: create a container, fill it with anonymous memory and share the |
483 |
% container with the server. Since this is a very common operation, a |
% container with the server. Since this is a very common operation, a |
484 |
% short cut has been provided to which combines the three operations: |
% short cut has been provided to which combines the three operations: |
485 |
|
|
486 |
|
Deallocating memory is done using: |
487 |
|
|
488 |
|
\begin{code} |
489 |
|
error\_t pm\_container\_deallocate (in container\_t container, in |
490 |
|
frame\_t start, in out int count, in int flags) |
491 |
|
\end{code} |
492 |
|
|
493 |
|
\noindent |
494 |
|
The arguments have similar meaning as those in |
495 |
|
\function{pm\_container\_allocate}. \constant{CONT\_DEALLOC\_PARTIAL} |
496 |
|
and \constant{CONT\_DEALLOC\_SQUASH} are similar to |
497 |
|
\constant{CONT\_ALLOC\_PARTIAL} and \constant{CONT\_ALLOC\_SQUASH} |
498 |
|
respectively. |
499 |
|
|
500 |
\paragraph{Mapping Memory} |
\paragraph{Mapping Memory} |
501 |
|
|
502 |
The physical memory server guarantees that a mapping operation will |
The physical memory server guarantees that a mapping operation takes a |
503 |
take a short amount of time: there is no guarantee that this will |
short amount of time: no guarantee is made that this will happen |
504 |
happen immediately as the underlying physical frames may have to be |
immediately as the underlying physical frames may have to be allocated |
505 |
allocated in which case the physical memory server may have to be reap |
in which case the physical memory server may have to be reap physical |
506 |
physical pages from other tasks' extra frame allocations. |
pages from other tasks' extra frame allocations. |
507 |
|
|
508 |
The physical memory server may unmap pages at any time. This allows |
The physical memory server may unmap pages at any time. This allows |
509 |
the physical memory server to fucntionally lock the contents of the |
the physical memory server to fucntionally lock the contents of the |
510 |
frame and move it to a new physical frame. Given this, tasks must be |
frame and move it to a new physical frame. As such, tasks must be |
511 |
prepared to reestablish a mapping with the physical memory server at |
prepared to reestablish a mapping with the physical memory server at |
512 |
anytime. (Thus, the physical memory server does not serve as a |
anytime. The physical memory server is not a registry of mappings: it |
513 |
registry of mappings.) |
is a cache. |
514 |
|
|
515 |
Read-only mappings may be returned when read/write mapping are |
Read-only mappings may be returned when read/write mapping are |
516 |
requested: the physical memory server will never grant a read/write |
requested: the physical memory server will never grant a read/write |
524 |
\end{code} |
\end{code} |
525 |
|
|
526 |
\noindent |
\noindent |
527 |
Flags may is a bit wise or of: CONT\_MAP\_READ, CONT\_MAP\_WRITE and |
Flags may is a bitwise or of: \constant{CONT\_MAP\_READ}, |
528 |
CONT\_MAP\_FORCE\_WRITE. CONT\_MAP\_FORCE\_WRITE will only be |
\constant{CONT\_MAP\_WRITE} and \constant{CONT\_MAP\_FORCE\_WRITE}. |
529 |
respected if CONT\_MAP\_WRITE is also set. |
\constant{CONT\_MAP\_FORCE\_WRITE} will only be respected if |
530 |
|
\constant{CONT\_MAP\_WRITE} is also set. |
531 |
\paragraph{Moving Data} |
|
532 |
|
\paragraph{Copying Data Into or Out of Containers} |
533 |
In a monolithic kernel, little data is exchanged between tasks. In a |
|
534 |
multiserver system, file systems live in their own tasks and thus |
It is possible to copy data into containers by mapping the frames in |
535 |
reading and writing involve servers. Thus, powerful primatives for |
question and using \function{memcpy}. If this technique is used there |
536 |
moving memory around with the least number of physical copies, |
is no easy way to create logical copies (copy on write): an especially |
537 |
i.e. using virtual copy mechanisms which preserve COW pages, etc. |
important technique for sharing executable and shared library text. A |
538 |
|
family of functions are available which logically copies the contents |
539 |
It is important that an fs does not map from one task to another |
of one container to another: |
540 |
directly: the client may not trust the source or the source may die, |
|
541 |
etc. Doing the mapping via the phys memory server means all trust |
\begin{code} |
542 |
issues are resolved at the time of mapping and can be reported to the |
error\_t pm\_container\_copy (in container\_t src, in frame\_t |
543 |
user: the fs cannot pretend to be nice and then revoke mappings |
src\_start, in src\_count, in countainer\_t dest, in frame\_t |
544 |
silently harming the client. |
dest\_start, in int dest\_count, out frame\_t frame\_error) |
545 |
|
\end{code} |
546 |
|
|
547 |
|
\begin{code} |
548 |
|
error\_t pm\_container\_copy\_scatter (in container\_t src, in frame\_t |
549 |
|
src\_start, in src\_count, in countainer\_t dest, in frame\_t [] |
550 |
|
dest\_frames, out frame\_t frame\_error) |
551 |
|
\end{code} |
552 |
|
|
553 |
|
\begin{code} |
554 |
|
error\_t pm\_container\_copy\_gather (in container\_t src, in frame\_t |
555 |
|
[] src\_frames, in countainer\_t dest, in frame\_t dest\_start, in int |
556 |
|
dest\_count, out frame\_t frame\_error) |
557 |
|
\end{code} |
558 |
|
|
559 |
|
\begin{code} |
560 |
|
error\_t pm\_container\_copy\_scatter\_gather (in container\_t src, in |
561 |
|
frame\_t [] src\_frames, in countainer\_t dest, in frame\_t [] |
562 |
|
dest\_frames, out frame\_t frame\_error) |
563 |
|
\end{code} |
564 |
|
|
565 |
|
If a frame does not exist in the source, ENOENT. If a frame does not |
566 |
|
exist in the destination, ENOMEM is returned. In both cases, the |
567 |
|
frame identifier causing the error is returned in |
568 |
|
\variable{frame\_error}. |
569 |
|
|
570 |
|
\paragraph{Locking Containers and Pinning Memory} |
571 |
|
|
572 |
|
\paragraph{Finding Deallocate Memory} |
573 |
|
|
574 |
|
\paragraph{Reusing frames} |
575 |
|
|
576 |
|
release\_data |
577 |
|
|
578 |
|
\subsection{Moving Data} |
579 |
|
|
580 |
Data will be moved around using containers. Describe how to read and |
Data will be moved around using containers. Describe how to read and |
581 |
write. Task -> FS -> Device drivers. Locking memory. Caching. |
write. Task -> FS -> Device drivers. Locking memory. Caching. |