Linux内存描述符mm_struct实例详解(含图文说明)

本文详细探讨了Linux操作系统中进程虚拟地址空间的管理机制。通过分析2.6.32.60版本内核代码,文章揭示了task_struct和mm_struct数据结构在内存管理中的作用,特别是mm_struct如何抽象并描述进程地址空间的关键信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:https://www.jb51.net/article/123056.htm

Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起。(所依据的代码是2.6.32.60)

无论是内核线程还是用户进程,对于内核来说,无非都是task_struct这个数据结构的一个实例而已,task_struct被称为进程描述符(process descriptor),因为它记录了这个进程所有的context。其中有一个被称为'内存描述符‘(memory descriptor)的数据结构mm_struct,抽象并描述了Linux视角下管理进程地址空间的所有信息。

mm_struct定义在include/linux/mm_types.h中,其中的域抽象了进程的地址空间,如下图所示:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

struct mm_struct {

  struct vm_area_struct * mmap;  //指向虚拟区间(VMA)的链表

  struct rb_root mm_rb;      //指向线性区对象红黑树的根

  struct vm_area_struct * mmap_cache;   //指向最近找到的虚拟区间

  unsigned long(*get_unmapped_area) (struct file *filp,

  unsigned long addr, unsigned long len,

  unsigned long pgoff, unsigned long flags);//在进程地址空间中搜索有效线性地址区

  unsigned long(*get_unmapped_exec_area) (struct file *filp,

    unsigned long addr, unsigned long len,

    unsigned long pgoff, unsigned long flags);

  void(*unmap_area) (struct mm_struct *mm, unsigned long addr);//释放线性地址区间时调用的方法

  unsigned long mmap_base;        /* base of mmap area */

  unsigned long task_size;        /* size of task vm space */

  unsigned long cached_hole_size;

  unsigned long free_area_cache;     //内核从这个地址开始搜索进程地址空间中线性地址的空闲区域

  pgd_t * pgd;              //指向页全局目录

  atomic_t mm_users;           //次使用计数器,使用这块空间的个数 

  atomic_t mm_count;           //主使用计数器

  int map_count;             //线性的个数

  struct rw_semaphore mmap_sem;      //线性区的读/写信号量

  spinlock_t page_table_lock;       //线性区的自旋锁和页表的自旋锁

  struct list_head mmlist;       //指向内存描述符链表中的相邻元素

  /* Special counters, in some configurations protected by the

  * page_table_lock, in other configurations by being atomic.

  */

  mm_counter_t _file_rss; //mm_counter_t代表的类型实际是typedef atomic_long_t

  mm_counter_t _anon_rss;

  mm_counter_t _swap_usage;

  unsigned long hiwater_rss;  //进程所拥有的最大页框数

  unsigned long hiwater_vm;   //进程线性区中最大页数

  unsigned long total_vm, locked_vm, shared_vm, exec_vm;

  //total_vm 进程地址空间的大小(页数)

  //locked_vm 锁住而不能换出的页的个数

  //shared_vm 共享文件内存映射中的页数

  unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;

  //stack_vm 用户堆栈中的页数

  //reserved_vm 在保留区中的页数或者在特殊线性区中的页数

  //def_flags 线性区默认的访问标志

  //nr_ptes 进程的页表数

  unsigned long start_code, end_code, start_data, end_data;

  //start_code 可执行代码的起始地址

  //end_code 可执行代码的最后地址

  //start_data已初始化数据的起始地址

  // end_data已初始化数据的最后地址

  unsigned long start_brk, brk, start_stack;

  //start_stack堆的起始位置

  //brk堆的当前的最后地址

  //用户堆栈的起始地址

  unsigned long arg_start, arg_end, env_start, env_end;

  //arg_start 命令行参数的起始地址

  //arg_end命令行参数的起始地址

  //env_start环境变量的起始地址

  //env_end环境变量的最后地址

  unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */

  struct linux_binfmt *binfmt;

  cpumask_t cpu_vm_mask; //用于惰性TLB交换的位掩码

  /* Architecture-specific MM context */

  mm_context_t context; //指向有关特定结构体系信息的表

  unsigned int faultstamp;

  unsigned int token_priority;

  unsigned int last_interval;

  unsigned long flags; /* Must use atomic bitops to access the bits */

  struct core_state *core_state; /* coredumping support */

#ifdef CONFIG_AIO

  spinlock_t       ioctx_lock; //用于保护异步I/O上下文链表的锁

  struct hlist_head    ioctx_list;//异步I/O上下文

#endif

#ifdef CONFIG_MM_OWNER

  struct task_struct *owner;

#endif

#ifdef CONFIG_PROC_FS

  unsigned long num_exe_file_vmas;

#endif

#ifdef CONFIG_MMU_NOTIFIER

  struct mmu_notifier_mm *mmu_notifier_mm;

#endif

#ifdef CONFIG_TRANSPARENT_HUGEPAGE

  pgtable_t pmd_huge_pte; /* protected by page_table_lock */

#endif

#ifdef __GENKSYMS__

  unsigned long rh_reserved[2];

#else

  //有多少任务分享这个mm OOM_DISABLE

  union {

    unsigned long rh_reserved_aux;

    atomic_t oom_disable_count;

  };

  /* base of lib map area (ASCII armour) */

  unsigned long shlib_base;

#endif

};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值