[LINUX] Wann wird die mmap (2) -Datei aktualisiert? (3)

Das letzte Mal beschreibt zwei Arten von Erkennungsmethoden zum Schreiben in den mMap-Bereich und drei Arten im Detail (1a Seitentabellen-Scanmethode, 1b). Es wurde eine physikalische Seitenabtastmethode (2 Schreibfehlererfassungsmethode) vorhergesagt. Letztes Mal hat sich tatsächlich den Quellcode von Linux und NetBSD angesehen und bestätigt, dass beide die Methode zur Erfassung von Schreibfehlern übernommen haben. In diesem Artikel werden zwei weitere Betriebssysteme vorgestellt, macOS und Solaris.

Für macOS

macOS wurde basierend auf NeXTSTEP (OpenSTEP) entwickelt, das auf Mach 2.5, dem Mikrokernel der CMU, basiert. Im Mikrokernel sind nur die minimal erforderlichen Funktionen im Kernel implementiert, und Funktionen wie Netzwerkstapel, Dateisystem und Prozessverwaltung sind auf einem Server (Subsystem) implementiert, der im Benutzerbereich ausgeführt wird. Ein reiner Mikrokernel hat jedoch häufig Leistungsprobleme aufgrund der hohen Häufigkeit der Umschaltung des virtuellen Raums und der Kontextumschaltung, und Subsystemfunktionen werden häufig im Kernelraum implementiert. Dies wird als Hybridkernel bezeichnet (Windows wird auch als Hybridkernel klassifiziert). Mach enthält eine große Menge an Code, der von 4.3BSD abgeleitet wurde, um die Kompatibilität mit 4.3BSD zu gewährleisten, was zu diesem Zeitpunkt der Standard war, und es ist eine einzelne Binärdatei, die im selben Adressraum wie der Mikrokernel-Teil ausgeführt wird. War dort. Das heißt, es wird als Hybridkern klassifiziert. Für macOS wurde der NeXT STEP-Kernel Mach 2.5 + 4.3BSD auf den Mikrokernel + FreeBSD von OSF / 1 aktualisiert. Scheint zu sein. Die Überreste von OSF / 1 erscheinen im Verzeichnisnamen osfmk, in dem der Mach-Teil des Quellbaums gespeichert ist. Die Unix-Befehle usw. scheinen ebenfalls auf FreeBSD zu basieren.

