免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: bfdhczw
打印 上一主题 下一主题

[内存管理] 【求助】OOM的时候kill进程失败 [复制链接]

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
11 [报告]
发表于 2015-12-21 16:43 |只看该作者
还是由等待的事件源来wakeup要安全一些。

这种情况下,倒不如想办法终止或减少磁盘IO的频率?

论坛徽章:
2
2015年亚洲杯之乌兹别克斯坦
日期:2015-04-15 15:43:482015亚冠之迪拜阿赫利
日期:2015-06-30 20:36:46
12 [报告]
发表于 2015-12-21 17:20 |只看该作者
回复 11# nswcfd


    我也想等到事件来源,但是现在系统已经不调度了,几乎是卡死状态,没法等到事件来源。
减少磁盘操作是不可能的,原因有两个
其一,这个进程的源码不在我们手上,
其二,这个进程本身是个下载器,不操作磁盘不可能。

所以,我现在期望能达到的最好效果就是,OOM的时候kill这个进程,保证系统不被卡死。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
13 [报告]
发表于 2015-12-22 16:10 |只看该作者
11楼表达的不准确,意思是接管内核的disk io入口(hack/hack/hack),替换成空操作,避免新的io操作产生。
这样,旧的请求才能及时被旧的io模块满足,产生wakeup调用,进程才能结束D状态。

当然,也可以去模拟disk io的complete事件,终极目标是触发wakeup。
不太建议绕过io系统去直接wakeup处于D状态的进程,除非先cancel掉原来的wait。

不建议的原因是出于稳定性考虑。
waitq通常位于等待进程的stack上(类似DEFINE_WAIT),如果自行把进程wakeup,则进程会继续执行。
像楼主的例子,就响应OOM的kill signal结束进程了。
但是io子系统不知道这些事情,当事件完成后,依然会调用wakeup,去修改waitq的状态。
这时候就不知道会touch到谁的内存了。

论坛徽章:
2
2015年亚洲杯之乌兹别克斯坦
日期:2015-04-15 15:43:482015亚冠之迪拜阿赫利
日期:2015-06-30 20:36:46
14 [报告]
发表于 2015-12-24 15:04 |只看该作者
回复 13# nswcfd


    我是这样做的,直接active,但还是杀不掉
  1. int kill_etm(void)
  2. {
  3.         int ret = 0;
  4.         struct task_struct *p;

  5.         read_lock(&tasklist_lock);
  6.         for_each_process(p){
  7.                 if(!strcmp("my_process_name", p->comm)){
  8.                         oom_kill_task(p, NULL);
  9.                         ret = 1;
  10.                         break;
  11.                 }
  12.         }
  13.         read_unlock(&tasklist_lock);

  14.         if(likely(ret) && likely(p!=current)){
  15.                 printk("%s active %s and schedule()\n", __func__, p->comm);
  16.                 activate_task_priv(p);               
  17.                 schedule_timeout_uninterruptible(HZ>>2);
  18.         }
  19.        
  20.         return ret;
  21. }
复制代码

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
15 [报告]
发表于 2015-12-25 10:37 |只看该作者
不好意思,忽略了一件事情,D状态是不考虑signal的。
  1. #define __wait_event(wq, condition)                                         \
  2. do {                                                                        \
  3.         DEFINE_WAIT(__wait);                                                \
  4.                                                                         \
  5.         for (;;) {                                                        \
  6.                 prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);        \
  7.                 if (condition)                                                \
  8.                         break;                                                \
  9.                 schedule();                                                \
  10.         }                                                                \
  11.         finish_wait(&wq, &__wait);                                        \
  12. } while (0)
复制代码
其中的schedule会被楼主显式的wake_up恢复,但是如果继续检查条件(IO未完成等),还是不满足,继续schedule。
关键还是得破坏(或者说满足)condition条件。

论坛徽章:
2
2015年亚洲杯之乌兹别克斯坦
日期:2015-04-15 15:43:482015亚冠之迪拜阿赫利
日期:2015-06-30 20:36:46
16 [报告]
发表于 2015-12-28 18:18 |只看该作者
回复 15# nswcfd


    D状态不响应signal我是知道的,我理解的不响应只是暂时不响应,信号被挂起而已,等到进程退出D状态的时候,就会响应了。难道我理解错了?

论坛徽章:
2
2015年亚洲杯之乌兹别克斯坦
日期:2015-04-15 15:43:482015亚冠之迪拜阿赫利
日期:2015-06-30 20:36:46
17 [报告]
发表于 2015-12-29 10:35 |只看该作者
本帖最后由 bfdhczw 于 2015-12-29 10:36 编辑

回复 15# nswcfd
  1. #define __wait_event(wq, condition)                                         \
  2. do {                                                                        \
  3.         DEFINE_WAIT(__wait);                                                \
  4.                                                                         \
  5.         for (;;) {                                                        \
  6.                 prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);        \
  7.                 if (condition)                                                \
  8.                         break;                                                \
  9.                 if(current->force_quit)\
  10.                         break;\
  11.                 schedule();                                                \
  12.         }                                                                \
  13.         finish_wait(&wq, &__wait);                                        \
  14.         if(current->force_quit){\
  15.                 printk("=========> force_quit at %s\n", __func__);\
  16.                 force_sig(SIGKILL, current);\
  17.         }\
  18. } while (0)
复制代码
我把代码改成了这样,在task_struct里面加了force_quit成员,看起来wait queue上不会出什么问题,不知道会不会引起其他问题。
目前还没有测试结果,等后面有测试结果了,再继续更新状况。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
18 [报告]
发表于 2015-12-29 11:08 |只看该作者
回复 16# bfdhczw
“退出D状态去响应信号”不会平白无故的发生,一定对应某个kernel code path,比如
1)等待的条件满足,结束wait_event循环,在核心态返回用户态的路径上检查信号处理;
2)像wait_event_interruptible那样,在wait循环里面,每次醒来之后显式的检查是否有信号发生,如果有退出循环,在返回用户态的路径上处理signal。


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP