6 ヒュージ・ページの構成

Oracle Linuxでは、物理メモリーはページと呼ばれる固定サイズのブロックで管理されます。x86_64アーキテクチャでは、各ページのデフォルト・サイズは4KBです。

カーネルは、ページの仮想アドレスから物理アドレスへのマッピングを、ページ表と呼ばれるデータ構造に格納します。ただし、ページ表のルックアップはリソースを大量に消費するため、最近使用されたアドレスはCPUのTranslation Lookaside Buffer (TLB)にキャッシュされるため、取得が高速になります。CPUがアドレスマッピングのリクエストを満たす必要がある場合、CPUは最初にそのTLBキャッシュを検索します。TLBヒットは、TLBキャッシュ内のアドレスを見つけるCPUを示します。TLBミスは、リクエストされたアドレスマッピングがキャッシュ内に見つからないCPUを示します。その場合、システムはページ表上でリソースを大量に消費するルックアップを実行してアドレス情報を取得します。

4KBのデフォルト・ページ・サイズは、ほとんどのアプリケーションに適しています。ただし、大量のメモリーで動作するアプリケーションの場合、必要な4KBページの数が増加し、TLBミスの数が多くなり、パフォーマンスのオーバーヘッドが発生する可能性があります。より多くのメモリーを必要とするアプリケーションがより少ないページで要件を満たすことができるように、Oracle Linuxにはヒュージ・ページ機能が提供されています。

使用可能なヒュージ・ページ機能

Oracle Linuxには、次のヒュージ・ページ機能が含まれています:

HugeTLBページ

HugeTLBページは、静的ヒュージ・ページとも呼ばれます。

HugeTLBページ機能を使用すると、各ヒュージ・ページのサイズについて、指定された各数量のヒュージ・ページのプールを予約できます。x86_64プラットフォームで使用可能な巨大なページ・サイズ・オプションは、2MBおよび1GBです。

HugeTLBページの構成の詳細は、「HugeTLBページの構成」を参照してください

ノート:

ベスト・プラクティス:
  • メモリーの断片化の発生が最小限の場合、できるだけブート時間に近い静的なヒュージ・ページのリクエストをカーネルに作成します。
  • ヒュージ・ページでは、システムで使用可能なメモリーの量を減らすことができます。したがって、予約されたヒュージ・ページ・プールをリクエストする場合は、プールのサイズが超過していないこと、およびシステムのメモリーへのアクセスが影響を受けないことを確認してください。

透過的HugePages

透過的HugePages (THP)機能は、Oracle Linuxでデフォルトで有効になっています。THPでは、カーネルによってヒュージ・ページが自動的にプロセスに割り当てられます。THPでは、x86_64プラットフォームに2MBのページのみを割り当てることができます。

THPは、次のモードで実行できます。

  • system-wide (デフォルト): カーネルは、可能なかぎり、連続する大きな仮想メモリー領域を使用するプロセスにヒュージ・ページを割り当てます。
  • per-process: カーネルは、madvise()システム・コールを介してヒュージ・ページを明示的にリクエストするアプリケーション・プロセスにのみ、ヒュージ・ページを割り当てます。

THPの構成の詳細は、「透過的HugePagesの構成」を参照してください

HugeTLBページの構成

次のタイプのパラメータを使用して、HugeTLBページを構成できます。

  • カーネル・ブート・パラメータ
  • ファイルベースの構成パラメータ

次の各項では、パラメータの詳細を説明します。

HugeTLBページのカーネル・ブート・パラメータ

カーネル・ブート・オプションを使用すると、カーネルのプールに予約するサイズやページ数などの値を指定できます。カーネル・ブート・パラメータの使用は、ヒュージ・ページをリクエストする最も信頼性の高い方法です。

次の表に、HugeTLBページ設定で使用可能なカーネル・ブート・パラメータを示します。

表6-1 HugeTLBページをリクエストするためのカーネル・ブートのコマンドライン・パラメータ

