2.4.0内核中进程的mm_struct释放问题

发布于 2022-07-25 13:31:22 字数 2200 浏览 18 评论 2

进程结束时,要通过do_exit退出系统。do_exit()会调用__exit_mm().以下是__exit_mm()的源代码:

static inline void __exit_mm(struct task_struct * tsk)
{
        struct mm_struct * mm = tsk->mm;

        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);
        }
}

__exit_mm()先调用atomic_inc(&mm->mm_count)使mm->mm_count加1,使其变成2。最后调用mmput(mm)。其代码如下:

void mmput(struct mm_struct *mm)
{
        if (atomic_dec_and_lock(&mm->mm_users, &mmlist_lock)) {
                list_del(&mm->mmlist);
                spin_unlock(&mmlist_lock);
                exit_mmap(mm);
                mmdrop(mm);
        }
}

可见,在mmput()中,mm->mm_users被减到0。可由于在__exit_mm()调用atomic_inc(&mm->mm_count)使mm->mm_count变成了2,因此在mmdrop(mm)中将mm->mm_count减1后,其值不会达到0,故该进程的mm_struct结构不会被释放。而该进程的父进程,只会调用release_task把它的task_struct结构释放掉。这样,这个进程的mm_struct结构的残骸只能永远留在系统中了,因为该进程的task_struct被释放后,已经没有指针指向它的mm_struct了。
        我想我的理解一定有问题,但又不知错在哪,请高人赐教,谢谢!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧人九事 2022-07-27 00:38:08

mm_release() 只是唤醒父进程,没有其他操作

static inline void __exit_mm(struct task_struct * tsk)
{
        struct mm_struct * mm = tsk->mm;

        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);
        }
}

请楼主注意其中的 :  tsk->mm = NULL;

同时本进程既然在运行,那么它必须有一个active_mm,眼下的 tsk->active_mm== tsk->mm

现在要tsk->mm = NULL, 所以必须mm->user--,这就是mmput要做的事;

虽然mmput后,mm->user是减减了,但是本进程的active_mm还是在使用着刚释放的这个mm。

而这个mm又不属于本进程,相当于一个借用的mm,而借用其他mm只能mm->count++

从exit_mm返回后,mm确实没有被释放,但是一旦发生schedule(),可能do_exit本身就会显式调用schedule()。
schedule发现将要切换出去的老进程,是一个本身没有mm,借用其他的mm当作active_mm的进程,会对active_mm执行mmdrop的操作。

春夜浅 2022-07-26 22:00:36

恩,是有些问题。
不过 __exit_mm 中的 mm_release() 调用,会不会已经将mm->count减为0了呢?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文