Das gesamte macOS ist kein OSS, aber die von Mach / FreeBSD abgeleiteten Teile einschließlich des Kernels (XNU) sind OSS unter dem Namen Darwin. Es gibt einen [Spiegel] auf Github (https://github.com/apple/darwin-xnu/), daher werde ich darauf verweisen, aber da das Dateisystem (APFS, HFS +) nicht enthalten ist, besteht ein Gefühl von Juckreiz.

Ich erwähnte, dass das frühere virtuelle Speichersystem von NetBSD Mach-basiert war. UVM wurde ebenfalls unter dem Einfluss des virtuellen Mach-Speichersystems von Mach entwickelt und weist viele Ähnlichkeiten mit dem virtuellen XNU-Speichersystem auf. Beispielsweise wird das D-Bit wie netBSD von pmap_is_modified () referenziert, und pmap_clear_modify () funktioniert genauso wie NetBSD. Es gibt auch Schnittstellen wie pmap_get_refmod () und pmap_clear_refmod (), die A-Bit und D-Bit gleichzeitig arbeiten. Das gleichzeitige Bearbeiten von A-Bit und D-Bit bedeutet, dass im Gegensatz zu Linux und NetBSD durch Scannen der Seitentabelle nach schmutzigen Seiten gesucht wird. Lass uns einen Blick darauf werfen.

Seitentabelle scannen

Das virtuelle Speichersystem von XNU scheint sich in einem Verzeichnis namens [osfmk / vm] zu befinden (https://github.com/apple/darwin-xnu/tree/xnu-4903.221.2/osfmk/vm). Der Mach-Teil wird in einem Verzeichnis namens osfmk und der BSD-Subsystemteil in einem Verzeichnis namens bsd Bsd / vm gespeichert Es gibt auch ein Verzeichnis namens). bsd / vm implementiert Teile, die vom BSD-Subsystem abhängen, z. B. den vnode-Pager (entspricht dem NetBSD-vnode-Pager).

In der Datenstruktur von osfmk / vm gibt es Strukturen wie struct vm_map, struct vm_map_entry, struct vm_page usw., wie in NetBSD dargestellt, und vm_page ist über listq, pageq usw. mit der Liste verbunden. Lass mich das riechen.

Wenn Sie mit pmap_is_modified, pmap_clear_modify, pmap_get_refmod, pmap_clear_refmod usw. arbeiten, vm_pageout.c Es scheint hier zu sein, weil es in der Nähe von .c gefangen wird. Es ist jedoch ziemlich schwer zu verstehen, da es unglaublich lange Blöcke gibt und die Anzahl der Zustände (Flag der Struktur vm_page) groß ist.

Es scheint eine der Eigenschaften zu sein, dass viele Warteschlangen (Listen) über pageq verbunden sind. Grundsätzlich scheint es Seiten zu verschieben und die Reihenfolge zwischen aktiven / inaktiven / freien Listen zu ändern, aber jede Liste ist in mehrere Teile unterteilt.

Wenn Sie es auf diese Weise in viele Listen unterteilen, können Sie den Zeitpunkt und die Häufigkeit der Scans je nach Nutzungsstatus der Seite genau steuern.

Das Scannen jeder Liste von Aktiv / Inaktiv ist Kontext nach Kernel-Initialisierung Es scheint, dass es so gemacht wird, wie es ist. Der Hauptteil ist eine lange Funktion mit fast 1500 Zeilen namens vm_pageout_scan (). Gibt es. In diesem (zum Beispiel [hier]](https://github.com/apple/darwin-xnu/blob/xnu-4903.221.2/osfmk/vm/vm_pageout.c#L2883)) sowohl A-Bit als auch D-Bit Wenn das D-Bit gesetzt ist, ist die Seite gleichzeitig verschmutzt.

		if (m->vmp_reference == FALSE && m->vmp_pmapped == TRUE) {
		        refmod_state = pmap_get_refmod(VM_PAGE_GET_PHYS_PAGE(m));

		        if (refmod_state & VM_MEM_REFERENCED)
			        m->vmp_reference = TRUE;
		        if (refmod_state & VM_MEM_MODIFIED) {
				SET_PAGE_DIRTY(m, FALSE);
			}
		}

Sie können vm_fault () auch grob verfolgen, um Seitenfehler zu behandeln. Es scheint, dass zum Zeitpunkt des Schreibfehlers nur ein Fehler (SEGV usw.) oder eine Kopie beim Schreiben vorliegt.

Aus dem oben Gesagten wurde herausgefunden, dass macOS anscheinend eine physische Seitenscan-Methode verwendet, die Verschmutzungen erkennt, indem das D-Bit gleichzeitig mit der Prüfung des A-Bits in der Seitentabelle überprüft wird.

Für OpenIndiana

Apropos SunOS (Solaris: Genau genommen scheint der Umfang von SunOS und Solaris unterschiedlich zu sein, aber die Details interessieren mich nicht), für eine Weile war es The Unix, und es war ein Betriebssystem, das weiterhin alle Unix-basierten Betriebssysteme beeinflusste. .. Ich denke, Linux strebte SunOS bis etwa 2.6 an. Auch in diesem Bereich hat SunOS 4 als erstes den für mMap (2) verwendeten Seitencache und den für Lesen (2) / Schreiben (2) verwendeten Puffercache integriert.

Das SunOS hat den Quellcode einmal als OpenSolaris um 5.10 (Solaris 10) veröffentlicht. Die Lizenz war CDDL, und obwohl sie nicht mit GPL kompatibel war, war es OSS. Zu dieser Zeit basierte das Produkt Solaris ebenfalls auf OpenSolaris, aber als Sun von Oracle übernommen wurde, endete das Open (Solar) -basierte OpenSolaris-Projekt.

OpenIndiana, das von der letzten Version von OpenSolaris abgeleitet ist, befindet sich noch in der Entwicklung, daher möchte ich dies untersuchen. Von dem Teil illumos-gate, der den Kernel enthält, die neueste Version OpenIndiana Hipster 2020.04 Siehe commit entsprechend / openindiana-hipster-2020-04-is-here /). Der Kernel befindet sich unter usr / src / uts. Unix Time-Sharing-System. Der x86-abhängige Teil ist uts / i86pc und der architekturunabhängige Teil ist [uts / common]. //github.com/illumos/illumos-gate/tree/45de8795bcb0e4c49743f37edfdd2c89d5a7863b/usr/src/uts/common)

Seitentabelle scannen

Von den virtuellen Speichersystemen scheint der modellabhängige Teil das HAT-Management (Hardware Address Translation) zu sein. Für x86 gehen Sie zu uts / i86pc / vm / hat_i86.c Gibt es. Es ist pmap sehr ähnlich, z. B. hat_t (struct hat), das jedem virtuellen Raum entspricht. Lesen Sie diagonal mit PT_MOD als Bit P, das einem P-Bit entspricht. Dann können wir Folgendes sehen.

hat_pagesync () verwendet eine Strukturseite (entsprechend einer physischen Seite: daher mehrere PTEs) und ein Bitmap-Flag als Argumente und ein Bit, D-Bit, R / W-Bit eines PTE, das sich auf eine physische Seite bezieht. Wird in p_nrm der Strukturseite wiedergegeben. Als Flagge

Nimm eine Bitmap von. Ich bin nicht sicher, was HAT_SYNC_STOP_ON_SHARED bedeutet, aber ich denke, dass Seiten, die von vielen virtuellen Räumen gemeinsam genutzt werden, bevorzugt behandelt werden.

/*
 * get hw stats from hardware into page struct and reset hw stats
 * returns attributes of page
 * Flags for hat_pagesync, hat_getstat, hat_sync
 *
 * define	HAT_SYNC_ZERORM		0x01
 *
 * Additional flags for hat_pagesync
 *
 * define	HAT_SYNC_STOPON_REF	0x02
 * define	HAT_SYNC_STOPON_MOD	0x04
 * define	HAT_SYNC_STOPON_RM	0x06
 * define	HAT_SYNC_STOPON_SHARED	0x08
 */

Schauen Sie sich vor diesem Hintergrund den Code an, der die Seitentabelle durchsucht. Der modellunabhängige Teil des virtuellen Speichersystems befindet sich in uts / common / vm. Der Code zum Scannen der Seitentabelle befindet sich irgendwie in uts / common / os Gibt es. Oh, aus irgendeinem Grund hat es den gleichen Dateinamen wie macOS. Eigentlich auch unter FreeBSD [auch unter NetBSD] vor der UVM-Konvertierung (http: //cvsweb.netbsd) .org / bsdweb.cgi / src / sys / vm / Attic / vm_pageout.c), so dass dies der Fall sein könnte (beachten Sie, dass macOS, FreeBSD und NetBSDs vm_pageout.c eindeutig verwurzelt sind).

OpenIndiana oder Solaris-Quelle hat viele Kommentare und ist leicht zu lesen. Der Seitenersatz ist pageout_scanner (). Es läuft im Kernel-Thread von. Es scheint den Clock-Algorithmus zu implementieren, aber im Gegensatz zu anderen Betriebssystemen, die ich bisher gesehen habe, hat es keine inaktive Liste, es scheint eine einzelne Liste zu verwenden. Der Zeiger bedeutet die Zeiger einer Uhr, und es fühlt sich an, als würden die beiden Zeiger, der vordere und der hintere Zeiger, in regelmäßigen Abständen der Liste der physischen Seiten (Strukturseiten) folgen (Handspread-Seiten).

checkpage () scheint der Punkt zu sein. Grundsätzlich fronthand [löscht D-Bit, A-Bit](https://github.com/illumos//illumos-gate/blob/45de8795bcb0e4c49743f37edfdd2c89d5a7863b/usr/src/uts/common/os/vm_pageout.c # L1010), gehen Sie nach Rückhandprüfungen ein wenig L1012) Es sieht so aus.

	/*
	 * Turn off REF and MOD bits with the front hand.
	 * The back hand examines the REF bit and always considers
	 * SHARED pages as referenced.
	 */
	if (whichhand == FRONT)
		pagesync_flag = HAT_SYNC_ZERORM;
	else
 		pagesync_flag = HAT_SYNC_DONTZERO | HAT_SYNC_STOPON_REF |
		    HAT_SYNC_STOPON_SHARED;

	ppattr = hat_pagesync(pp, pagesync_flag);

Und wenn ein Bit gesetzt ist Was Gehen Sie zurück und wenn das D-Bit gesetzt ist , Queue_io_request () [call](htt] //github.com/illumos//illumos-gate/blob/45de8795bcb0e4c49743f37edfdd2c89d5a7863b/usr/src/uts/common/os/vm_pageout.c#L1088), Export anfordern. Wenn beides nicht festgelegt ist, Seite zuordnen ) Öffnen.

Aus dem Obigen ist ersichtlich, dass OpenIndiana oder Solaris zu einem bestimmten Zeitpunkt eine physische Seiten-Scan-Methode verwendet.

Für 4.4BSD

Bisher habe ich festgestellt, dass NetBSD und macOS, die dieselben Wurzeln zu haben scheinen, unterschiedliche Methoden haben und dass Solaris, das bis zu einer bestimmten Zeit die Norm war, und Linux und NetBSD unterschiedlich sind. Wann habe ich die Methode geändert? Bist du gekommen, um es zu nehmen, oder hat dich die Geschichte interessiert?

Wenn Sie Unix schon lange verwenden, können Sie sich daran erinnern, dass es früher einen Daemon namens update (8) gab, der alle 30 Sekunden einen Systemaufruf namens sync (2) ausgab. Das Schreiben durch Schreiben (2) usw. wurde nicht automatisch vom Kernel geschrieben, und ich musste fsync (2) usw. ausgeben oder auf das Update (8) warten, um nach bis zu 30 Sekunden zu schreiben. Vielleicht war die mmap (2) -Datei dieselbe.

Beispielsweise kann der Quellcode für 4.4BSD, einen gemeinsamen Vorfahren von NetBSD und macOS (macOS ist einer der Vorfahren), im Web angezeigt werden (https://minnie.tuhs.org/cgi-bin/utree). .pl? file = 4.4BSD / usr / src). vm_pageout.c, das viele aktive / inaktive Listen unter macOS gescannt hat, ist unter 4.4BSD (https://minnie.tuhs.org/cgi-bin/utree.pl?file=4.4BSD) [so einfach] /usr/src/sys/vm/vm_pageout.c). Ich habe das D-Bit hier nicht gesehen. Außerdem ist Seitenfehlercode eine Kopie für einen Schreibfehler. -Nur schreiben auf schreiben. Im Gegenteil, es wird hier definiert (https://minnie.tuhs.org/cgi-bin/utree.pl?file=4.4BSD/usr/src/sys/kern/vfs_syscalls.c) sync (2) Daher wird nur der Puffercache geleert (obwohl der Seitencache und der Puffercache zu diesem Zeitpunkt nicht integriert waren), und der von mMap verwendete Seitencache bleibt unberührt.

Es scheint, dass der Seitencache nur geleert wird, wenn msync (2) ausgegeben wird und wenn munmap (2) oder der Prozess beendet wird. Im Fall von NetBSD begann Sync (2), den Seitencache zu leeren seit Februar 1997. Es ist.

Danach jage ich nur noch danach, aber wenn die Mach-VM gelöscht wird [wenn UVM eingeführt wird](https: / /github.com/NetBSD/src/commit/8f7ee94e136f377ecd00e43bc146adecc505c8ea) sieht genauso aus. Anscheinend wenn der Puffercache und der Seitencache integriert sind Es scheint, dass der Schreibfehler abgefangen wurde.

FreeBSD hat seine Vorgeschichte vor 2.0-RELEASE aufgrund rechtlicher Probleme verloren. Es scheint, dass 2.0 den Schreibfehler bereits erkannt und verschmutzt hat, sodass es nicht einfach ist zu wissen, wann dies auch die aktuelle Methode war. Da Linux auch VCS geändert hat, ist es ziemlich mühsam, den Verlauf vor 2.6.12 zu verfolgen. In 2.4.20 hatte ich Code, der es während eines Schreibfehlers schmutzig machte.

Zusammenfassung

Im Gegensatz zu NetBSD ist macOS, das allgemein als BSD bezeichnet wird, eine physische Seitenscanmethode, und Solaris, das einst der Standard für verschiedene Unix-Betriebssysteme war, ist auch eine physische Seitenscanmethode. In der Vergangenheit leert mindestens 4.4BSD den Seitencache nicht automatisch, was sich zwischen macOS mit 4.3BSD (und beiden FreeBSD) als Vorfahr und NetBSD mit 4,4BSD unterscheidet. Aber kein Wunder.

Recommended Posts

Wann wird die mmap (2) -Datei aktualisiert? (3)
Wann wird die mmap (2) -Datei aktualisiert? (2)
Wann wird die mmap (2) -Datei aktualisiert? (1)
Sagen Sie voraus, wann die ISS sichtbar sein wird
"Temporäre Lösung", wenn pip nicht aktualisiert werden kann [Python]
Seien Sie vorsichtig, wenn Sie mit gzip-komprimierten Textdateien arbeiten
[Python] Wann werden Variablen erstellt? Wann werden Klasseninstanzen gelöscht?
Reverse Pull Numpy / Pandas (wird jederzeit aktualisiert)
Wenn USB nicht formatiert werden konnte
Wenn pydub nicht installiert werden kann