Why we Use both mm_users and mm_count in struct mm_struct{ }
anish singh
anish198519851985 at gmail.com
Mon Mar 25 02:02:18 EDT 2013
On Mon, Mar 25, 2013 at 1:35 AM, Rami Rosen <roszenrami at gmail.com> wrote:
> Hi, Niroj,
>
> Please look at the following scenario:
> Suppose we create a kernel thread.
> With kernel threads, the mm member of the task_struct is NULL.
> (We are not permitted to access user space addresses from kernel thread,
> so we don't need mm).
> Kernel threads use ("borrow") the active_mm of the previous thread.
as we know that kernel threads are not associated with any user space
process then why this overheads of active_mm or why we borrow the
active_mm of the previous thread.
Can you explain: what is previous thread here?
> But in order to avoid freeing the active_mm if the previous threads terminates
> before the kernel thread terminates, we increment mm_count of the
> active_mm of the previous thread
> when we create a kernel thread (which "borrows" the active_mm of the
> previous thread).
> In such a case, even if the mm_users is 0, mm_count is not 0, and
> we do not free that mm_active.
> (remember that mm_users is initialized to 1).
>
> To be more specific:
> when that previous thread terminates, we call
> the mmput() (see exit_mm(), in kernel/exit.c)
> mmput() decrements mm_users and calls mmdrop().
> Since in mmdrop(), after decrements mm_count it is not 0,
> we do not free the mm_struct.
>
> Here are the code snippets:
>
> /*
> * Decrement the use count and release all resources for an mm.
> */
> void mmput(struct mm_struct *mm)
> {
> might_sleep();
>
> if (atomic_dec_and_test(&mm->mm_users)) {
> uprobe_clear_state(mm);
> exit_aio(mm);
> ksm_exit(mm);
> khugepaged_exit(mm); /* must run before exit_mmap */
> exit_mmap(mm);
> set_mm_exe_file(mm, NULL);
> if (!list_empty(&mm->mmlist)) {
> spin_lock(&mmlist_lock);
> list_del(&mm->mmlist);
> spin_unlock(&mmlist_lock);
> }
> if (mm->binfmt)
> module_put(mm->binfmt->module);
> mmdrop(mm);
> }
> }
>
>
>
> mmdrop() is for freeing a memory descriptor:
>
> static inline void mmdrop(struct mm_struct * mm)
> {
> if (unlikely(atomic_dec_and_test(&mm->mm_count)))
> __mmdrop(mm);
> }
>
>
> When the condition if (!mm) is true, this means this is a kernel thread:
>
> static inline void
> context_switch(struct rq *rq, struct task_struct *prev,
> struct task_struct *next)
> {
> struct mm_struct *mm, *oldmm;
>
> prepare_task_switch(rq, prev, next);
>
> mm = next->mm;
> oldmm = prev->active_mm;
> /*
> * For paravirt, this is coupled with an exit in switch_to to
> * combine the page table reload and the switch backend into
> * one hypercall.
> */
> arch_start_context_switch(prev);
>
> if (!mm) {
> next->active_mm = oldmm;
> atomic_inc(&oldmm->mm_count);
> enter_lazy_tlb(oldmm, next);
> } else
> ...
>
> Regards,
> Rami Rosen
> http://ramirose.wix.com/ramirosen
>
>
>
>
> On Sat, Mar 23, 2013 at 7:02 AM, Niroj Pokhrel <nirojpokhrel at gmail.com> wrote:
>> Hi all,
>> I have been going through the Address Space in the linux and came across two
>> variables in the struct mm_struct and I'm a bit confused about the two:
>> struct mm_struct
>> {
>> ..........
>> atomic_t mm_users;
>> atomic_t mm_count;
>> ............
>> }
>> Basically, after reading through I came to understand that mm_users are used
>> to store the number of processes or threads using the memory so depending
>> upon the number of users it is going to be set.
>> But, I am confused with mm_count, it is said the mm_count is increment by
>> one for all the mm_users and when all the mm_users value is reduced to zero
>> then mm_count is reduced. So, my question is can the value of mm_count be
>> ever greater than one because all the mm_users are equivalent to mm_count .
>> So, if not then why are we using the mm_count as we can simply remove the
>> memory areas whenever the mm_users count reduce to zero.
>> May be the explanation is simple but I'm lost. Thanking all of you in
>> advance.
>>
>>
>> Regards,
>> Niroj Pokhrel
>>
>> _______________________________________________
>> Kernelnewbies mailing list
>> Kernelnewbies at kernelnewbies.org
>> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>>
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
More information about the Kernelnewbies
mailing list