mm_release();
if (mm) {
atomic_inc(&mm->mm_count);
if (mm != tsk->active_mm) BUG();
/* more a memory barrier than a real lock */
task_lock(tsk);
tsk->mm = NULL;
task_unlock(tsk);
enter_lazy_tlb(mm, current, smp_processor_id());
mmput(mm);
}
}
271/*
272 * We can use these to temporarily drop into
273 * "lazy TLB" mode and back.
274 */
275struct mm_struct * start_lazy_tlb(void)
276{
277 struct mm_struct *mm = current->mm;
278 current->mm = NULL;
279 /* active_mm is still 'mm' */
280 atomic_inc(&mm->mm_count); // 如出一辄
281 enter_lazy_tlb(mm, current, smp_processor_id());
282 return mm;
283}
284
285void end_lazy_tlb(struct mm_struct *mm)
286{
287 struct mm_struct *active_mm = current->active_mm;
288
289 current->mm = mm;
290 if (mm != active_mm) {
291 current->active_mm = mm;
292 activate_mm(active_mm, mm);
293 }
294 mmdrop(active_mm); //对应的释放
295}
296 作者: zylthinking 时间: 2011-11-18 16:53
明白了, 和 lazy tlb 没太大关系, 我还不明白这玩艺呢
保留active_mm 的原因在于调度时需要, 因此这玩艺至少要保留到调度后。
615 /*
616 * there are 3 processes which are affected by a context switch:
617 *
618 * prev == .... ==> (last => next)
619 *
620 * It's the 'much more previous' 'prev' that is on next's stack,
621 * but prev is set to (the just run) 'last' process by switch_to().
622 * This might sound slightly confusing but makes tons of sense.
623 */
624 prepare_to_switch();
625 {
626 struct mm_struct *mm = next->mm;
627 struct mm_struct *oldmm = prev->active_mm;
628 if (!mm) {
629 if (next->active_mm) BUG();
630 next->active_mm = oldmm;
631 atomic_inc(&oldmm->mm_count);
632 enter_lazy_tlb(oldmm, next, this_cpu);
633 } else {
634 if (next->active_mm != mm) BUG();
635 switch_mm(oldmm, mm, next, this_cpu);
636 }
637
638 if (!prev->mm) { // 释放地
639 prev->active_mm = NULL;
640 mmdrop(oldmm);
641 }
642 }
643
644 /*