numaのnodemask構造体


Rev.1を表示中。最新版はこちら

numaは物理メモリ群を、領域単位で独立したメモリ領域として管理します。この独立したメモリ領域をノードと言い、node_data[]で、そのノード単位のpageを管理しています。

このnode_data[]のどのノードを使うとか、どのように使うかは、メモリポリシーとして定義され、タスク/vma領域単位/tmpfsとか物理メモリを取得するエレメント毎に設定されます。

このどのノードを使うのかは、メモリポリシのメンバーstruct nodemask_tにビットマップとして設定しています。tmpfsのmountオプションのノードリストはstruct nodemask_tにビットマップとして設定されるわけです。

struct nodemask_tはstruct { DECLARE_BITMAP(bits, MAX_NUMNODES); }して定義され、要はstruct { unsigned long bits[hoge]; }の単純な構造体です。hogeはノード数に対応した配列数で、longを4バイトとすると、ノード数が30ならbit[1]、ノード数が40ならbit[2]となるわけですが、それをコンパイル時は可変値となる一定値のノード数と言うことで、マクロのみでの実装故、以下のような難しげなコードとなっています。
struct pglist_data *node_data[MAX_NUMNODES];

typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t;

#define DECLARE_BITMAP(name,bits) \
       unsigned long name[BITS_TO_LONGS(bits)]
BITS_TO_LONGS(bits)でノード数となるbitsに応じた配列数を求めます。BITS_PER_BYTE * sizeof(long)は配列1つで格納できるノード数です。
#define BITS_PER_BYTE           8
#define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
DIV_ROUND_UPで配列数を算出します。dは1配列に設定できるノード数で、longを4バイトとすると8×4=32です。要はn/d+(n%d?1: 0)ということです。
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
CONFIG_NODES_SHIFTはカーネルコンパイルオプションで、NODES_SHIFTとなっていますが結果的にノード数になります。1をNODES_SHIFTでシフトする事でMAX_NUMNODESとしているため、NODES_SHIFT=1だとノード数は2で、CONFIG_NODES_SHIFTでない場合、NODES_SHIFT=0でノード数は1となります。
#ifdef CONFIG_NODES_SHIFT
#define NODES_SHIFT     CONFIG_NODES_SHIFT
#else
#define NODES_SHIFT     0
#endif

#define MAX_NUMNODES    (1 << NODES_SHIFT)

最終更新 2014/03/01 02:05:47 - north
(2014/03/01 02:05:47 作成)


検索

アクセス数
3694363
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。