设为首页 加入收藏

TOP

oom killer(六)
2019-09-01 23:08:40 】 浏览:122
Tags:oom killer
_task_struct(p); return; } if (__ratelimit(&oom_rs)) dump_header(p, gfp_mask, order, memcg, nodemask); task_lock(p); pr_err("%s: Kill process %d (%s) score %d or sacrifice child\n", message, task_pid_nr(p), p->comm, points); task_unlock(p); /* * If any of p's children has a different mm and is eligible for kill, * the one with the highest oom_badness() score is sacrificed for its * parent. This attempts to lose the minimal amount of work done while * still freeing memory. */ read_lock(&tasklist_lock); for_each_thread(p, t) { list_for_each_entry(child, &t->children, sibling) { unsigned int child_points; if (child->mm == p->mm) continue; /* * oom_badness() returns 0 if the thread is unkillable */ child_points = oom_badness(child, memcg, nodemask, totalpages); if (child_points > victim_points) { put_task_struct(victim); victim = child; victim_points = child_points; get_task_struct(victim); } } } read_unlock(&tasklist_lock); p = find_lock_task_mm(victim); if (!p) { put_task_struct(victim); return; } else if (victim != p) { get_task_struct(p); put_task_struct(victim); victim = p; } /* mm cannot safely be dereferenced after task_unlock(victim) */ mm = victim->mm; pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n", task_pid_nr(victim), victim->comm, K(victim->mm->total_vm), K(get_mm_counter(victim->mm, MM_ANONPAGES)), K(get_mm_counter(victim->mm, MM_FILEPAGES))); task_unlock(victim); /* * Kill all user processes sharing victim->mm in other thread groups, if * any. They don't get access to memory reserves, though, to avoid * depletion of all memory. This prevents mm->mmap_sem livelock when an * oom killed thread cannot exit because it requires the semaphore and * its contended by another thread trying to allocate memory itself. * That thread will now get access to memory reserves since it has a * pending fatal signal. */ rcu_read_lock(); for_each_process(p) if (p->mm == mm && !same_thread_group(p, victim) && !(p->flags & PF_KTHREAD)) { if (p->signal->oom_score_adj == OOM_SCORE_ADJ_MIN) continue; task_lock(p); /* Protect ->comm from prctl() */ pr_err("Kill process %d (%s) sharing same memory\n", task_pid_nr(p), p->comm); task_unlock(p); do_send_sig_info(SIGKILL, SEND_SIG_FORCED, p, true); } rcu_read_unlock(); set_tsk_thread_flag(victim, TIF_MEMDIE); do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true); put_task_struct(victim); }

该函数将会判断当前被kill的进程情况,如果该进程处于退出状态,则设置TIF_MEMDIE标志,不做kill操作;接着会通过list_for_each_entry()遍历该进程的子进程信息,如果某个子进程拥有不同的mm且合适被kill掉,将会优先考虑将该子进程替代父进程kill掉,这样可以避免kill掉父进程带来的接管子进程的工作开销;再往下通过find_lock_task_mm()找到持有mm锁的进程,如果进程处于退出状态,则return,否则继续处理,若此时的进程与传入的不是同一个时则更新victim;继而接着通过for_each_process()查找与当前被kill进程使用到了同样的共享内存的进程进行一起kill掉,kill之前将对应的进程添加标识TIF_MEMDIE,而kill的动作则是通过发送SICKILL信号给对应进程,由被kill进程从内核态返回用户态时进行处理。

至此,OOM kill处理分析完毕。

首页 上一页 3 4 5 6 下一页 尾页 6/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Linux 匿名页的反向映射 下一篇在keil中添加stc系列单片机型号(..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目