<table cellpadding="4" cellspacing="0" class="Formal" title="The Kernel Boot Command Line Parameters for Requesting HugeTLB Pages" summary='This table describes the kernel boot parameters that are available for HugeTLB page setup. The content includes variable placeholders, for example "<size>" for size of page, and " パラメータ 用途 x86_64アーキテクチャで使用可能な値オプション default_hugepagesz ブート時にカーネルで構成された永続的なヒュージ・ページのデフォルト・サイズを定義します。 2M (デフォルト)、1G hugepageszおよびhugepages

サイズ・パラメータhugepageszを数量パラメータhugepagesとともに使用して、指定したページ・サイズおよび数量のプールを予約します。たとえば、サイズが2MBの1500ページのプールをリクエストするには、コマンドライン・オプションは次のようになります:

hugepagesz=2M hugepages=1500

複数のヒュージ・ページ・サイズがサポートされている場合は、ページ・サイズごとに1回ずつ、"hugepagesz=<size> hugepages=<qty>"ペアを複数回指定できます。たとえば、次のコマンドライン・オプションを使用すると、1GBサイズの4ページの1つのプールと、2MBサイズの1500ページのもう1つのプールをリクエストできます:

hugepagesz=1G hugepages=4 hugepagesz=2M hugepages=1500

Hugepagesz: 2M1G

hugepages: 0以上

ノート:

NUMAシステムでは、前の表に示すように、カーネル・コマンドライン・オプションで予約されたページはNUMAノード間で均等に分割されます。

各ノードでページ数が異なることが要件である場合は、sysfsファイル・システムでファイルベースのHugeTLBパラメータを使用できます。「HugeTLBページのファイルベースの構成パラメータ」および「ブート・プロセスの初期段階でのNUMAノード固有パラメータを使用したHugeTLBページのリクエスト」を参照してください。

HugeTLBページのファイルベースの構成パラメータ

ファイルベースの構成パラメータは、構成設定への実行時アクセスを提供します。

ノート:

実行時に設定にアクセスするだけでなく、起動bashスクリプトの作成や、ローカルのrc initスクリプトでのパラメータの設定によって、ブート・プロセスの初期段階でパラメータを初期化することもできます。
各ファイルベース・パラメータの複数のインスタンスをシステムで構成できます。たとえば、2MBと1GBのHugeTLBページ・サイズの両方を処理できるシステムでは、複数のnr_hugepages設定が存在することが可能です。このパラメータは、次のようなプール内のページ数を定義します:
  • 2MBページのプール内のページ数を示すファイル/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
  • 1GBページのプール内のページ数を示すファイル/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages

次の表に、一般的に使用されるHugeTLB構成パラメータと、各パラメータに対して検出される複数のファイル・インスタンスを示します。

表6-2 一般的に使用されるファイルベースのHugeTLBパラメータ

<table cellpadding="4" cellspacing="0" class="Formal" title="Commonly Used File-Based HugeTLB Parameters" summary='This table outlines commonly used HugeTLB configuration parameters and the multiple file instances that you might find for each parameter. Some folders in the parameter file paths are listed with placeholder names that convey a range of possible values. For example, the folder name “hugepages- パラメータ 用途 異なるインスタンスのファイル・パス nr_hugepages
  • nr_hugepagesの各インスタンスは、そのインスタンスに関連付けられたプール内の現在のヒュージ・ページ数を定義します。
  • 実行時に変更できます。
  • コマンド例:

    echo 20 | sudo tee /proc/sys/vm/nr_hugepages
  • デフォルト値は0です。
nr_hugepagesの異なるインスタンスのファイル・パス形式は次のとおりです。
  • ファイルの場所: /proc/sys/vm/nr_hugepages (すべてのシステムに存在)。
  • ファイルの場所: /sys/kernel/mm/hugepages/hugepages-<SIZE>kB/nr_hugepages (複数のヒュージ・ページ・サイズをサポートするシステム上に存在)。
  • ファイルの場所: /sys/devices/system/node/node{0,1,2…n}/hugepages/hugepages-<SIZE>kB/nr_hugepages (NUMAシステムのみに存在)。

    ノート:

    特定のNUMAノードでサポートされる様々なサイズのページ数をリクエストする必要がある場合は、NUMAノード固有のパス形式を使用します。他のパス形式(/proc/sys/vm/nr_hugepagesなど)を使用する場合は、HugeTLBページをリクエストします。ページはNUMAノード間で均等に分割されます。

