active_mm versus mm in the task_struct
Overview
In sched.h we see that each task has
...
struct list_head tasks;
struct list_head ptrace_children;
struct list_head ptrace_list;
-----> struct mm_struct *mm, *active_mm; <-----
/* task state */
struct linux_binfmt *binfmt;
int exit_code, exit_signal;
int pdeath_signal; /* The signal sent when the parent dies */
/* ??? */
...
Each process clearly has a mm_struct associated with it -- this gives the pages tables for the process. But what good is the active_mm?
Kernel Threads
Kernel threads have no user space context. They have no need for page tables of their own, so don't really need a struct_mm mm allocated. But on the other hand, you want kernel threads to act like normal threads in terms of scheduling, where you obviously need to switch struct_mm mm's when you swap processes. Swapping around this on context switches to kernel threads would be a waste, as it would just be a dummy structure. Thus kernel threads borrow the user space struct_mm mm for their own use.
In the scheduler sched.c
/*
* context_switch - switch to the new MM and the new
* thread's register state.
*/
static inline task_t * context_switch(runqueue_t *rq, task_t *prev, task_t *next)
{
struct mm_struct *mm = next->mm;
struct mm_struct *oldmm = prev->active_mm;
if (unlikely(!mm)) {
next->active_mm = oldmm;
atomic_inc(&oldmm->mm_count);
enter_lazy_tlb(oldmm, next, smp_processor_id());
} else
switch_mm(oldmm, mm, next, smp_processor_id());
if (unlikely(!prev->mm)) {
prev->active_mm = NULL;
WARN_ON(rq->prev_mm);
rq->prev_mm = oldmm;
}
/* Here we just switch the register state and the stack. */
switch_to(prev, next, prev);
return prev;
}
So you can see here that if the task doesn't have an mm if (!mm) we set the active_mm of the process we are about to switch to (the kernel thread) to the old thread's (the user space threads) mm.
If you switch from a kernel thread to a kernel thread you will be OK, because you 'chain' on the active_mm. For user tasks, I think the general rule that active_mm == mm should be true?
Personal Note
This is pretty interesting, but only appears to be intrinsically documented. sigh.
