GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Linux – Ist es falsch, „memfds“ als „dem Prozess, dem die Datei gehört“ zuzuordnen?

https://dvdhrm.wordpress.com/2014/06/10/memfd_create2/

Theoretisch könnten Sie [memfd_create() erreichen ]-Verhalten, ohne neue Systemaufrufe einzuführen, etwa so:

int fd = open("/tmp", O_RDWR | O_TMPFILE | O_EXCL, S_IRWXU);

(Beachten Sie, um hier einen tmpfs portierbarer zu garantieren, können wir „/dev/shm verwenden “ statt „/tmp “).

Daher ist die wichtigste Frage, warum zum Teufel brauchen wir einen dritten Weg?

[…]

  • Der Hintergrundspeicher wird dem Prozess zugerechnet, der die Datei besitzt, und unterliegt keinen Einhängequoten.

^ Gehe ich recht in der Annahme, dass auf den ersten Teil dieses Satzes kein Verlass ist?

Der Code memfd_create() ist buchstäblich als „nicht verknüpfte Datei, die in [einem] tmpfs lebt, das Kernel-intern sein muss“ implementiert. Wenn ich den Code nachverfolge, verstehe ich, dass er sich dadurch unterscheidet, dass keine LSM-Prüfungen implementiert werden, außerdem werden memfds erstellt, um „Siegel“ zu unterstützen, wie der Blog-Beitrag weiter erklärt. Ich bin jedoch äußerst skeptisch, dass memfds angerechnet werden prinzipiell anders als eine tmpfile.

Insbesondere wenn der OOM-Killer anklopft, glaube ich nicht, dass er den Speicher von memfds berücksichtigen wird. Dies kann bis zu 50 % des Arbeitsspeichers ausmachen – der Wert der Option size=für tmpfs. Der Kernel setzt keinen anderen Wert für das interne tmpfs, also würde er die Standardgröße von 50 % verwenden.

Ich denke also, dass wir im Allgemeinen erwarten können, dass Prozesse, die einen großen memfd, aber keine anderen signifikanten Speicherzuweisungen enthalten, nicht durch OOM getötet werden. Ist das richtig?

Akzeptierte Antwort:

Aufbauend auf der Antwort von @danblack:

Die Entscheidung basiert auf oom_kill_process() (etwas aufgeräumt):

for_each_thread(p, t) {
        list_for_each_entry(child, &t->children, sibling) {
                unsigned int child_points;

                child_points = oom_badness(child,
                        oc->memcg, oc->nodemask, oc->totalpages);
                if (child_points > victim_points) {
                        put_task_struct(victim);
                        victim = child;
                        victim_points = child_points;
                        get_task_struct(victim);
                }
        }
}

(https://github.com/torvalds/linux/blob/master/mm/oom_kill.c#L974)

Was von oom_badness() abhängt um den besten Kandidaten zu finden:

child_points = oom_badness(child,
        oc->memcg, oc->nodemask, oc->totalpages);

oom_badness() tut:

points = get_mm_rss(p->mm) + get_mm_counter(p->mm, MM_SWAPENTS) +
        mm_pgtables_bytes(p->mm) / PAGE_SIZE;

(https://github.com/torvalds/linux/blob/master/mm/oom_kill.c#L233)

Wo:

static inline unsigned long get_mm_rss(struct mm_struct *mm)
{
        return get_mm_counter(mm, MM_FILEPAGES) +
                get_mm_counter(mm, MM_ANONPAGES) +
                get_mm_counter(mm, MM_SHMEMPAGES);
}

(https://github.com/torvalds/linux/blob/master/mm/oom_kill.c#L966)

Es sieht also so aus, als würden anonyme Seiten gezählt, was memfd_create() ist verwendet.


Linux
  1. Finden Sie die Ausführungszeit eines Befehls oder Prozesses in Linux

  2. Was ist die aktuelle Linux-Kernelquelle?

  3. Den Prozess finden, der einen bestimmten Port in Linux verwendet

  4. Was ist die Definition einer Sitzung unter Linux?

  5. Gibt es eine Linux-Distribution oder einen Kernel-Patch, der einen Prozessspeicherplatz löscht, nachdem der Prozess beendet wurde?

So ändern Sie die Priorität eines Prozesses in Linux

So beenden oder beenden Sie einen Linux-Prozess:Der ultimative Leitfaden

Die 10 Unix-basierten Betriebssysteme, die nicht Linux sind

So finden Sie die PID und PPID eines Prozesses in Linux

So senden Sie Prozesse unter Linux an den Hintergrund

Was ist die Linux-Prozesstabelle? Woraus besteht es?