Zarządzanie Hugepage baseny z przegrodą pamięci w Linuksie

Original: http://www.csn.ul.ie/~mel/docs/poolmanagement/

 

Pierwszy pisał w blogu tutaj.
Ostatnia aktualizacja: 26 października 2007

Hugepages potencjalnie mogą osiągnąć wyższą wydajność sprzętu poprzez ograniczenie TLB strzela i cache CPU usage [1]. Korzyści z reguły stosuje się do zastosowań, które wykorzystują duże ilości przestrzeni adresowej, chociaż nie może być wtórne korzyści, takie jak poprawa sprzęt pre-fetch.

Na wniosek wykorzystać coś z tego jednak, hugepages muszą być dostępne. Nie jest trywialne zdecydowana większość procesorów wymagać pamięci być oczywiście zestrojone i przylega zarówno fizycznie, jak i wirtualnym. W przeszłości administratorzy musieli zarezerwować na hugepages czasie startu systemu, jak pamięć stała się zbyt rozdrobniony, w krótkim okresie czasu przydzielenia strony normalnie. Doborze basen przedstawiony trudny problem do administratora: zbyt duży i pamięci jest tracona w systemach długowiecznych; zbyt małe i aplikacji nie powiedzie się. Ten problem sam wyklucza hugepages zostały użyte w kilku sytuacjach.

Jednak ograniczenie to zostało złagodzone nieco w jądrze 2.6.23 z powodu partycji pamięci. Korzystanie z partycjonowanie, administrator może rosnąć i kurczyć się basen w trakcie trwania układu zamiast podejmowaniu decyzji w czasie startu systemu. W tym artykule omówimy, jak zrobić hugepages dostępny z większą elastyczność niż było wcześniej dostępne.

Informacje podstawowe Hugepage
Aby dowiedzieć się, czy jądro obsługuje hugepages, przeczytaj / proc / meminfo i poszukaj wpisów HugePages. Na przykład, na moim komputerze widzę
Mel @ Arnold: ~ $ grep Wielki / proc / meminfo
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
Hugepagesize: 4096 kB
Oznacza to, że jądro obsługuje hugepage zużycia, ale nie mam żadnych hugepages w basenie i hugepage jest 4MiB wielkości. Aby dodać hugepages na basen, numer jest po prostu zapisywane do / proc / sys / vm / nr_hugepages jak tak;
Arnold: / proc / sys / vm # echo 10> nr_hugepages
Arnold: / proc / sys / vm # cat nr_hugepages
10
Arnold: / proc / sys / vm # grep Wielki / proc / meminfo
HugePages_Total: 10
HugePages_Free: 10
HugePages_Rsvd: 0
Hugepagesize: 4096 kB
Dyskusji, jak korzystać hugepages w aplikacji wykracza poza zakres tego artykułu, ale istnieją informacje, jeśli rozejrzeć się [1] [2].

W przypadku, gdy coś idzie nie tak
W standardowym systemie raz pamięć została wypełniona (updatedb, Dekompresja i rozpakowywanie wiele danych itp), pamięć staje się zbyt rozdrobnione i pisanie wartość nr_hugepages nie może przydzielić wszystkich wymaganych hugepages.Problemem jest to, że nie wszystkie pamięci mogą zostać odzyskane przez jądro. Wiele stron dedykowanych przez jądro nie może być łatwo odzyskane na żądanie i tylko jeden źle umieszczona strona może spowodować awarię przydziału hugepage.

Rozwiązanie problemu z partycji pamięci
Od wersji 2.6.23, pamięć może być podzielony na dwie części przy każdym uruchomieniu tworząc strefę o nazwie ZONE_MOVABLE (patrz informacje na temat stref przez czytanie / proc / zoneinfo). Tylko strony, które mogą być odzyskane na żądanie użycia jądra tej strefie. W ramach tego obszaru pamięci, przydział hugepage prawie zawsze (patrz Ostrzeżenia później) odnieść sukces bez względu na to, jak długo system jest uruchomiony.

