- 论坛徽章:
- 11
|
因为下面要对该结构体操作,防止操作的过程中其他内核路径将该结构体释放了。mmput又会对mm_count减1
flikelinux 发表于 2011-11-18 15:36 ![]()
单说一个普通情况, mm->count 和 mm->user_count 都是1, 这个是 allocate_mm 中设置的。
mm->count 和 mm->user_count 区别在于无论 mm->user_count 是多大, 都只是对应一个 mm->count.
因此, fork 的时候, 增加了 mm->user_count 却仍然保持 mm->count 为原值。
换句话说, mm->user_count记录的是有几个 task->mm 引用了这个 mm, 只要被任意一个引用, 则 mm->count 值至少为1
mm->count 变化发生与除此之外的其他引用中, 比如 switch 中被暂借到 active_mm 时;
因此,
230static int exec_mmap(void)
231{
232 struct mm_struct * mm, * old_mm;
233
234 old_mm = current->mm;
235 if (old_mm && atomic_read(&old_mm->mm_users) == 1) {
236 flush_cache_mm(old_mm);
237 mm_release();
238 exit_mmap(old_mm);
239 flush_tlb_mm(old_mm);
240 return 0;
241 }
242
243 mm = mm_alloc();
244 if (mm) {
245 struct mm_struct *active_mm = current->active_mm;
246
247 current->mm = mm;
248 current->active_mm = mm;
249 activate_mm(active_mm, mm);
250 mm_release();
251 if (old_mm) {
252 if (active_mm != old_mm) BUG();
253 mmput(old_mm); // 这里只需要 mmput 即可, 因为 active_mm 是本身, 在 switch 时直接赋值而没有增加 mm->count, mm->count, mm->user_count 都是1
254 return 0;
255 }
256 mmdrop(active_mm); // 而这里, 确实暂借的, mm_count 被增加了; 需要额外释放
257 return 0;
258 }
259 return -ENOMEM;
260}
261
因此, 你那种解释是肤浅的 |
|