nr_overcommit_hugepages
  • nr_overcommit_hugepagesの各インスタンスは、nr_hugepagesで指定された数量より多い追加の数のヒュージ・ページを定義します。これは、メモリーのオーバーコミットを通じて実行時に、システムによって作成されます。
  • これらの追加のヒュージ・ページは、使用されなくなると、解放されてカーネルの通常のページ・プールに戻されます。
  • コマンド例:
    echo 20 | sudo tee /proc/sys/vm/nr_overcommit_hugepages
nr_overcommit_hugepagesの異なるインスタンスのファイル・パス形式は次のとおりです。
  • ファイルの場所: /proc/sys/vm/nr_overcommit_hugepages (すべてのシステムに存在)。
  • ファイルの場所: /sys/kernel/mm/hugepages/hugepages-<SIZE>kB/nr_overcommit_hugepages (複数のページ・サイズをサポートするシステムに存在)。

ノート:

nr_overcommit_hugepagesパラメータは個々のノード・レベルでは定義されないため、この設定にはノード固有のファイルが存在しません。

free_hugepages
  • 読取り専用パラメータ。
  • free_hugepagesの各インスタンスは、まだ割り当てられていない関連ページ・プール内のヒュージ・ページ数を返します。

free_hugepagesの異なるインスタンスのファイル・パス形式は次のとおりです。

  • ファイルの場所: /sys/kernel/mm/hugepages/hugepages-<SIZE>kB/free_hugepages (複数のヒュージ・ページ・サイズをサポートするシステム上に存在)。
  • ファイルの場所: /sys/devices/system/node/node{0,1,2…n}/hugepages/hugepages-<SIZE>kB/ free_hugepages (NUMAシステムのみに存在)。
surplus_hugepages
  • 読取り専用パラメータ。
  • surplus_hugepagesの各インスタンスは、関連付けられたページ・プールからオーバーコミットされたヒュージ・ページ数を返します。

surplus_hugepagesの異なるインスタンスのファイル・パス形式は次のとおりです。

  • ファイルの場所: /sys/kernel/mm/hugepages/hugepages-<SIZE>kB/surplus_hugepages (複数のヒュージ・ページ・サイズをサポートするシステムに存在)。
  • ファイルの場所: /sys/devices/system/node/node{0,1,2…n}/hugepages/hugepages-<SIZE>kB/surplus_hugepages (NUMAシステムのみに存在)。

次の項では、HugeTLBパラメータの様々なインスタンスが格納されるファイルのブランチを示します:

/proc/sys/vm

静的ヒュージ・ページをサポートするすべてのシステムには、/proc/sys/vmの下にHugeTLBパラメータ・ファイルが含まれています。

ノート:

多数のOracleデータベース・サーバーを含む多くのシステムでは、procfsファイル・システムが使用される主要なパラメータ・セットです。

sysctlパラメータvm.nr_hugepagesは、通常、ヒュージ・ページをリクエストするスクリプトで初期化され、procfsファイル/proc/sys/vm/nr_hugepagesにも書き込まれます。

ブランチ/proc/sys/vmの下にあるフォルダの例を次に示します:

    ├── ...
    ├── ...
    ├── nr_hugepages
    ├── ...
    ├── nr_overcommit_hugepages
    ├── ...
    ├── ...

/sys/kernel/mm/hugepages/

複数のサイズ・プールをサポートするシステムには、/sys/kernel/mm/hugepages/のサイズ固有のフォルダにHugeTLBパラメータ・ファイルが含まれています。

ブランチ/sys/kernel/mm/hugepages/の下にあるフォルダの例を次に示します:

