3.4. cpuset

Das cpuset-Subsystem weist Kontrollgruppen individuelle CPUs und Speicherknoten zu. Jedes 'cpuset' kann anhand der folgenden Parameter bestimmt werden, wobei sich jeder in einer separaten Pseudodatei innerhalb des virtuellen Dateisystems der Kontrollgruppe befindet:

Wichtig

Einige Controller besitzen Pflichtparameter, die Sie setzen müssen, bevor Sie eine Aufgabe in eine Kontrollgruppe verlegen können, die eine dieser Subsysteme verwendet. Bevor Sie beispielsweise eine Aufgabe in eine Kontrollgruppe verlegen, die das cpuset-Subsystem verwendet, müssen die Parameter cpuset.cpus und cpuset.mems definiert sein.
cpuset.cpus (obligatorisch)
spezifiziert die CPUs, auf die Aufgaben in dieser Kontrollgruppe Zugriff besitzen. Dies ist eine kommagetrennte Liste im ASCII-Format mit Bindestrichen ("-") zur Darstellung von Bereichen. Zum Beispiel:
0-2,16
repräsentiert CPUs 0, 1, 2 und 16.
cpuset.mems (obligatorisch)
spezifiziert die Speicherknoten, auf die Aufgaben in dieser Kontrollgruppe Zugriff besitzen. Dies ist eine kommagetrennte Liste im ASCII-Format mit Bindestrichen ("-") zur Darstellung von Bereichen. Zum Beispiel:
0-2,16
repräsentiert Speicherknoten 0, 1, 2 und 16.
cpuset.memory_migrate
beinhaltet ein Flag (0 oder 1), das festlegt, ob eine Seite im Speicher auf einen neuen Knoten migrieren soll, falls sich die Werte in cpuset.mems ändern. Standardmäßig ist Speicher-Migration deaktiviert (0) und Seiten bleiben auf dem Knoten, dem sie ursprünglich zugewiesen wurden, auch wenn dieser Knoten nicht länger einer der Knoten ist, die aktuell in cpuset.mems definiert sind. Falls aktiviert (1), migriert das System Seiten auf Speicherknoten im Rahmen der durch cpuset.mems definierten neuen Parameter und behält deren relative Platzierung bei, falls möglich. So werden beispielsweise Seiten auf dem zweiten Knoten auf der Liste, der ursprünglich via cpuset.mems definiert wurde, dem zweiten Knoten auf der Liste zugewiesen, jetzt definiert durch cpuset.mems, falls dieser Platz zur Verfügung steht.
cpuset.cpu_exclusive
beinhaltet ein Flag (0 oder 1), das definiert, ob andere 'cpusets' und deren über- und untergeordneten Sets die für diese 'cpuset' definierten CPUs gemeinsam nutzen können. Standardmäßig (0) werden keine CPUs exklusiv nur einem 'cpuset' zugewiesen.
cpuset.mem_exclusive
beinhaltet ein Flag (0 oder 1), das definiert, ob andere 'cpusets' die für diese 'cpuset' definierten Speicherknoten gemeinsam nutzen können. Standardmäßig (0) werden keine Speicherknoten exklusiv nur einem 'cpuset' zugewiesen. Das Reservieren von Speicherknoten für den exklusiven Gebrauch von einem 'cpuset' (1) ist im Endeffekt das gleiche, wie die Aktivierung eines Speicher-Hardwalls mit cpuset.mem_hardwall.
cpuset.mem_hardwall
beinhaltet ein Flag (0 oder 1), das definiert, ob Kernel-Zuweisungen von Speicherseiten und Puffer-Daten auf die Speicherknoten beschränkt werden soll, die für dieses 'cpuset' angegeben wurden. Standardmäßig (0) werden Seiten und Puffer-Daten von Prozessen, die zu mehreren Benutzern gehören, gemeinsam genutzt. Mit einer aktivierten Hardwall (1) kann die Benutzerzuweisung für jede Aufgabe getrennt gehalten werden.
cpuset.memory_pressure
eine schreibgeschützte Datei, die einen laufenden Durchschnittswert des Speicherdrucks enthält, der von Prozessen in diesem 'cpuset' erzeugt wird. Der Wert in dieser Pseudodatei wird automatisch aktualisiert, wenn cpuset.memory_pressure_enabled aktiviert ist. Ansonsten enthält die Pseudodatei den Wert 0.
cpuset.memory_pressure_enabled
beinhaltet ein Flag (0 oder 1), das definiert, ob das System den von Prozessen in dieser Kontrollgruppe generierten Speicherdruck errechnen soll. Errechnete Werte werden in cpuset.memory_pressure ausgegeben und repräsentiert die Rate, mit der Prozesse derzeit verwendeten Speicher freizusetzen versuchen. Diese Rate wird als ganzzahliger Wert der Anzahl der Versuche zur Zurückgewinnung von Speicher pro Sekunde, multipliziert mit 1000, dargestellt.
cpuset.memory_spread_page
beinhaltet ein Flag (0 oder 1), das definiert, ob der Puffer des Dateisystems gleichmäßig auf den für dieses 'cpuset' zugewiesenen Speicherknoten verteilt werden soll. Standardmäßig (0) werden keine Versuche unternommen, Speicherseiten für diesen Puffer gleichmäßig zu verteilen und Puffer werden auf demselben Knoten platziert, auf dem der Prozess läuft, der sie erstellte.
cpuset.memory_spread_slab
beinhaltet ein Flag (0 oder 1), das definiert, ob Kernel-Slab-Caches für Datei-Eingabe/-Ausgabe Operationen gleichmäßig auf dem 'cpuset' verteilt werden sollen. Standardmäßig (0) werden keine Versuche unternommen, um Kernel-Slab-Caches gleichmäßig zu verteilen und Slab-Caches werden auf demselben Knoten platziert, auf dem der Prozess, der sie erstellte, läuft.
cpuset.sched_load_balance
beinhaltet ein Flag (0 oder 1), das definiert, ob der Kernel in diesem 'cpuset' die Lasten zwischen den CPUs verteilt. Standardmäßig (1) verteilt der Kernel Lasten, indem er Prozesse von überlasteten CPUs auf weniger ausgelastete CPUs verlegt.
Beachten Sie jedoch, dass das Setzen dieses Flags in einer Kontrollgruppe keinerlei Auswirkungen hat, wenn die Lastverteilung in einer übergeordneten Kontrollgruppe aktiviert ist, da in diesem Fall die Lastverteilung bereits auf höherer Ebene stattfindet. Um die Lastverteilung in einer Kontrollgruppe zu deaktivieren, müssen Sie demzufolge auch in allen übergeordneten Gruppen in der Hierarchie die Lastverteilung deaktivieren. In diesem Fall sollten Sie berücksichtigen, ob die Lastverteilung für andere Gruppen auf gleicher Ebene (also "Geschwister" der fraglichen Kontrollgruppe) aktiviert sein sollte.
cpuset.sched_relax_domain_level
beinhaltet einen ganzzahligen Wert zwischen -1 und einem kleinen, positiven Wert, welcher die Bandbreite der CPUs darstellt, innerhalb welcher der Kernel versuchen soll, die Last zu verteilen. Dieser Wert ist bedeutungslos, wenn cpuset.sched_load_balance deaktiviert ist.
Der genaue Effekt dieses Wertes variiert abhängig von der Systemarchitektur, doch die folgenden Werte sind typisch:
Die Werte von cpuset.sched_relax_domain_level
WertEffekt
-1System-Standardwert für Lastverteilung verwenden
0Keine unmittelbare Lastverteilung durchführen. Lastverteilung erfolgt nur periodisch
1Umgehend die Last auf Threads auf demselben Kern verteilen
2Umgehend die Last auf Kernen in demselben Paket verteilen
3Umgehend die Last auf CPUs auf demselben Knoten oder Blade verteilen
4Umgehend die Last auf mehreren CPUs auf Architekturen mit Non-Uniform Memory Access (NUMA) verteilen
5Umgehend die Last auf allen CPUs auf Architekturen mit NUMA verteilen