xref: /OK3568_Linux_fs/kernel/Documentation/vm/active_mm.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. _active_mm:
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun=========
4*4882a593SmuzhiyunActive MM
5*4882a593Smuzhiyun=========
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun::
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun List:       linux-kernel
10*4882a593Smuzhiyun Subject:    Re: active_mm
11*4882a593Smuzhiyun From:       Linus Torvalds <torvalds () transmeta ! com>
12*4882a593Smuzhiyun Date:       1999-07-30 21:36:24
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun Cc'd to linux-kernel, because I don't write explanations all that often,
15*4882a593Smuzhiyun and when I do I feel better about more people reading them.
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun On Fri, 30 Jul 1999, David Mosberger wrote:
18*4882a593Smuzhiyun >
19*4882a593Smuzhiyun > Is there a brief description someplace on how "mm" vs. "active_mm" in
20*4882a593Smuzhiyun > the task_struct are supposed to be used?  (My apologies if this was
21*4882a593Smuzhiyun > discussed on the mailing lists---I just returned from vacation and
22*4882a593Smuzhiyun > wasn't able to follow linux-kernel for a while).
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun Basically, the new setup is:
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun  - we have "real address spaces" and "anonymous address spaces". The
27*4882a593Smuzhiyun    difference is that an anonymous address space doesn't care about the
28*4882a593Smuzhiyun    user-level page tables at all, so when we do a context switch into an
29*4882a593Smuzhiyun    anonymous address space we just leave the previous address space
30*4882a593Smuzhiyun    active.
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun    The obvious use for a "anonymous address space" is any thread that
33*4882a593Smuzhiyun    doesn't need any user mappings - all kernel threads basically fall into
34*4882a593Smuzhiyun    this category, but even "real" threads can temporarily say that for
35*4882a593Smuzhiyun    some amount of time they are not going to be interested in user space,
36*4882a593Smuzhiyun    and that the scheduler might as well try to avoid wasting time on
37*4882a593Smuzhiyun    switching the VM state around. Currently only the old-style bdflush
38*4882a593Smuzhiyun    sync does that.
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun  - "tsk->mm" points to the "real address space". For an anonymous process,
41*4882a593Smuzhiyun    tsk->mm will be NULL, for the logical reason that an anonymous process
42*4882a593Smuzhiyun    really doesn't _have_ a real address space at all.
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun  - however, we obviously need to keep track of which address space we
45*4882a593Smuzhiyun    "stole" for such an anonymous user. For that, we have "tsk->active_mm",
46*4882a593Smuzhiyun    which shows what the currently active address space is.
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun    The rule is that for a process with a real address space (ie tsk->mm is
49*4882a593Smuzhiyun    non-NULL) the active_mm obviously always has to be the same as the real
50*4882a593Smuzhiyun    one.
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun    For a anonymous process, tsk->mm == NULL, and tsk->active_mm is the
53*4882a593Smuzhiyun    "borrowed" mm while the anonymous process is running. When the
54*4882a593Smuzhiyun    anonymous process gets scheduled away, the borrowed address space is
55*4882a593Smuzhiyun    returned and cleared.
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun To support all that, the "struct mm_struct" now has two counters: a
58*4882a593Smuzhiyun "mm_users" counter that is how many "real address space users" there are,
59*4882a593Smuzhiyun and a "mm_count" counter that is the number of "lazy" users (ie anonymous
60*4882a593Smuzhiyun users) plus one if there are any real users.
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun Usually there is at least one real user, but it could be that the real
63*4882a593Smuzhiyun user exited on another CPU while a lazy user was still active, so you do
64*4882a593Smuzhiyun actually get cases where you have a address space that is _only_ used by
65*4882a593Smuzhiyun lazy users. That is often a short-lived state, because once that thread
66*4882a593Smuzhiyun gets scheduled away in favour of a real thread, the "zombie" mm gets
67*4882a593Smuzhiyun released because "mm_count" becomes zero.
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun Also, a new rule is that _nobody_ ever has "init_mm" as a real MM any
70*4882a593Smuzhiyun more. "init_mm" should be considered just a "lazy context when no other
71*4882a593Smuzhiyun context is available", and in fact it is mainly used just at bootup when
72*4882a593Smuzhiyun no real VM has yet been created. So code that used to check
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun 	if (current->mm == &init_mm)
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun should generally just do
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun 	if (!current->mm)
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun instead (which makes more sense anyway - the test is basically one of "do
81*4882a593Smuzhiyun we have a user context", and is generally done by the page fault handler
82*4882a593Smuzhiyun and things like that).
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun Anyway, I put a pre-patch-2.3.13-1 on ftp.kernel.org just a moment ago,
85*4882a593Smuzhiyun because it slightly changes the interfaces to accommodate the alpha (who
86*4882a593Smuzhiyun would have thought it, but the alpha actually ends up having one of the
87*4882a593Smuzhiyun ugliest context switch codes - unlike the other architectures where the MM
88*4882a593Smuzhiyun and register state is separate, the alpha PALcode joins the two, and you
89*4882a593Smuzhiyun need to switch both together).
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun (From http://marc.info/?l=linux-kernel&m=93337278602211&w=2)
92