第61章 仮想メモリー領域( vm_area_struct )

 仮想メモリー領域( vm_area_struct )オブジェクトはプロセスのユーザー空間スタックであったり、メモリーマッピングしたファイルに該当するオブジェクトです。

// /usr/src/linux-headers-4.18.16-041816-generic/include/linux/mm_types.h
264 struct vm_area_struct {
265   /* The first cache line has the info for VMA tree walking. */
266
267   unsigned long vm_start;   /* Our start address within vm_mm. */
268   unsigned long vm_end;   /* The first byte after our end address
269              within vm_mm. */
270
271   /* linked list of VM areas per task, sorted by address */
272   struct vm_area_struct *vm_next, *vm_prev;
273
274   struct rb_node vm_rb;
275
276   /*
277    * Largest free memory gap in bytes to the left of this VMA.
278    * Either between this VMA and vma->vm_prev, or between one of the
279    * VMAs below us in the VMA rbtree and its ->vm_prev. This helps
280    * get_unmapped_area find a free area of the right size.
281    */
282   unsigned long rb_subtree_gap;
283
284   /* Second cache line starts here. */
285
286   struct mm_struct *vm_mm;  /* The address space we belong to. */
287   pgprot_t vm_page_prot;    /* Access permissions of this VMA. */
288   unsigned long vm_flags;   /* Flags, see mm.h. */
289
290   /*
291    * For areas with an address space and backing store,
292    * linkage into the address_space->i_mmap interval tree.
293    */
294   struct {
295     struct rb_node rb;
296     unsigned long rb_subtree_last;
297   } shared;
298
299   /*
300    * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
301    * list, after a COW of one of the file pages.  A MAP_SHARED vma
302    * can only be in the i_mmap tree.  An anonymous MAP_PRIVATE, stack
303    * or brk vma (with NULL file) can only be in an anon_vma list.
304    */
305   struct list_head anon_vma_chain; /* Serialized by mmap_sem &
306             * page_table_lock */
307   struct anon_vma *anon_vma;  /* Serialized by page_table_lock */
308
309   /* Function pointers to deal with this struct. */
310   const struct vm_operations_struct *vm_ops;
311
312   /* Information about our backing store: */
313   unsigned long vm_pgoff;   /* Offset (within vm_file) in PAGE_SIZE
314              units */
315   struct file * vm_file;    /* File we map to (can be NULL). */
316   void * vm_private_data;   /* was vm_pte (shared mem) */
317
318   atomic_long_t swap_readahead_info;
319 #ifndef CONFIG_MMU
320   struct vm_region *vm_region;  /* NOMMU mapping region */
321 #endif
322 #ifdef CONFIG_NUMA
323   struct mempolicy *vm_policy;  /* NUMA policy for the VMA */
324 #endif
325   struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
326 } __randomize_layout;

 メンバーオブジェクト・変数・ポインターの中で特に重要なのが以下です。

vm_start, vm_end
メモリー領域の開始・終端です。 /proc/<pid>/maps でもチェックできます。
vm_file
関連するファイルオブジェクトへのポインターです。
vm_pgoff
ファイル内のオフセットです。
vm_flags
フラグです。
vm_ops
関連する関数です。
vm_next, vm_prev
同プロセスの領域をリスト構造体で連結するポインターです。

 メンバーを見れば分かるように vm_area_struct は連結されています。

 vm_next とか vm_prev どかですね。

 後はファイルイメージのオフセットである vm_pgoff 何かもありますね。

 ファイルオフセットは mmap を使う場合や動的ライブラリを vm_area_struct としてマッピングする場合に必要になるんですが、この辺は図を見たほうが早いと思います。

img/address_space.png

 関連している file があるデータなのであれば、それを指すポインターである vm_file もあります。

 ページキャッシュの情報を抽象化した struct address_space とも繋がっていますよね。

Copyright 2018-2019, by Masaki Komatsu