AW: query about mm_struct

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

> What is the difference between mm_count, mm_users and
> mm_realusers?

> Also what is active_mm and when is it set/cleared and to
> what??

A process address spaces is described by it's memory descriptor
'mm_struct'; mm field in task_struct points to the address of 
this descriptor (task_struct->mm). Only one mm_struct exists for
each process, and (task_struct->active_mm == task_struct->mm) is 
always true. 

Well, I am not 'the' expert in linux memory management, and if 
there is an error in some aspects of my explanation I appreciate
any corrections... but I think what is really used by the Linux
memory management subsystem is the active_mm field, and not the
mm field.

Kernel threads have no user space context/ no own memory areas / 
page tables... and so the task_struct->mm field is always NULL. 

Anyway, no matter if the current task is a kernel thread or an user
space process, Linux expects and requires a memory descriptor for
the current context (e.g. to map it's virtual memory to physical
memory it needs the address of the pgd). Kernel threads borrow the
mm of the previous task and place it in the task_struct->active_mm 
field. (Results in better performance, e.g. just borrowing mm_struct 
instead of carrying out an expensive TLB flush etc...).

Have a look at the source code in kernel/sched.c:
...
673         prepare_to_switch();
674         {
675                 struct mm_struct *mm = next->mm;
676                 struct mm_struct *oldmm = prev->active_mm;
677                 if (!mm) {
678                         if (next->active_mm) BUG();
679                         next->active_mm = oldmm;
680                         atomic_inc(&oldmm->mm_count);
681                         enter_lazy_tlb(oldmm, next, this_cpu);
682                 } else {
683                         if (next->active_mm != mm) BUG();
684                         switch_mm(oldmm, mm, next, this_cpu);
685                 }
686 
687                 if (!prev->mm) {
688                         prev->active_mm = NULL;
689                         mmdrop(oldmm);
690                 }
691         }


As you see, every task has a memory descriptor, but mem. descriptors
can be shared between tasks.

mm_count is a reference counter to the mm. This is important for lazy
TLB
switches where a task may be using one mm_struct TEMPORARILY.

mm_users counts of the number of threads accessing an mm. A cloned
thread
will up this count to make sure an mm_struct() is not destroyed early.
The
swap_out code will increment this count when swapping out portions of
the
mm

Hope this throws a little more light on the usage of memory descriptors.

Thomas

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux