プロセス毎のswap使用量を計測するパッチを読む その1

「show per-process swap usage via procfs」の続き。パッチの内容を追っていきながら、kernelのソースコードを読んでみたいと思います。

パッチエントリ

mm_types.h

Index: mm-test-kernel/include/linux/mm_types.h
===================================================================
--- mm-test-kernel.orig/include/linux/mm_types.h
+++ mm-test-kernel/include/linux/mm_types.h
@@ -228,6 +228,7 @@ struct mm_struct {
         */
        mm_counter_t _file_rss;
        mm_counter_t _anon_rss;
+       mm_counter_t _swap_usage;

        unsigned long hiwater_rss;      /* High-watermark of RSS usage */
        unsigned long hiwater_vm;       /* High-water virtual memory usage */ 

mm_struct構造体

このパッチエントリはmm_struct構造体にswapの使用量をカウントする_swap_usageを追加しています。mm_struct構造体はLinuxのプロセス空間を管理する構造体で、1プロセス毎に作成されます。

mm_counter_tはrssやswapの使用量(カウンタ)を表します。実体はunsigned longもしくはatomic_long_tという型になります。どちらの型が使用されるかは、「NR_CPUS」と「CONFIG_SPLIT_PTLOCK_CPUS」の値によって決まります。
include/linux/mm_types.h

#define USE_SPLIT_PTLOCKS       (NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS)

#if USE_SPLIT_PTLOCKS
=>pedef atomic_long_t mm_counter_t;
#else  /* !USE_SPLIT_PTLOCKS */
typedef unsigned long mm_counter_t;
#endif /* !USE_SPLIT_PTLOCKS */

NR_CPUS

プロセッサ数の最大値で、make configを実行すると生成されるinclude/linux/autoconf.hで定義されるCONFIG_NR_CPUSの値です。
include/linux/threads.h

/*                                                                           
 * Maximum supported processors.  Setting this smaller saves quite a         
 * bit of memory.  Use nr_cpu_ids instead of this except for static bitmaps. */
#ifndef CONFIG_NR_CPUS
/* FIXME: This should be fixed in the arch's Kconfig */
#define CONFIG_NR_CPUS  1
#endif

/* Places which use this should consider cpumask_var_t. */
#define NR_CPUS         CONFIG_NR_CPUS

#define MIN_THREADS_LEFT_FOR_ROOT 4

include/linux/autoconf.h

=>efine CONFIG_NR_CPUS 8

「CONFIG_SPLIT_PTLOCK_CPUS」もautoconf.hで定義されていました。

=>efine CONFIG_SPLIT_PTLOCK_CPUS 4

コメントがないのでどんな意味なのかわかりません。ページテーブルのロックに関係することかな?「NR_CPUS > CONFIG_SPLIT_PTLOCK_CPUS」がtrueなので、mm_counter_tの型はatomic_long_tとなります。ちなみにatomic_long_tは、32/64bitで実際に定義される型が異なります。
include/linux/atomic-long.h

if BITS_PER_LONG == 64

typedef atomic64_t atomic_long_t;
...
#else  /*  BITS_PER_LONG == 64  */

typedef atomic_t atomic_long_t;
...

このマシンは32bitなので、実際にはmm_counter_tの型はatomic_cとなります。そのatomic_tは次のように定義されています。
include/linux/types.h

typedef struct {
        volatile int counter;
=>atomic_t;

以上より、swapの使用量をカウントする際に使用される型は「volatile int」でした。

参考文献:

Linuxカーネル2.6解読室
Linuxカーネル2.6解読室
ソフトバンククリエイティブ 2006-11-18
売り上げランキング : 63555

おすすめ平均 star
starLinuxカーネル全般についてじっくり学べる
starこれを理解できなくてもがっかりするな
star細かい割りに、肝心な疑問点がわからない

Amazonで詳しく見る
by G-Tools