On Mon, Mar 25, 2013 at 12:16 PM, Rami Rosen <roszenrami@gmail.com> wrote:
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. and I think the memory descriptor would be changed so that it can point to the kernel thread.
Rgs, Rami Rosen http://ramirose.wix.com/ramirosen
On Mon, Mar 25, 2013 at 8:02 AM, anish singh <anish198519851985@gmail.com> wrote:
On Mon, Mar 25, 2013 at 1:35 AM, Rami Rosen <roszenrami@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@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@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies