linux下的use_mm比NT的KeAttachProcess高效的原因

在linux中可以实现进程挂靠,通过use_mm函数可以将当前进程(或线程,linux不区分)的地址空间设置为特定的mm_struct,先不管函 数的形态是否一致,它和windows的KeAttachProcess的作用是一样的,它同样要切换硬件上下文,但是别的方面设置却非常简单。这一切有 一个终极原因和一个辅助原因两个原因:1.linux的全局页目录不和进程挂钩,而是和地址空间挂钩(pgd在mm_struct里而没有在 task_struct里);2.很好的缺页中断处理机制。

这样,我们只需要把要挂靠的进程的mm_struct设置到当前进程的task_struct的mm里面就是了,这样在实际访问时会从mm_struct 里面得到页全局目录,从而访问叶面或处理缺页,而缺页处理也是首先得到当前进程的mm_struct结构从而可以得到pgd,这个设计简直太好了,妙!

不光这里受惠,在进程切换的时候可以首先查看两个task_struct的mm_struct是否一致,一致的话就是线程切换,不切换cr3硬件环境,不同时再切换。

linux这么好的 数据结构设计使得很多操作同时受惠,一脉相承。所以说linux的进程实现既轻量又高效!

static void use_mm(struct mm_struct *mm)

{

struct mm_struct *active_mm;

struct task_struct *tsk = current;

task_lock(tsk);

tsk->flags |= PF_BORROWED_MM;

active_mm = tsk->active_mm;

atomic_inc(&mm->mm_count);

tsk->mm = mm;

tsk->active_mm = mm;

/*

* Note that on UML this *requires* PF_BORROWED_MM to be set, otherwise

* it won't work. Update it accordingly if you change it here

*/

activate_mm(active_mm, mm);

task_unlock(tsk);

mmdrop(active_mm);

}

static void unuse_mm(struct mm_struct *mm)

{

struct task_struct *tsk = current;

task_lock(tsk);

tsk->flags &= ~PF_BORROWED_MM;

tsk->mm = NULL;

/* active_mm is still 'mm' */

enter_lazy_tlb(mm, tsk);

task_unlock(tsk);

}

不过如果你实在看不出这到底比windows好在哪,我就没有办法了,好好感受!这代码多么简洁,如果你还是不明白,那么和KeAttachProcess比较一下吧

你可能感兴趣的:(process)