└── hugepages-2048kB
    ├── free_hugepages
    ├── nr_hugepages
    ├── ...
    ├── nr_overcommit_hugepages
    ├── ...
    └── surplus_hugepages

└── hugepages-1048576kB
    ├── free_hugepages
    ├── nr_hugepages
    ├── ...
    ├── nr_overcommit_hugepages
    ├── ...
    └── surplus_hugepages

/sys/devices/system/node/

NUMAシステムのみに、/sys/devices/system/node/にHugeTLBパラメータ・ファイルが含まれています。

ブランチ/sys/devices/system/nodeの下にあるフォルダの例を次に示します:

      ├─  ...
      ├── node0
      │   ├── ...
      │   ├──hugepages
      │          hugepages-2048kB
      │              ├── free_hugepages
      │              ├── nr_hugepages
      │              └── surplus_hugepages
      │   
      │          hugepages-1048576kB
      │              ├── free_hugepages
      │              ├── nr_hugepages
      │              └── surplus_hugepages
      ├── node1
          ├── ...
          ├──hugepages
                 hugepages-2048kB
                     ├── free_hugepages
                     ├── nr_hugepages
                     └── surplus_hugepages
          
                 hugepages-1048576kB
                     ├── free_hugepages
                     ├── nr_hugepages
                     └── surplus_hugepages

ブート時のHugeTLBページの構成

ブート時にヒュージ・ページをリクエストする詳細な方法は、システムの要件によって異なります。次の手順の例では、使用可能な開始点について説明します。

ブート時のカーネル・パラメータを使用したHugeTLBページのリクエスト
次の手順では、カーネル・コマンドライン・オプションを使用して、複数のヒュージ・ページ・サイズを処理するシステムで、HugeTLBページの2つのプールとデフォルトのページ・サイズを指定する方法を示します。この手順では、次をリクエストします:
  • 1GBのデフォルトのページ・サイズ。
  • 1GBサイズのHugeTLBページが4つ含まれる1つのプール。
  • 2MBサイズの1500のHugeTLBページが含まれる1つのプール。
次の手順を開始する前に、必要な管理権限があることを確認してください。
  1. カーネル・ブート・パラメータdefault_hugepageszに1GBサイズを指定し、2つのヒュージ・ページ・プールに2つのペアの"hugepagesz=<Size_num>G hugepages=Qty_num"パラメータを指定します。

    /etc/default/grubのカーネル・コマンドライン・オプションに次の行を追加します

    default_hugepagesz=1G hugepagesz=1G hugepages=4 hugepagesz=2M hugepages=1500
  2. GRUB2構成ファイルを再生成します。
    1. システムでBIOSファームウェアを使用している場合、次のコマンドを実行します:
      sudo grub2-mkconfig -o /boot/grub2/grub.cfg
    2. システムでUEFIフレームワークを使用している場合、次のコマンドを実行します:
      sudo grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
  3. 次回システムがブートすると、2つのヒュージ・ページ・プールがリクエストされます。
ブート・プロセスの初期段階でのNUMAノード固有パラメータを使用したHugeTLBページのリクエスト

前述の例に示すように、カーネル・ブート時パラメータを使用してリクエストされたヒュージ・ページは、NUMAノード間で均等に分割されます。

ただし、ノード固有のファイル・パスに構成値を設定して、特定のノードに対して異なる数のヒュージ・ページをリクエストすることが必要になる場合があります。ファイル・パスは次のように定義されます:

/sys/devices/system/node/node{0,1,2…n}/hugepages/hugepages-<SIZE>kB/

次の手順では、NUMAシステムのノード0に2MBサイズの299ページと、ノード1に2MBサイズの300ページを予約する方法について説明します。