Więc powiedzmy, że administrator wie, że liczba miejsc pracy zostanie uruchomiony na swoim systemie, który ma zostać użyty hugepages. Zadania korzystać między 0 i 256 hugepages i nie chce tracić pamięć. Wcześniej, administrator określa, hugepages = 256 na linii poleceń i tracić pamięć dla zadań, które nie jest używany.

Teraz zamiast administrator określa, movablecore = 1024MB w wierszu poleceń do konfiguracji partycji dla ruchomych stron 1GiB rozmiaru lub 256 hugepages. Oferty pracy, które wymagają hugepages może teraz zwrócić je z / proc / sys / vm / nr_hugepages i mieć uzasadnione oczekiwanie uzyskania tych stron.

Różnica między podziałem i konfigurowania basen w czasie startu systemu jest to, że pamięć na partycji niewykorzystanej przez hugepages mogą być nadal używane do normalnych stron. Oznacza to, że pamięć może być zwrócony po zakończeniu procesu stronę świetnie, i przeniesione do małych procesów stronie; Pamięć nigdy nie jest zmarnowany.

Konfigurowanie partycji pamięci
Partycja musi być skonfigurowany przy każdym uruchomieniu przy użyciu albo kernelcore = lub movablecore = udokumentowane w pliku Documentation / kernel-parameters.txt. movablecore określa ile pamięci powinny być wykorzystywane do ZONE_MOVABLE.Alternatywnym sposobem jest spojrzenie na movablecore

Maksymalna Hugepages, które mogą być przyznane w każdym czasie = movablecore / hugepagesize

Jeśli z drugiej strony administrator wie, ile pamięci resztę potrzeb jądra i chce jak najwięcej pamięci, jak to możliwe, aby być dostępne dla różnej liczby hugepages, kernelcore = może być stosowany zamiast. W takim przypadku, wielkość pamięci ZONE_MOVABLE jest co pozostawia się lub alternatywnie

Maksymalna Hugepages, które mogą być przyznane w każdym czasie = (TotalMem – kernelcore) / hugepagesize

Gdy partycja jest konfiguracja, ogromne strony nie będą automatycznie przydzielane z nim. To dlatego, że hugepages nie są w pełni ruchome i partycja może być również skonfigurować do hot-usuwanie pamięci w czasie wykonywania. Aby umożliwić hugepages być przydzielane z puli, zrobić
Arnold: / proc / sys / vm # echo 1> hugepages_treat_as_movable

Rośnie The Pool
Gdy partycja jest konfiguracja, basen hugepage może być łatwo uprawiana. W zależności od aktywności systemu pierwsza próba może się nie powieść, więc spróbować kilka razy lub użyć skryptu jak ten nie-bardzo-testowane i bardzo szorstki dzieło;

#!/bin/bash
# Attempt to grow the pool to the requested size
# This benchmark checks how many hugepages can be allocated in the hugepage
# pool
#
# Copyright Mel Gorman (c) 2007
# Licensed under GPL V2. See http://www.gnu.org/licenses/gpl-2.0.txt for details

SLEEP_INTERVAL=5
FAIL_AFTER_NO_CHANGE_ATTEMPTS=20
NUM_REQUIRED=0

usage() {
	echo "get_hugepages: Get the requested number of hugepages"
	echo
	echo "	-s	Time to sleep between attempts to grow pool"
	echo "	-f	Give up after failing this number of times"
	echo "	-n	Number of hugepages that should be in the pool"
	echo
	exit $1
}

# Arg processing
while [ "$1" != "" ]; do
	case "$1" in
		-s)	export SLEEP_INTERVAL=$2; shift 2;;
		-f)	export FAIL_AFTER_NO_CHANGE_ATTEMPTS=$2; shift 2;;
		-c)	export MAX_ATTEMPT=$2; shift 2;;
		-n)	export NUM_REQUIRED=$2; shift 2;;
	esac
