Компания
302,06
рейтинг
2 августа 2014 в 17:04

Разное → Memory management в ядре Linux. Семинар в Яндексе

Привет! Меня зовут Роман Гущин. В Яндексе я занимаюсь ядром Linux. Некторое время назад я провел для системных администраторов семинар, посвященный общему описанию подсистемы управления памятью в Linux, а также некоторым проблемам, с которыми мы сталкивались, и методам их решения. Большая часть информации описывает «ванильное» ядро Linux (3.10), но некоторая часть специфична для ядра, использующегося в Яндексе. Вполне возможно, семинар окажется интересен не только системным администраторам, но и всем, кто хочет узнать, как в Linux устроена работа с памятью.



Основные темы, затронутые на семинаре:
  • Задачи и компоненты подсистемы управления памятью;
  • Аппаратные возможности платформы x86_64;
  • Как описывается в ядре физическая и виртуальная память;
  • API подсистемы управления памятью;
  • Высвобождение ранее занятой памяти;
  • Инструменты мониторинга;
  • Memory Cgroups;
  • Compaction — дефрагментация физической памяти.

Под катом вы найдете более подробный план доклада с раскрытием основных понятий и принципов.



Задачи подсистемы управления памятью и компоненты, из которых она состоит


Основная задача подсистемы — выделение физической памяти ядру и userspace-процессам, а также высвобождение и перераспределение в тех случаях, когда вся память занята.

Основные компоненты:
  • Buddy allocator занимается менеджментом пула свободной памяти.
  • Page replacent («LRU» reclaim model) решает, у кого отобрать память, когда закончилась свободная.
  • PTE management — блок управления таблицами трансляции.
  • Slub kernel allocator — внутренний ядерный аллокатор.
  • и др.

Аппаратные возможности платформы x86_64


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

Как описывается в ядре физическая и виртуальная память?


Физическая память в ядре описывается тремя структурами: ноды (pg_data_t), зоны (struct zone), страницы (struct page). Виртуальная память у каждого процесса своя и описывается при помощи структуры struct mm_struct. Они, в свою очередь, делятся на регионы (struct vm_area_struct).

API подсистемы управления памятью


Ядро взаимодействует с подсистемой memory management при помощи таких функцций функций, как __get_free_page(), kmalloc(), kfree(), vmalloc(). Они отвечают за выделение свободных страниц, больших и малых участков памяти, а также их высвобождение. Существует целое семейство подобных функций, отличающихся небольшими особенностями, например, будет ли занулена область при высвобождении.

Пользовательские программы взаимодействуют с mm-подсистемой при помощи функций mmap(), munmap(), brk(), mlock(), munlock(). Также есть функции posix_fadvice() и madvice(), которые могут давать ядру «cоветы». Но учитывать их в своих эвристиках оно строго говоря не обязано.

Высвобождение ранее занятой памяти (memory reclaim)


Система всегда старается поддерживать некоторый объем свободной памяти (free pool). Таким образом, память выделяется гораздо быстрее, т.к. не приходится высвобождать ее в тот момент, когда она уже действительно нужна.

Те страницы в памяти, которые используются постоянно (системные библиотеки и т.п), называются working set. Вытеснение их из памяти приводит к замедлению работы всей системы. Общая скорость потребления памяти в системе называется memory pressure. Эта величина может очень сильно колебаться в зависимости от того, насколько загружена система.

Всю незанятую ядром память в системе можно поделить на две части: анонимная память и файловая. Отличаются они тем, что про первую мы точно знаем, что каждый ее кусок соответствует какому-либо файлу, и его можно туда сбросить.

Модель «LRU»


LRU расшифровывается как least recently used. Это абстракция, которая предлагает выкидывать страницы, к которым мы дольше всего не обращались. Реализовать ее в Linux полноценно невозможно, т.к. все что нам известно — было ли когда-либо обращение к той или иной странице. Чтобы как-то отслеживать частоту обращений к страницам используются списки active, inactive и unevictable. В последнем находятся залоченные пользователем страницы, которые не будут выбрасываться из памяти ни при каких условиях.

