プロセス毎のswap使用量を計測するパッチを読む その3
「プロセス毎のswap使用量を計測するパッチを読む その2」の続き。
copy_one_pte
copy_one_pte関数は、proc/(PID)/statusに書き込むswapサイズを計測する処理が追加されています。copy_to_pte関数そのものの機能は、あるタスクのvm_areaの1つを別のタスクにコピーする関数です。
copy_to_pte関数の呼び出し元を追いかけていくと、fork処理(do_fork)まで遡ります。fork時にページテーブルをコピーするのでしょう。
fork_idle, do_fork → copy_process → copy_mm → dup_mm → dup_mmap → copy_page_range → copy_pud_range → copy_pmd_range → copy_pte_range → copy_to_pte
最初の部分だけ見てみます。
mm/memory.c
copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, pte_t *dst_pte, pte_t *src_pte, struct vm_area_struct *vma, unsigned long addr, int *rss) { unsigned long vm_flags = vma->vm_flags; pte_t pte = *src_pte; struct page *page; /* pte contains position in swap or file, so copy. */ if (unlikely(!pte_present(pte))) { if (!pte_file(pte)) { swp_entry_t entry = pte_to_swp_entry(pte); swap_duplicate(entry); /* make sure dst_mm is on swapoff's mmlist. */ if (unlikely(list_empty(&dst_mm->mmlist))) { spin_lock(&mmlist_lock); if (list_empty(&dst_mm->mmlist)) list_add(&dst_mm->mmlist, &src_mm->mmlist); spin_unlock(&mmlist_lock); }
pte_t
pte_tの定義は以下のようになっています。このあたりはCPUのアーキテクチャによって異なるので、asm-generic下の定義を貼り付けました。
/usr/src/linux-2.6.32.12/include/asm-generic/page.h
/* * These are used to make use of C type-checking.. */ typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pmd[16]; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; typedef struct page *pgtable_t;
swp_entry_t
swp_entry_tは、スワップ領域上のページを表しているとのこと。
include/linux/swap.h
typedef struct { unsigned long val; =>swp_entry_t;
pte_to_swp_entry
pte_to_swp_entry関数は、アーキテクチャ依存のpteからアーキテクチャ非依存のswp_entry_tに変換するようです。
include/linux/swapops.h
/* * Convert the arch-dependent pte representation of a swp_entry_t into an * arch-independent swp_entry_t. */ static inline swp_entry_t pte_to_swp_entry(pte_t pte) { swp_entry_t arch_entry; BUG_ON(pte_file(pte)); arch_entry = __pte_to_swp_entry(pte); return swp_entry(__swp_type(arch_entry), __swp_offset(arch_entry)); }
swap_info_struct
スワップ領域を管理する構造体。swap_mapメンバがスワップ領域のページの参照カウントを管理しています。
include/linux/swap.h
/* * The in-memory structure used to track swap areas. */ =>ruct swap_info_struct { unsigned long flags; int prio; /* swap priority */ int next; /* next entry on swap list */ struct file *swap_file; struct block_device *bdev; struct list_head extent_list; struct swap_extent *curr_swap_extent; unsigned short *swap_map; unsigned int lowest_bit; unsigned int highest_bit; unsigned int lowest_alloc; /* while preparing discard cluster */ unsigned int highest_alloc; /* while preparing discard cluster */ unsigned int cluster_next; unsigned int cluster_nr; unsigned int pages; unsigned int max; unsigned int inuse_pages; unsigned int old_block_size; };
swap_info_structは、次の箇所で使用されています。
/usr/src/linux-2.6.32.12/mm/swapfile.c
=>atic struct swap_info_struct swap_info[MAX_SWAPFILES];
swap_duplicate
swap_duplicate関数は以下のようにして__swap_duplicate関数を呼び出します。
/* * increase reference count of swap entry by 1. */ void swap_duplicate(swp_entry_t entry) { __swap_duplicate(entry, SWAP_MAP); }
SWAP_MAPは、以下のように定義されていました。
mm/swapfile.c
/* For reference count accounting in swap_map */ /* enum for swap_map[] handling. internal use only */ enum { => SWAP_MAP = 0, /* ops for reference from swap users */ SWAP_CACHE, /* ops for reference from swap cache */ };
「ops for reference from swap users」は何だろう。「from swap cache」ではない、という意味で、一般的なスワップ領域を示すのでしょうか。
__swap_duplicate関数の中でこの値を見て処理が分かれるのですが、SWAP_MAPの場合は指定したswap_entry_tからスワップ領域を管理する構造体swap_infoに変換してスワップ領域のページを特定し、その参照カウントを1増やしていました。
mm_struct.mmlist
コピー先のmm_structのmmlistが空であれば、コピー元のmm_structのmmlistをコピー先のmmlistに追加しています。が、このmmlistメンバの位置づけが良くわかりません。
include/linux/mm_types.h
struct list_head mmlist; /* List of maybe swapped mm's. These are globally strung * together off init_mm.mmlist, and are protected * by mmlist_lock */
『Linuxカーネル解読室』(p218)を見ると、「スワップページありのmm_structリンクリスト用」とあるのですが、意味が良く分からない…。プロセスのページの一部がスワップアウトしたら、そのプロセスのmm_structがmmlistに追加されるのでしょうか。
参考文献:
Linuxカーネル2.6解読室 | |
ソフトバンククリエイティブ 2006-11-18 売り上げランキング : 63555 おすすめ平均 Linuxカーネル全般についてじっくり学べる これを理解できなくてもがっかりするな 細かい割りに、肝心な疑問点がわからない Amazonで詳しく見る by G-Tools |