done

# Check proc entry exists
if [ ! -e /proc/sys/vm/nr_hugepages ]; then
	echo Attempting load of hugetlbfs module
	modprobe hugetlbfs
	if [ ! -e /proc/sys/vm/nr_hugepages ]; then
		echo ERROR: /proc/sys/vm/nr_hugepages does not exist
		exit -1
	fi
fi

# Check a number was requested
if [ "$NUM_REQUIRED" = "" -o $NUM_REQUIRED -lt 0 ]; then
	echo ERROR: You must specify a number of hugepages to alloc
	usage -2
fi

# Ensure we have permission to write
echo $STARTING_COUNT 2> /dev/null > /proc/sys/vm/nr_hugepages || {
	echo ERROR: Do not have permission to adjust nr_hugepages count
	exit -3
}

# Record existing hugepage count
STARTING_COUNT=`cat /proc/sys/vm/nr_hugepages`
echo Starting page count: $STARTING_COUNT

# Start attempt to grow pool
CURRENT_COUNT=$STARTING_COUNT
LAST_COUNT=$STARTING_COUNT
NOCHANGE_COUNT=0
ATTEMPT=0

while [ $NOCHANGE_COUNT -ne $FAIL_AFTER_NO_CHANGE_ATTEMPTS ] && [ $CURRENT_COUNT -ne $NUM_REQUIRED ]; do
	ATTEMPT=$((ATTEMPT+1))
	echo $NUM_REQUIRED > /proc/sys/vm/nr_hugepages

	CURRENT_COUNT=`cat /proc/sys/vm/nr_hugepages`
	PROGRESS=
	if [ $CURRENT_COUNT -eq $LAST_COUNT ]; then
		NOCHANGE_COUNT=$(($NOCHANGE_COUNT+1))
	elif [ $CURRENT_COUNT -ne $NUM_REQUIRED ]; then
		NOCHANGE_COUNT=0
		PROGRESS="Progress made with $(($CURRENT_COUNT-$LAST_COUNT)) pages"
		echo Attempt $ATTEMPT: $CURRENT_COUNT pages $PROGRESS 
		LAST_COUNT=$CURRENT_COUNT
		sleep $SLEEP_INTERVAL
	fi

done

echo Final page count: $CURRENT_COUNT

# Exit with 0 if number of pages was successfully allocated
if [ $CURRENT_COUNT -eq $NUM_REQUIRED ]; then
	exit 0
else
	exit -4
fi

Ostrzeżenia
Przydziały prawie zawsze się uda.Jeden przypadek, w którym nie jest, gdy pamięć jest mlock () ed. Technicznie te strony mogą być przenoszone i istnieją łatki nie tylko to, ale nie było zapotrzebowania na funkcję do dnia dzisiejszego.

Przyszłość
W 2.6.24, grupowanie stron mobilność może oznaczać, że partycja nie musi nawet być skonfigurowany do jądra, aby móc się rozwijać / zmniejszyć basen w dużym stopniu. Jednakże, jeśli dostępność hugepage muszą być gwarantowane przez cały czas, a następnie partycja powinna być konfiguracja.

Podsumowanie Nie masz go. W przeszłości hugepages musiały być przyznane w czasie ładowania systemu. Teraz można skonfigurować partycję przy każdym uruchomieniu zamiast i przydzielić hugepages do puli, gdy są potrzebne, i zwrócić je do ogólnego stosowania, gdy nie jest wymagane pozwalając pamięci do wykorzystania jako normalne.

Podziękowania
Dzięki Nishanth Aravamudan i Andy Whitcroft do przeglądu projektów tego.

Referencje
[1] Wykorzystaj przejrzyste ogromne stron na Linux na platformie POWER
http://www.ibm.com/developerworks/systems/library/es-Lop-leveragepages/

[2] Źródło Kernel: Dokumentacja / VM / hugetlbpage.txt

Comments are closed.