Что заставляет ядро потреблять процессор при page_fault?

#linux #linux-kernel #mmap #perf #page-fault

#linux #linux-ядро #mmap #perf #ошибка страницы

Вопрос:

hw / os: linux 4.9, 64 ГБ оперативной памяти.

запущено 16 демонов. Каждое чтение случайных коротких (100 байт) фрагментов файла размером 5 ГБ обращается к нему как к памяти, отображаемой через mmap () при запуске демона. Каждый демон читает свой собственный файл, всего 16 файлов размером 5 ГБ.

Каждый демон выполняет, возможно, 10 операций чтения в секунду. Не слишком много, нагрузка на диск довольно мала.

Иногда (1 событие за 5 минут, без периода, полностью случайное) какой-то случайный демон застрял в коде ядра со стеком followind (см. Рисунок) на 300 миллисекунд. Это не соответствует основным ошибкам: основные ошибки происходят с постоянной скоростью около 100 … 200 в секунду. Чтения с диска также постоянны.

Что может вызвать это?

стек получен с записью perf

Текст изображения: __list_del_entry isolate_lru_pages.isra.48 shrink_inactive_list shrink_node_memcg shrink_node node_reclaim get_page_from_freelist enqueue_task_fair sched_clock __alloc_pages_nodemask alloc_pages_vma handle_mm_fault __do_page_fault page_fault

Комментарии:

1. Итак, вы уверены, что это была одна ошибка программной страницы, которая остается в ядре в течение 300 мс? Можете ли вы сказать, становится ли свободный список фрагментированным или что-то в этом роде? Я не думаю, что прозрачные огромные страницы актуальны для mmap с файловой поддержкой, поэтому, вероятно, ваши /sys/kernel/mm/transparent_hugepage/defrag настройки не должны иметь значения, если только они не выбирают этот момент для дефрагментации анонимных страниц для другого процесса? Или, если это ошибка на анонимной странице, отделите ее от используемых вами сопоставлений с поддержкой файлов.

2. @PeterCordes «ошибка soft page» — не знаю, что такое «ошибка soft page». Я не знаю, с какой ошибкой страницы я имею дело. «если свободный список становится огромным фрагментированным» — я не знаю, как это выяснить. «/sys/kernel/mm/transparent_hugepage /defrag» — спасибо вам за это. Я не знаю, как найти ответ на большинство ваших вопросов.

3. @PeterCordes я думаю madvise(MADV_RANDOM) , что решил проблему.

4. Ах, ядро пыталось выполнить предварительную ошибку / readahead с диска, задерживая обработку ошибки для фактической страницы, к которой вы прикасались? Re: ошибка программной страницы, см. en.wikipedia.org/wiki/Page_fault#Minor в отличие от основного / жесткого (требуется ввод-вывод) или недопустимого (ошибка сегмента).

5. @PeterCordes кажется, однажды мое решение сработало. После перезапуска приложения все вернулось к плохому поведению

Ответ №1:

В вашем стеке есть функции shrink_node и node_reclaim . Они вызываются для освобождения памяти (которая отображается как buff / cache с помощью free инструмента командной строки): https://www.kernel.org/doc/html/latest/admin-guide/mm/concepts.html#reclaim

Процесс освобождения восстанавливаемых страниц физической памяти и их повторного использования называется (сюрприз!) восстановление. Linux может восстанавливать страницы либо асинхронно, либо синхронно, в зависимости от состояния системы. Когда система не загружена, большая часть памяти свободна, и запросы на выделение будут немедленно удовлетворены из источника свободных страниц. По мере увеличения нагрузки количество свободных страниц уменьшается, и когда оно достигает определенного порога (высокий водяной знак), запрос на выделение пробудит демона kswapd. Он будет асинхронно сканировать страницы памяти и либо просто освобождать их, если содержащиеся в них данные доступны в другом месте, либо удалять на резервное запоминающее устройство (помните эти грязные страницы?). Поскольку использование памяти увеличивается еще больше и достигает другого порога — минимальный водяной знак — выделение вызовет прямое восстановление. В этом случае выделение останавливается до тех пор, пока не будет освобождено достаточно страниц памяти для удовлетворения запроса.

Итак, в вашей системе 64 ГБ ОЗУ возникает ситуация, когда свободной памяти не осталось. Этого объема памяти достаточно для хранения копии 12 файлов по 5 ГБ каждый, а ваши демоны используют 16 файлов. Linux может считывать из файлов больше данных, чем требовалось приложению с помощью метода Readahead («Linux readahead: меньше трюков для большего», ols 2007 pp273-284, man 2 readahead). MADV_SEQUENTIAL также может включить этот механизм, https://man7.org/linux/man-pages/man2/madvise .2.html

    MADV_SEQUENTIAL
  

Ожидайте ссылки на страницы в последовательном порядке. (Следовательно, страницы в
данном диапазоне могут быть агрессивно прочитаны вперед и могут быть
освобождены вскоре после доступа к ним.)

   MADV_RANDOM
  

Ожидайте ссылки на страницы в случайном порядке. (Следовательно, чтение вперед
может быть менее полезным, чем обычно.)

Не уверен, как ваши демоны открывали и читали файлы, был ли MADV_SEQUENTIAL активен для них или нет (или этот флаг был добавлен glibc или любой другой библиотекой). Также может быть некоторый эффект от THP — передачи огромных страниц https://www.kernel.org/doc/html/latest/admin-guide/mm/transhuge.html . Обычное ядро 4.9 выпущено в 2016 году, а расширение thp для файловых систем было запланировано на 2019 год https://lwn.net/Articles/789159 /, но если вы используете RHEL/ CentOS, некоторые функции могут быть перенесены в форк ядра 4.9.

Вы должны периодически проверять free и cat /proc/meminfo выводить, чтобы проверить, как ваши демоны и ядро Linux readahead используют память.

Комментарии:

1. Без или MADV_SEQUENTIAL или MADV_RANDOM ядро выполнит некоторое чтение вперед, только менее агрессивно, чем с MADV_SEQUENTIAL . Таким образом, дополнительное загрязнение от readahead можно объяснить, не MADV_SEQUENTIAL будучи «включенным по умолчанию» или чем-то еще.