Có sai không khi nghĩ về mem memddd của s như là hạch toán với quy trình sở hữu tập tin giỏi?


15

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

Về mặt lý thuyết, bạn có thể đạt được memfd_create()hành vi [ ] mà không cần giới thiệu các tòa nhà mới, như thế này:

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

(Lưu ý, để đảm bảo một cách hợp lý hơn một tmpfs ở đây, chúng ta có thể sử dụng " /dev/shm" thay vì " /tmp").

Do đó, câu hỏi quan trọng nhất là tại sao chúng ta cần một cách thứ ba?

[...]

  • Bộ nhớ sao lưu được tính vào quá trình sở hữu tệp và không phải chịu hạn ngạch gắn kết.

^ Tôi có đúng khi nghĩ phần đầu của câu này không thể dựa vào không?

memfd_create () được triển khai theo nghĩa đen là " tệp không được liên kết sống trong [a] tmpfs phải là kernel bên trong ". Theo dõi mã, tôi hiểu nó khác nhau khi không thực hiện kiểm tra LSM, cũng có các memfds được tạo để hỗ trợ "con dấu", khi bài đăng trên blog tiếp tục giải thích. Tuy nhiên, tôi cực kỳ nghi ngờ rằng các memfds được hạch toán khác với một tmpfile về nguyên tắc.

Cụ thể, khi kẻ giết người OOM đến gõ cửa, tôi không nghĩ rằng nó sẽ chiếm bộ nhớ do các memfds nắm giữ. Điều này có thể tổng cộng lên tới 50% RAM - giá trị của tùy chọn size = cho tmpfs . Hạt nhân không đặt giá trị khác cho các tmpfs nội bộ, do đó, nó sẽ sử dụng kích thước mặc định là 50%.

Vì vậy, tôi nghĩ rằng chúng ta thường có thể mong đợi các quy trình chứa một memfd lớn, nhưng không có phân bổ bộ nhớ quan trọng nào khác, sẽ không bị OOM giết. Đúng không?


2
Theo như điểm số của OOM , nó dường như đi xuống hàm oom_badness của kernel . Vì vậy, tôi nghi ngờ nếu memfd_create không hiển thị trong / Proc / {pid} / map thì nó không được tính. Vì vậy, câu trả lời chung là họ có thể bị giết, nhưng họ sẽ không có số điểm lớn vì sử dụng memfd_create. Bộ nhớ cho fd có thể được chia sẻ trên các quy trình vì nhiều quá trình có thể kế thừa / được gửi, cùng một fd.
danblack

Câu trả lời:


1

Dựa trên câu trả lời của @ danblack:

Quyết định dựa trên oom_kill_process()(làm sạch một chút):

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 )

Mà phụ thuộc vào oom_badness()để tìm ứng cử viên tốt nhất:

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

oom_badness() làm:

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 )

Ở đâu:

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 )

Vì vậy, có vẻ như nó đếm các trang ẩn danh, đó là những gì memfd_create()sử dụng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.