Существуют четкие правила перемещения между списками inactive и active. Под воздействием memory pressure, страницы из неактивного списка могут быть либо выброшены из памяти, либо перейти в активный. Страницы из активного списка перемещаются в неактивный, если к ним давно не было обращений.

Инструменты мониторинга


Утилита top демонстрирует статистику потребления памяти в системе. Програмка vmtouch — показывает какая часть определенного файла находится в памяти. Исчерпывающую информацию по количеству файловых, активных и неактивных страниц можно найти в /proc/vmstat. Статистика buddy allocator есть в /proc/buddyinfo, а статистика slub allocator, соответственно, в /proc/slabinfo. Часто бывает полезно посмотреть на perf top, где отлично видны все проблемы с фрагментацией.

Memory cgroups


Сигруппы зародились из желания выделить группу из нескольких процессов, объединить их логически и ограничить их суммарное потребление памяти определенным. При этом, если они достигнут своего лимита, память должна высвобождаться именно из выделенного им объема. В этом случае нужно освободить память, принадлежащую именно этой сигруппе (это называется target reclaim). Если в системе просто закончилась память и нужно пополнить free pool — это называется global reclaim. C точки зрения аккаунтинга каждая страница принадлежит только одной сигруппе: той, которая ее первой прочитала.

Compaction


Compaction — это механизм дефрагментации физической памяти. Он достаточно подробно описывается в этой статье. Механизм этот был достаточно долго сломан, примерно с версии 3.3 до версии 3.7. Это проявлялось в том, что на некоторых машинах с мощным фрагментирующим моментом спустя две недели работы все процессоры были заняты исключительно compaction и никакого полезного действия не совершали.
Автор: @yaklamm
Яндекс
рейтинг 302,06

Комментарии (15)

  • +2
    Очень интересно, но мало. Требуем подробнее и больше.
    • +3
      Чувак непрерывно целый час говорил, а вам мало)) За подробностями на гитхаб, как говорится.
      • +7
        Ох, тут видео, оказывается. Request Policy порезало, я думал только конспект. С видео всё ок, спасибо ещё раз.
    • +1
      Подробнее можно почитать в книге Бовет и Чезати «Ядро Linux». Затронутые темы слишком обширны, чтобы так по ним галопировать.
  • +3
    Хотелось бы попросить делать видео «поменьше картинку докладчика и побольше видео его экрана». Хотя бы при смене слайда или попеременно. А то приходиться сильно зрение напрягать что бы понять что там показывают.
    • +1
      Спасибо за замечание, учтём в будущем.
      Обратите внимание, что там есть кнопки развернуть на весь экран и HD — так экран со слайдами будет видно хорошо.
      • +1
        «Развернуть на весь экран» — да, а вот HD как-то непривычно реализована. Я первый 20 минут смотрел в HD и думал «какое-то оно хреновое HD». Потом таки тыкнул по индикатору выбора качества видео в надежде найти тим FullHD, а оказалось что это кнопка включения\выключения HD и все это время оба у меня была выключена.
      • +1
        А можно для еще большего удобства просмотра слайды еще отдельно выкладывать?
        Чтобы их можно было в большем разрешении или дольше посмотреть, или во время прослушивания вернуться и посмотреть предыдущий слайд…
        • +1
          Добавили презентацию сразу после ката.
  • +1
    Ссылку на слайды добавьте пожалуйста (в личку писал, просил добавить, но пока так и не добавили)
    • +2
      Слайды теперь сразу полсе ката.
  • +1
    За ядерные потроха всегда зелень, спасибо!
  • 0
    Роман, вы обмолвились про «наш запатченный vmtouch», а где его можно взять?
    • +1
      В публичном доступе нигде. Кроме того, к нему должно прилагаться пропатченное ядро.
      Идея простая: передавать информацию о том, что страница лежит в active в свободном бите в вызове mincore(), который используется vmtouch.
  • +1
    Лучше бы видео на ютуб выложили. Для ютуба полно инструментов для скачивания видео, позволяющие его потом смотреть оффлайн, например…

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разное