On Mon, Mar 25, 2013 at 1:35 AM, Rami Rosen <roszenrami@xxxxxxxxx> 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@xxxxxxxxx> 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@xxxxxxxxxxxxxxxxx >> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies >> > > _______________________________________________ > Kernelnewbies mailing list > Kernelnewbies@xxxxxxxxxxxxxxxxx > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies