move_pages -
あるプロセスの個々のページを別のノードに移動する
#include <numaif.h>
long move_pages(int pid, unsigned long count, void **pages,
const int *nodes, int *status, int flags);
-lnuma とリンクする。
move_pages() は、プロセス
pid
の指定されたページ
pages を
nodes
で指定されたメモリノードに移動する。
移動の結果は
status
に反映される。
flags
では移動されるページに関する制約を指定する。
pid
は、移動されるページが属するプロセスの
ID である。
別のプロセスのページを移動するためには、呼び出し元が特権
(
CAP_SYS_NICE)
を持っているか、呼び出したプロセスの実ユーザ
ID か実効ユーザ ID が
ページ移動対象のプロセスの実ユーザ
ID か保存 set-user-ID
のどちらかと
一致しなければならない。
pid が 0 の場合、
move_pages()
は呼び出したプロセスのページを移動する。
count
は移動するページ数である。
count により
pages,
nodes,
status の 3
つの配列の大きさが定義される。
pages
は、移動すべきページへのポインタの配列であり、
各ポインタはページ境界に揃えた値を指定すべきである。
pid
で指定されたプロセスで見えるアドレスを指定する。
nodes
は、各ページの希望の移動場所を示す整数値の配列であり、
配列の各要素はノード番号である。
nodes には NULL
を指定することもでき、この場合には
move_pages()
はどのページも移動しないが、各ページが現在配置されているノードを配列
status
に格納して返す。どのページを移動する必要があるかを判断するために、
各ページの状態の取得が必要な場合もある。
status
は、各ページの状態を表す整数値の配列である。
この配列に有効な値が格納されるのは、
move_pages()
がエラーを返さなかった場合だけである。
flags
には、どの種類のページを移動するかを指定する。
MPOL_MF_MOVE
は、そのプロセスが排他的に使用しているページだけを移動することを意味する。
MPOL_MF_MOVE_ALL
は、複数のプロセス間で共有されているページも移動できることを意味する。
MPOL_MF_MOVE_ALL
を使用するためには、そのプロセスが特権
(
CAP_SYS_NICE)
を持っていなければならない。
status
配列に格納されるページ状態¶
status
配列の各要素として、以下の値が返される。
- 0..MAX_NUMNODES
- そのページが配置されているノードを示す。
- -EACCES
- そのページは複数のプロセスによりマップされており、
MPOL_MF_MOVE_ALL
が指定された場合にのみ移動できる。
- -EBUSY
- そのページが現在ビジーであり、移動できない。後でもう一度試すこと。
この状況は、ページが
I/O
の実行中であったり、カーネルの他のサブシステム
がそのページへの参照を保持している場合に発生する。
- -EFAULT
- そのページが zero page
であるか、そのメモリ領域はそのプロセスにより
マップされていない。
- -EIO
- ページを書き戻す
(write back)
ことができない。
ページが dirty
で、ファイルシステムが
dirty
なページを移動できるような
移動機能を提供していないため、そのページを移動するためにはページを
書き戻さなければならない。
- -EINVAL
- dirty
なページを移動できない。
ファイルシステムが
dirty
なページを移動するための機能を提供しておらず、
ページを書き戻す能力もない。
- -ENOENT
- ページが存在しない。
- -ENOMEM
- 移動先のノードでメモリを確保することができない。
返り値¶
成功すると、
move_pages() は 0
を返す。
エラーの場合、-1
を返し、
errno
にエラーを示す値を設定する。
エラー¶
- E2BIG
- 移動すべきページが多過ぎる。
- EACCES
- 移動先のノードのいずれかが現在の
CPU
集合では許可されていない。
- EFAULT
- パラメータ配列にアクセスできなかった。
- EINVAL
- flags に MPOL_MF_MOVE でも
MPOL_MF_MOVE_ALL
でもない値が指定されたか、カーネルスレッドのページを移動させようとした。
- ENODEV
- 移動先のノードのいずれかがオンラインでない。
- ENOENT
- 移動が必要なページが全く見つからなかった。
指定された全てのページが、すでに移動先のノードに存在するか、存在しないか、
無効なアドレスであったか、複数のプロセスによってマップされていて移動でき
なかったか、のいずれかであった。
- EPERM
- 呼び出し元は
MPOL_MF_MOVE_ALL
を指定したが、十分な特権
( CAP_SYS_NICE)
を持っていない。
または、呼び出し元が他のユーザに属するプロセスのページを移動しようとしたが、
それを行えるだけの特権
( CAP_SYS_NICE)
を持っていなかった。
- ESRCH
- プロセスが存在しない。
バージョン¶
move_pages() は、バージョン
2.6.18 で初めて Linux
に登場した。
このシステムコールは
Linux 固有である。
ライブラリによるサポートについては
numa(7) を参照。
現在の CPU
集合で許可されているノードの集合を取得するには、フラグ
MPOL_F_MEMS_ALLOWED を指定して
get_mempolicy(2)
を使用すればよい。
取得した情報は、CPU
集合の手動または自動での再構成により
いつ何時変化してしまうか分からない。
この関数を使用すると、ページの位置
(ノード) が
指定されたアドレスに対して設定されたメモリポリシー
(
mbind(2) 参照)
や指定されたプロセスに対して設定されたメモリポリシー
(
set_mempolicy(2) 参照)
に違反してしまう可能性がある。
つまり、メモリポリシーは
move_pages()
で使われる移動先ノードを制限しないということである。
ヘッダファイル
<numaif.h>
は glibc
には含まれておらず、
libnuma-devel
か同様のパッケージをインストールする必要がある。
関連項目¶
get_mempolicy(2),
mbind(2),
set_mempolicy(2),
numa(3),
numa_maps(5),
cpuset(7),
numa(7),
migratepages(8),
numa_stat(8)
この文書について¶
この man ページは Linux
man-pages
プロジェクトのリリース
3.41 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。