次の手順を開始する前に、すべてのステップに必要な管理権限があることを確認してください。

  1. /usr/lib/systemd/ディレクトリにhugetlb-reserve-pages.shというスクリプト・ファイルを作成し、次の内容を追加します。
    #!/bin/sh
    
    nodes_path=/sys/devices/system/node/
    if [ ! -d $nodes_path ]; then
        echo "ERROR: $nodes_path does not exist"
        exit 1
    fi
    
    #######################################################
    #                                                     #
    #     FUNCTION                                        #
    #           reserve_pages <number_of_pages> <node_id> #
    #                                                     #
    ####################################################### 
    
    reserve_pages()
    {
        echo $1 > $nodes_path/$2/hugepages/hugepages-2048kB/nr_hugepages
    }
    
    reserve_pages 299 node0    
    reserve_pages 300 node1 
    
  2. スクリプトを実行可能にします。
    sudo chmod +x /usr/lib/systemd/hugetlb-reserve-pages.sh
  3. /usr/lib/systemd/system/ディレクトリにhugetlb-gigantic-pages.serviceというサービス・ファイルを作成し、次の内容を追加します。
    [Unit]
    Description=HugeTLB Gigantic Pages Reservation
    DefaultDependencies=no
    Before=dev-hugepages.mount
    ConditionPathExists=/sys/devices/system/node
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=/usr/lib/systemd/hugetlb-reserve-pages.sh
    
    [Install]
    WantedBy=sysinit.target
  4. サービス・ファイルを有効にします。
    sudo systemctl enable hugetlb-gigantic-pages

実行時のHugeTLBの構成

場合によっては、実行時にヒュージ・ページに対してリクエストを作成する必要があります。

実行時の特定のNUMAノードのHugeTLBページの構成

次の手順は、実行時にnode2に対してサイズ2048KBの20のHugeTLBページをリクエストする方法を示しています。

開始する前に、すべてのステップに必要な管理権限があることを確認する必要があります。
  1. numastatコマンドを実行して、NUMAノードに関連するメモリー統計を表示します。
    numastat -cm | egrep 'Node|Huge'| grep -v AnonHugePages
                     Node 0 Node 1 Node 2 Node 3  Total add
    HugePages_Total       0      0      0      0      0
    HugePages_Free        0      0      0      0      0
    HugePages_Surp        0      0      0      0      0
    
  2. 指定したサイズの必要なヒュージ・ページ数を、選択したノードに追加します(たとえば、ノード2で2MBサイズの20ページ):
    echo 20 | sudo tee /sys/devices/system/node/node2/hugepages/hugepages-2048kB/nr_hugepages
  3. numastatコマンドを再度実行して、リクエストが成功し、リクエストされたメモリー(この例では20 x 2MBページ = 40MB)がHugePages_Totalとしてnode2に追加されていることを確認します:
    numastat -cm | egrep 'Node|Huge'| grep -v AnonHugePages
                     Node 0 Node 1 Node 2 Node 3  Total
    HugePages_Total       0      0     40      0     40
    HugePages_Free        0      0     40      0     40
    HugePages_Surp        0      0      0      0      0
    

透過的HugePagesの構成

透過的HugePages (THP)機能は、Oracle Linuxでデフォルトで有効になっています。ただし、システムのニーズに応じて、THPにアクセスして構成することが必要になる場合があります。

次の項では、様々なTHPパラメータとそれらの構成方法の例について説明します。

透過的HugePagesの構成に使用するパラメータ

次の表に、透過的HugePages (THP)の構成時に使用できる選択されるパラメータ設定を示します。

表6-3 一般的に使用されるTHPパラメータ

パラメータ ファイルの場所 値のオプション
enabled /sys/kernel/mm/transparent_hugepage/enabled THPとそのモードを設定します。このモードは次のいずれかです:
  • always (デフォルト): THPはsystem-wideモードで有効になっています。

    この設定では、カーネルは可能なかぎり、大きな連続する仮想メモリー領域を使用するプロセスにヒュージ・ページを割り当てます。

  • madvise: THPはper-processモードで有効になっています。

    この設定では、カーネルは、madvise()システム・コールを介してヒュージ・ページを明示的にリクエストするアプリケーション・プロセスにのみ、ヒュージ・ページを割り当てます。

  • disabled: THPは無効になっています。
