ผิดหรือเปล่าที่คิดว่า“ memfd” เป็น“ กระบวนการที่เป็นเจ้าของไฟล์”


15

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

ในทางทฤษฎีคุณสามารถบรรลุ [ memfd_create()] พฤติกรรมโดยไม่ต้องแนะนำ syscalls ใหม่เช่นนี้

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

(หมายเหตุเพื่อรับประกัน tmpfs มากขึ้นที่นี่เราสามารถใช้ " /dev/shm" แทน " /tmp")

ดังนั้นคำถามที่สำคัญที่สุดคือทำไมเราถึงต้องการวิธีที่สาม?

[ ... ]

  • หน่วยความจำสำรองจะถูกประมวลผลโดยกระบวนการที่เป็นเจ้าของไฟล์และไม่อยู่ภายใต้การเมาต์โควต้า

ฉันคิดถูกแล้วว่าส่วนแรกของประโยคนี้ไม่สามารถพึ่งพาได้

รหัสmemfd_create () มีการใช้งานอย่างแท้จริงว่าเป็น " ไฟล์ที่ไม่เชื่อมโยงอยู่ใน [a] tmpfs ซึ่งต้องเป็นเคอร์เนลภายใน " การติดตามรหัสฉันเข้าใจว่ามันไม่ได้มีการใช้การตรวจสอบ LSM แตกต่างกันนอกจากนี้ memfds ยังถูกสร้างขึ้นเพื่อรองรับ "แมวน้ำ" เนื่องจากโพสต์บล็อกอธิบายต่อไป อย่างไรก็ตามฉันสงสัยอย่างมากว่า memfds มีสัดส่วนแตกต่างจาก tmpfile ในหลักการ

โดยเฉพาะอย่างยิ่งเมื่อOOM-killer เข้ามากระแทกฉันไม่คิดว่ามันจะคำนึงถึงหน่วยความจำที่ memfds จัด ซึ่งอาจรวมถึง 50% ของแรม - ค่าของsize = ตัวเลือกสำหรับการ tmpfs เคอร์เนลไม่ได้ตั้งค่าที่แตกต่างกันสำหรับ tmpfs ภายในดังนั้นมันจะใช้ขนาดเริ่มต้น 50%

ดังนั้นฉันคิดว่าโดยทั่วไปเราสามารถคาดหวังได้ว่ากระบวนการที่มีหน่วยความจำขนาดใหญ่ แต่ไม่มีการจัดสรรหน่วยความจำที่สำคัญอื่น ๆ จะไม่ถูก OOM ถูกต้องหรือไม่


2
เท่าที่คะแนน OOM ไปมันดูเหมือนว่าจะมาลงไปที่ฟังก์ชั่นเคอร์เนล oom_badness ดังนั้นฉันจึงสงสัยว่า memfd_create จะไม่ปรากฏใน / proc / {pid} / map จากนั้นจะไม่ถูกนับ ดังนั้นคำตอบทั่วไปคือพวกเขาอาจถูกฆ่า แต่พวกเขาจะไม่ได้คะแนนมากเพราะการใช้ memfd_create หน่วยความจำสำหรับ fd สามารถแชร์ข้ามโปรเซสได้หลายโพรเซสสามารถรับ / ส่งเป็น fd เดียวกัน
danblack

คำตอบ:


1

สร้างคำตอบของ @ danblack:

การตัดสินใจขึ้นอยู่กับoom_kill_process()(ทำความสะอาดเล็กน้อย):

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 )

ซึ่งขึ้นอยู่กับoom_badness()การหาผู้สมัครที่ดีที่สุด:

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

oom_badness() ทำ:

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 )

ที่ไหน:

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 )

ดังนั้นจึงดูเหมือนว่าจะนับหน้าเว็บที่ไม่ระบุชื่อซึ่งเป็นสิ่งที่memfd_create()ใช้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.