https://dvdhrm.wordpress.com/2014/06/10/memfd_create2/
Teoreticky byste mohli dosáhnout [
memfd_create()
] chování bez zavádění nových systémových volání, jako je toto:
int fd = open("/tmp", O_RDWR | O_TMPFILE | O_EXCL, S_IRWXU);
(Všimněte si, že pro přenosnější zaručení tmpfs zde můžeme použít „/dev/shm
“ namísto „/tmp
“).
Nejdůležitější otázkou proto je, proč sakra potřebujeme třetí cestu?
[…]
- Záložní paměť je účtována procesu, který soubor vlastní, a nepodléhá kvótám pro připojení.
^ Mám pravdu, když si myslím, že na první část této věty se nelze spolehnout?
Kód memfd_create() je doslova implementován jako „nepropojený soubor žijící v [a] tmpfs, který musí být interní v jádře“. Sledování kódu, chápu, že se liší v neimplementaci LSM kontrol, také memfd jsou vytvořeny na podporu „pečetě“, jak dále vysvětluje příspěvek na blogu. Jsem však extrémně skeptický k tomu, že memfd jsou zaúčtovány v principu jinak než tmpfile.
Konkrétně, když zaklepe OOM-killer, nemyslím si, že to bude odpovídat paměti držené memfds. To by mohlo celkem až 50 % RAM – hodnota volby size=pro tmpfs. Jádro nenastavuje jinou hodnotu pro interní tmpfs, takže by použilo výchozí velikost 50 %.
Takže si myslím, že obecně můžeme očekávat, že procesy, které obsahují velké memfd, ale žádné další významné alokace paměti nebudou OOM-zabity. Je to správně?
Přijatá odpověď:
Na základě odpovědi @danblack:
Rozhodnutí je založeno na oom_kill_process()
(trochu vyčištěno):
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)
Což závisí na oom_badness()
najít nejlepšího kandidáta:
child_points = oom_badness(child,
oc->memcg, oc->nodemask, oc->totalpages);
oom_badness()
dělá:
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)
Kde:
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)
Takže to vypadá, že počítá anonymní stránky, což je to, co memfd_create()
použití.