defrag /sys/kernel/mm/transparent_hugepage/defrag
THPが使用できない場合にアプリケーションがページをどのように積極的に再利用し、メモリーをデフラグするかを決定します。次のリストに、使用可能なオプションを示します。
  • always: THPをリクエストしているアプリケーションは、割当て失敗時に停止し、ページおよびコンパクト・メモリーを直接再利用してすぐにTHPを取得します。

  • defer: アプリケーションは停止しませんが、小さなページを引き続き使用します。アプリケーションは、カーネル・デーモンkswapdおよびkcompactdにページおよびコンパクト・メモリーを再利用するようにリクエストし、後でTHPを使用できるようにします。
  • defer+madvise:

    madvise(MADV_HUGEPAGE)コールを使用しているリージョンは、割当て失敗時に停止し、ページおよびコンパクト・メモリーを直接再利用してすぐにTHPを取得します

    ただし、他のすべてのリージョンは、カーネル・デーモンkswapdおよびkcompactdにページおよびコンパクト・メモリーの再利用をリクエストして、後でTHPを使用できるようにします。

  • madvise (デフォルト): madvise(MADV_HUGEPAGE)コールを使用しているリージョンは、割当て失敗時に停止し、ページおよびコンパクト・メモリーを直接再利用してすぐにTHPを取得します

実行時の透過的HugePagesの構成

次の項では、sysfs仮想ファイル・システムのTHPパラメータにアクセスして、実行時にTHPを構成する方法の例を示します。

透過的HugePagesの現在のステータスの取得
THPの現在の設定を確認するには、次のコード例に示すように、/sys/kernel/mm/transparent_hugepage/enabledパラメータを読み取ります。
sudo cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never

角カッコ内の値は、現在の設定を表します。

透過的HugePagesの現在のステータスの変更

THPの現在のステータスを変更するには、優先する設定を/sys/kernel/mm/transparent_hugepage/enabledに書き込む必要があります。次の例は、ステータスをalwaysに設定する方法を示しています。

  1. THPの現在のステータスを確認するには、enabledパラメータを読み取ります。
    sudo cat /sys/kernel/mm/transparent_hugepage/enabled
    always madvise [never]

    角カッコ内の値は、現在の設定を表します。

  2. THPモードをalwaysに設定します。
    echo always | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
  3. enabledパラメータを読み取って、変更が成功したことを確認します。
    sudo cat /sys/kernel/mm/transparent_hugepage/enabled
    [always] madvise never

ノート:

sysfsなどの仮想ファイル・システムは、必ずしもディスク上のファイルとして格納されない項目に、ファイル・システム・インタフェースを提供します。したがって、sysfsファイルは、ディスク上の通常の物理ファイルと同じ方法でファイル・コマンドと相互作用することはありません。前述の例では、echoコマンドを使用した場合、/sys/kernel/mm/transparent_hugepage/enabledは通常のファイルで使用されるように上書きされませんが、選択したオプションが変更されます:
sudo cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
echo always | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
always
sudo cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never

.

透過的HugePagesのデフラグ設定の変更
THPデフラグ設定を変更するには、選択した設定を/sys/kernel/mm/transparent_hugepage/defragに書き込む必要があります

ノート:

最適なdefrag設定は、システムごとに異なります。ページおよびメモリー圧縮を再利用すると、使用可能なTHPページ数が増加する可能性があります。ただし、プロセスではCPU時間も使用されます。したがって、特定のシステムの正しいバランスを見つける必要があります。

次の例は、defrag設定をmadviseに設定する方法を示しています。

  1. defragパラメータの現在の値を確認します。
    sudo cat /sys/kernel/mm/transparent_hugepage/defrag
    [always] defer defer+madvise madvise never

    角カッコ内の値は、現在の設定を表します。

  2. /sys/kernel/mm/transparent_hugepage/defragパラメータをmadviseに設定します。
    echo madvise | sudo tee /sys/kernel/mm/transparent_hugepage/defrag
  3. defragパラメータを読み取って、変更が反映されたことを確認します。
    sudo cat /sys/kernel/mm/transparent_hugepage/defrag
    always defer defer+madvise [madvise] never