Hi, Regarding your question about the previous thread: Think of a context switch, let's say between a userspace process and a kernel thread. A context switch is done between two processes (processes are represented by struct task_struct). So when you look at context_switch() prototype, you see: context_switch(struct rq *rq, struct task_struct *prev, ...) and prev is the process which ran in the run_queue of the scheduler previously, before switching to the new kernel thread. And we borrow memory descriptor from this process. Rgs, Rami Rosen http://ramirose.wix.com/ramirosen On Mon, Mar 25, 2013 at 8:02 AM, anish singh <anish198519851985@xxxxxxxxx> wrote: > 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