Ursprünglich ist es Teil des Quellcodes des Linux-Kernels, daher wird es als GPLv2 behandelt (Anerkennung, dass es sein sollte).
https://www.kernel.org/doc/html/latest/index.html
Licensing documentation
The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.
https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing
https://www.kernel.org/doc/html/latest/vm/highmem.html
High Memory Handling By: Peter Zijlstra [email protected]
What Is High Memory?
High memory (highmem) is used when the size of physical memory approaches or exceeds the maximum size of virtual memory.
High Memory (Highmem) wird verwendet, wenn sich die Größe des physischen Speichers der maximalen Größe des virtuellen Speichers nähert oder diese überschreitet.
At that point it becomes impossible for the kernel to keep all of the available physical memory mapped at all times.
Ab diesem Zeitpunkt ist es nicht mehr möglich, den gesamten für den Kernel verfügbaren physischen Speicher jederzeit zuzuordnen.
This means the kernel needs to start using temporary mappings of the pieces of physical memory that it wants to access.
Dies bedeutet, dass Sie vorübergehend mit der Zuordnung eines Teils des physischen Speichers beginnen müssen, auf den der Kernel zugreifen möchte.
.
The part of (physical) memory not covered by a permanent mapping is what we refer to as ‘highmem’.
Der Teil des (physischen) Speichers, der nicht allein durch persistente Zuordnung abgedeckt wird, wird als "Highmem" bezeichnet. ..
There are various architecture dependent constraints on where exactly that border lies.
Es gibt verschiedene architekturabhängige Einschränkungen, wo sich die Grenzen befinden.
.
In the i386 arch, for example, we choose to map the kernel into every process’s VM space so that we don’t have to pay the full TLB invalidation costs for kernel entry/exit.
Wählen Sie beispielsweise für den i386-Bogen aus, dass der Kernel für alle Prozesse dem Speicherplatz der virtuellen Maschine zugeordnet werden soll. Wir müssen nicht mehr die vollen TLB-Invalidierungskosten für den Kernelein- / -ausgang bezahlen.
This means the available virtual memory space (4GiB on i386) has to be divided between user and kernel space.
Dies bedeutet, dass der verfügbare virtuelle Speicherplatz (4 GB auf dem i386) zwischen dem Benutzer und dem Kernelbereich aufgeteilt wird.
.
The traditional split for architectures using this approach is 3:1, 3GiB for userspace and the top 1GiB for kernel space:
Die traditionelle Split-Methode für Architekturen, die diesen Ansatz verfolgen, ist 3: 1 mit 3 GB im Benutzerbereich und 1 GB im Kernelbereich.
.
+--------+ 0xffffffff
| Kernel |
+--------+ 0xc0000000
| |
| User |
| |
+--------+ 0x00000000
This means that the kernel can at most map 1GiB of physical memory at any one time, but because we need virtual address space for other things - including temporary maps to access the rest of the physical memory - the actual direct map will typically be less (usually around ~896MiB).
Dies bedeutet, dass der Kernel bis zu 1 GiB physischen Speicher gleichzeitig zuordnen kann. Die tatsächliche direkte Zuordnung ist normalerweise geringer (normalerweise etwa 896 MB), da für andere Dinge virtueller Adressraum erforderlich ist, z. B. eine temporäre Zuordnung, um auf den Rest des physischen Speichers zuzugreifen.
.
Other architectures that have mm context tagged TLBs can have separate kernel and user maps. Some hardware (like some ARMs), however, have limited virtual space when they use mm context tags.
Andere Architekturen mit TLBs mit mm-Kontext-Tag können einen geteilten Kernel und eine Benutzerzuordnung haben. Auf einigen Hardwarekomponenten (z. B. einem Teil von ARM) wird durch die Verwendung von mm-Kontext-Tags der virtuelle Speicherplatz begrenzt.
Temporary Virtual Mappings
The kernel contains several ways of creating temporary mappings:
Der Kernel bietet verschiedene Möglichkeiten, um temporäre Zuordnungen zu generieren.
.
- vmap(). This can be used to make a long duration mapping of multiple physical pages into a contiguous virtual space. It needs global synchronization to unmap.
- kmap(). This permits a short duration mapping of a single page. It needs global synchronization, but is amortized somewhat. It is also prone to deadlocks when using in a nested fashion, and so it is not recommended for new code.
- kmap_atomic(). This permits a very short duration mapping of a single page. Since the mapping is restricted to the CPU that issued it, it performs well, but the issuing task is therefore required to stay on that CPU until it has finished, lest some other task displace its mappings. . kmap_atomic() may also be used by interrupt contexts, since it is does not sleep and the caller may not sleep until after kunmap_atomic() is called. . It may be assumed that k[un]map_atomic() won’t fail.
Using kmap_atomic
When and where to use kmap_atomic() is straightforward.
Es ist klar, wann und wo kmap_atomic () verwendet werden soll.
It is used when code wants to access the contents of a page that might be allocated from high memory (see __GFP_HIGHMEM), for example a page in the pagecache.
Dies wird verwendet, wenn der Code auf Seiten zugreift, die durch hohen Speicher reserviert sind (__ GFP_HIGHMEM), z. B. Seiten im Seitencache.
The API has two functions, and they can be used in a manner similar to the following
Die API verfügt über zwei Funktionen, von denen jede wie folgt verwendet wird.
.
/* Find the page of interest. */
struct page *page = find_get_page(mapping, offset);
/* Gain access to the contents of that page. */
void *vaddr = kmap_atomic(page);
/* Do something to the contents of that page. */
memset(vaddr, 0, PAGE_SIZE);
/* Unmap that page. */
kunmap_atomic(vaddr);
Note that the kunmap_atomic() call takes the result of the kmap_atomic() call not the argument.
Beachten Sie, dass kummap_atomic () unabhängig vom Ergebnis des Aufrufs von kmap_atomic () aufgerufen wird.
If you need to map two pages because you want to copy from one page to another you need to keep the kmap_atomic calls strictly nested, like:
Wenn Sie zwei Seiten zuordnen und von einer Seite auf eine andere kopieren möchten, müssen Sie kmap_atomic () mit einer strengen Verschachtelungsstruktur aufrufen. Zum Beispiel
vaddr1 = kmap_atomic(page1);
vaddr2 = kmap_atomic(page2);
memcpy(vaddr1, vaddr2, PAGE_SIZE);
kunmap_atomic(vaddr2);
kunmap_atomic(vaddr1);
Cost of Temporary Mappings
The cost of creating temporary mappings can be quite high.
Die Kosten für die Erstellung eines temporären Mappings können sehr hoch sein.
The arch has to manipulate the kernel’s page tables, the data TLB and/or the MMU’s registers.
Die Architektur erfordert die Arbeit mit der Kernel-Seitentabelle, dem Daten-TLB und / und dem MMU-Register.
.
If CONFIG_HIGHMEM is not set, then the kernel will try and create a mapping simply with a bit of arithmetic that will convert the page struct address into a pointer to the page contents rather than juggling mappings about. In such a case, the unmap operation may be a null operation.
Wenn CONFIG_HIGHMEM nicht festgelegt ist, versucht der Kernel, eine Zuordnung mit einigen arithmetischen Operationen zu erstellen, die die Adresse der Seitenstruktur in einen Zeiger auf den Inhalt der Seite übersetzen, anstatt die Zuordnung zu jonglieren. In solchen Fällen kann die Unmap-Operation eine Nulloperation sein.
.
If CONFIG_MMU is not set, then there can be no temporary mappings and no highmem. In such a case, the arithmetic approach will also be used.
Wenn CONFIG_MMU nicht festgelegt ist, gibt es möglicherweise keine temporäre Zuordnung oder Highmem. Auch in solchen Fällen wird der arithmetische Ansatz verwendet.
.
i386 PAE
The i386 arch, under some circumstances, will permit you to stick up to 64GiB of RAM into your 32-bit machine. This has a number of consequences:
Je nach Situation kann der i386 Architect Tea auch bis zu 64 GB RAM auf einem 32-Bit-Computer installieren. Dies hat viele Auswirkungen.
- Linux needs a page-frame structure for each page in the system and the pageframes need to live in the permanent mapping, which means:
- you can have 896M/sizeof(struct page) page-frames at most; with struct page being 32-bytes that would end up being something in the order of 112G worth of pages; the kernel, however, needs to store more than just page-frames in that memory…
- PAE makes your page tables larger - which slows the system down as more data has to be accessed to traverse in TLB fills and the like. One advantage is that PAE has more PTE bits and can provide advanced features like NX and PAT.
The general recommendation is that you don’t use more than 8GiB on a 32-bit machine - although more might work for you and your workload, you’re pretty much on your own - don’t expect kernel developers to really care much if things come apart.
Eine allgemeine Empfehlung ist, auf einem 32-Bit-Computer nicht mehr als 8 GB zu verwenden. Dies kann sich auf Benutzer und Benutzerlast auswirken. Aber mach es selbst. Wenn etwas schief geht, erwarten Sie nicht, dass sich der Kernel-Entwickler darum kümmert.