Est-il faux de penser que les «memfd» sont comptabilisés «dans le processus propriétaire du fichier»?

15

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

Théoriquement, vous pouvez obtenir un memfd_create()comportement [ ] sans introduire de nouveaux appels système, comme ceci:

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

(Remarque, pour garantir une portabilité plus tmpfs ici, nous pouvons utiliser " /dev/shm" au lieu de " /tmp").

Par conséquent, la question la plus importante est pourquoi diable avons-nous besoin d'une troisième voie?

[...]

  • La mémoire de sauvegarde est prise en compte dans le processus propriétaire du fichier et n'est pas soumise à des quotas de montage.

^ Ai-je raison de penser que la première partie de cette phrase ne peut pas être invoquée?

Le code memfd_create () est littéralement implémenté comme un " fichier non lié vivant dans [a] tmpfs qui doit être interne au noyau ". En traçant le code, je comprends qu'il diffère en ne mettant pas en œuvre les vérifications LSM, également des memfds sont créés pour prendre en charge les «sceaux», comme l'explique le blog. Cependant, je suis extrêmement sceptique quant au fait que les memfds sont comptabilisés différemment d'un fichier tmp en principe.

Plus précisément, lorsque le tueur OOM vient frapper, je ne pense pas qu'il rendra compte de la mémoire détenue par memfds. Cela pourrait totaliser jusqu'à 50% de RAM - la valeur de l' option size = pour tmpfs . Le noyau ne définit pas de valeur différente pour les tmpfs internes, il utiliserait donc la taille par défaut de 50%.

Je pense donc que nous pouvons généralement nous attendre à ce que les processus qui contiennent un grand memfd, mais aucune autre allocation de mémoire significative, ne soient tués par MOO. Est-ce exact?

sourcejedi
la source
2
En ce qui concerne les scores OOM, cela semble se résumer à la fonction noyau oom_badness . Donc je soupçonne que si memfd_create n'apparaît pas dans une carte / proc / {pid} / alors ce n'est pas compté. Donc, la réponse générale est qu'ils pourraient être tués, mais ils n'auront pas un score élevé en raison de l'utilisation de memfd_create. La mémoire du fd peut être partagée entre plusieurs processus car plusieurs processus peuvent hériter / être envoyés, le même fd.
danblack

Réponses:

1

S'appuyant sur la réponse de @ danblack:

La décision est basée sur oom_kill_process()(nettoyé un peu):

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 )

Cela dépend oom_badness()de trouver le meilleur candidat:

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

oom_badness() Est-ce que:

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 )

Où:

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 )

Il semble donc qu'il compte les pages anonymes, ce qui est memfd_create()utilisé.

V13
la source