1*ee65728eSMike Rapoport.. include:: ../disclaimer-zh_CN.rst 2*ee65728eSMike Rapoport 3*ee65728eSMike Rapoport:Original: Documentation/mm/active_mm.rst 4*ee65728eSMike Rapoport 5*ee65728eSMike Rapoport:翻译: 6*ee65728eSMike Rapoport 7*ee65728eSMike Rapoport 司延腾 Yanteng Si <siyanteng@loongson.cn> 8*ee65728eSMike Rapoport 9*ee65728eSMike Rapoport:校译: 10*ee65728eSMike Rapoport 11*ee65728eSMike Rapoport 12*ee65728eSMike Rapoport========= 13*ee65728eSMike RapoportActive MM 14*ee65728eSMike Rapoport========= 15*ee65728eSMike Rapoport 16*ee65728eSMike Rapoport这是一封linux之父回复开发者的一封邮件,所以翻译时我尽量保持邮件格式的完整。 17*ee65728eSMike Rapoport 18*ee65728eSMike Rapoport:: 19*ee65728eSMike Rapoport 20*ee65728eSMike Rapoport List: linux-kernel 21*ee65728eSMike Rapoport Subject: Re: active_mm 22*ee65728eSMike Rapoport From: Linus Torvalds <torvalds () transmeta ! com> 23*ee65728eSMike Rapoport Date: 1999-07-30 21:36:24 24*ee65728eSMike Rapoport 25*ee65728eSMike Rapoport 因为我并不经常写解释,所以已经抄送到linux-kernel邮件列表,而当我做这些, 26*ee65728eSMike Rapoport 且更多的人在阅读它们时,我觉得棒极了。 27*ee65728eSMike Rapoport 28*ee65728eSMike Rapoport 1999年7月30日 星期五, David Mosberger 写道: 29*ee65728eSMike Rapoport > 30*ee65728eSMike Rapoport > 是否有一个简短的描述,说明task_struct中的 31*ee65728eSMike Rapoport > "mm" 和 "active_mm"应该如何使用? (如果 32*ee65728eSMike Rapoport > 这个问题在邮件列表中讨论过,我表示歉意--我刚 33*ee65728eSMike Rapoport > 刚度假回来,有一段时间没能关注linux-kernel了)。 34*ee65728eSMike Rapoport 35*ee65728eSMike Rapoport 基本上,新的设定是: 36*ee65728eSMike Rapoport 37*ee65728eSMike Rapoport - 我们有“真实地址空间”和“匿名地址空间”。区别在于,匿名地址空间根本不关心用 38*ee65728eSMike Rapoport 户级页表,所以当我们做上下文切换到匿名地址空间时,我们只是让以前的地址空间 39*ee65728eSMike Rapoport 处于活动状态。 40*ee65728eSMike Rapoport 41*ee65728eSMike Rapoport 一个“匿名地址空间”的明显用途是任何不需要任何用户映射的线程--所有的内核线 42*ee65728eSMike Rapoport 程基本上都属于这一类,但即使是“真正的”线程也可以暂时说在一定时间内它们不 43*ee65728eSMike Rapoport 会对用户空间感兴趣,调度器不妨试着避免在切换VM状态上浪费时间。目前只有老 44*ee65728eSMike Rapoport 式的bdflush sync能做到这一点。 45*ee65728eSMike Rapoport 46*ee65728eSMike Rapoport - “tsk->mm” 指向 “真实地址空间”。对于一个匿名进程来说,tsk->mm将是NULL, 47*ee65728eSMike Rapoport 其逻辑原因是匿名进程实际上根本就 “没有” 真正的地址空间。 48*ee65728eSMike Rapoport 49*ee65728eSMike Rapoport - 然而,我们显然需要跟踪我们为这样的匿名用户“偷用”了哪个地址空间。为此,我们 50*ee65728eSMike Rapoport 有 “tsk->active_mm”,它显示了当前活动的地址空间是什么。 51*ee65728eSMike Rapoport 52*ee65728eSMike Rapoport 规则是,对于一个有真实地址空间的进程(即tsk->mm是 non-NULL),active_mm 53*ee65728eSMike Rapoport 显然必须与真实的mm相同。 54*ee65728eSMike Rapoport 55*ee65728eSMike Rapoport 对于一个匿名进程,tsk->mm == NULL,而tsk->active_mm是匿名进程运行时 56*ee65728eSMike Rapoport “借用”的mm。当匿名进程被调度走时,借用的地址空间被返回并清除。 57*ee65728eSMike Rapoport 58*ee65728eSMike Rapoport 为了支持所有这些,“struct mm_struct”现在有两个计数器:一个是 “mm_users” 59*ee65728eSMike Rapoport 计数器,即有多少 “真正的地址空间用户”,另一个是 “mm_count”计数器,即 “lazy” 60*ee65728eSMike Rapoport 用户(即匿名用户)的数量,如果有任何真正的用户,则加1。 61*ee65728eSMike Rapoport 62*ee65728eSMike Rapoport 通常情况下,至少有一个真正的用户,但也可能是真正的用户在另一个CPU上退出,而 63*ee65728eSMike Rapoport 一个lazy的用户仍在活动,所以你实际上得到的情况是,你有一个地址空间 **只** 64*ee65728eSMike Rapoport 被lazy的用户使用。这通常是一个短暂的生命周期状态,因为一旦这个线程被安排给一 65*ee65728eSMike Rapoport 个真正的线程,这个 “僵尸” mm就会被释放,因为 “mm_count”变成了零。 66*ee65728eSMike Rapoport 67*ee65728eSMike Rapoport 另外,一个新的规则是,**没有人** 再把 “init_mm” 作为一个真正的MM了。 68*ee65728eSMike Rapoport “init_mm”应该被认为只是一个 “没有其他上下文时的lazy上下文”,事实上,它主 69*ee65728eSMike Rapoport 要是在启动时使用,当时还没有真正的VM被创建。因此,用来检查的代码 70*ee65728eSMike Rapoport 71*ee65728eSMike Rapoport if (current->mm == &init_mm) 72*ee65728eSMike Rapoport 73*ee65728eSMike Rapoport 一般来说,应该用 74*ee65728eSMike Rapoport 75*ee65728eSMike Rapoport if (!current->mm) 76*ee65728eSMike Rapoport 77*ee65728eSMike Rapoport 取代上面的写法(这更有意义--测试基本上是 “我们是否有一个用户环境”,并且通常 78*ee65728eSMike Rapoport 由缺页异常处理程序和类似的东西来完成)。 79*ee65728eSMike Rapoport 80*ee65728eSMike Rapoport 总之,我刚才在ftp.kernel.org上放了一个pre-patch-2.3.13-1,因为它稍微改 81*ee65728eSMike Rapoport 变了接口以适配alpha(谁会想到呢,但alpha体系结构上下文切换代码实际上最终是 82*ee65728eSMike Rapoport 最丑陋的之一--不像其他架构的MM和寄存器状态是分开的,alpha的PALcode将两者 83*ee65728eSMike Rapoport 连接起来,你需要同时切换两者)。 84*ee65728eSMike Rapoport 85*ee65728eSMike Rapoport (文档来源 http://marc.info/?l=linux-kernel&m=93337278602211&w=2) 86