Для оригинальной версии ядра 3.10 linux (не исправлено, поскольку у меня нет LXR для ядер rhel) syscall move_pages
приведет к разделению огромной страницы (2 МБ; стили THP и hugetlbfs) на маленькие страницы (4 КБ). move_pages использует слишком короткие чанки (около 0,5 МБ, если я правильно рассчитал), и график функции выглядит так:
move_pages
.. -> migrate_pages
-> unmap_and_move
->
static int unmap_and_move(new_page_t get_new_page, unsigned long private,
struct page *page, int force, enum migrate_mode mode)
{
struct page *newpage = get_new_page(page, private, &result);
....
if (unlikely(PageTransHuge(page)))
if (unlikely(split_huge_page(page)))
goto out;
PageTransHuge
возвращает true для обоих видов огромных страниц (thp и libhugetlbs): https://elixir.bootlin.com/linux/v3.10/source/include/linux/page-flags.h#L411
PageTransHuge () возвращает true как для прозрачных огромных страниц, так и для страниц hugetlbfs, но не обычные страницы.
И split_huge_page
будут вызывать split_huge_page_to_list
, которые :
Разделить огромную страницу на нормальные страницы. Это не меняет положение главной страницы.
Split также выдаст приращение счетчика vm_event вида THP_SPLIT
. Счетчики экспортируются в /proc/vmstat
( "файл отображает различную статистику виртуальной памяти" ). Вы можете проверить этот счетчик с помощью этой команды UUO C cat /proc/vmstat |grep thp_split
до и после теста.
В версии 3.10 был некоторый код для переноса огромных страниц в виде функции unmap_and_move_huge_page
, которая не вызывается с move_pages
. только его использование в 3.10 было в migrate_huge_page
, которое называется только из обработчик сбоя памяти soft_offline_huge_page
(__soft_offline_page
) (добавлено 2010 ):
Софт офлайн-страницы, путем миграции или аннулирования, без уничтожения чего-либо. Это относится к случаю, когда страница еще не повреждена (поэтому она все еще действительна для доступа), но имеет ряд исправленных ошибок и ее лучше удалить.
Ответы:
может move_pages () перемещать огромные страницы? если да, должна ли граница страницы быть 4 КБ или 2 МБ при передаче массива адресов страниц? Похоже, что был патч для поддержки движущихся огромных страниц 5 лет go.
Стандартное ядро 3.10 имеет move_pages, который будет принимать массивы "страниц" 4KB указателей страниц и будет разбиваться (разбиваться) огромная страница на 512 маленьких страниц, а затем он будет мигрировать маленькие страницы. Шансы на их слияние с thp очень малы, так как move_pages выполняет отдельные запросы к страницам физической памяти, и они почти всегда будут непостоянными.
Не указывайте "2MB", это будет все еще разделяет каждую упомянутую огромную страницу и переносит только первые 4 КБ маленькие страницы этой памяти. Патч
2013 не был добавлен в оригинальное ядро 3.10.
Патч, кажется, будет принят в сентябре 2013 года: https://github.com/torvalds/linux/search?q=+extend+hugepage+migration&type=Commits
, если move_pages () не может двигаться огромные страницы, как я могу перемещать огромные страницы?
move_pages
будет перемещать данные с огромных страниц в виде маленьких страниц. Вы можете: разместить огромную страницу в ручном режиме на правильном узле numa и скопировать ваши данные (скопируйте дважды, если вы хотите сохранить виртуальный адрес); или обновите ядро до какой-то версии с помощью патча и используйте методы и тесты автора патча, Наоя Хоригучи (JP) . Есть копия его тестов: https://github.com/srikanth007m/test_hugepage_migration_extension (https://github.com/Naoya-Horiguchi/test_core требуется)
https://github.com/srikanth007m/test_hugepage_migration_extension/blob/master/test_move_pages.c
Теперь я не уверен, как запустить тест и как проверить, что он работает правильно. Для ./test_move_pages -v -m private -h 2048
, работающего с последним ядром, он не увеличивает счетчик THP_SPLIT.
Его тест выглядит очень похоже на наши тесты: mmap, memset для страниц с ошибками, заполнение массива страниц указателями на маленькие страницы, numa_move_pages
после перемещения огромных страниц, могу ли я запрашивать идентификаторы NUMA огромных страниц таким же образом, как я запрашиваю обычные страницы, как этот ответ?
Вы можете запросить состояние любой памяти, указав правильный массив "pages" для move_pages
системного вызова в режиме запроса (с нулевыми узлами). Массив должен перечислять каждую маленькую страницу области памяти, которую вы хотите проверить.
Если вы знаете какой-либо надежный способ проверить, соответствует ли память огромной странице или нет, вы можете запросить любую маленькую страницу огромной страницы. Я думаю, что может быть вероятностный метод c, если вы можете экспортировать физический адрес из ядра в пользовательское пространство (например, с помощью некоторого модуля LKM ): для огромных страниц виртуальные и физические адреса всегда будут 21 общая LSB бит , а для маленьких страниц биты будут совпадать только для 1 теста на миллион. Или просто напишите LKM для экспорта PMD Directory .