免费注册 查看新帖 |

Chinaunix

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

[进程管理] [每周一议]linux内核如何统计负载 [复制链接]

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
31 [报告]
发表于 2013-01-23 18:59 |只看该作者
回复 30# T-Bagwell
应该是IO受限导致的负载过高

   

论坛徽章:
0
32 [报告]
发表于 2013-01-23 19:21 |只看该作者
那有个进程cpu利用率90%多,loadagv显示达到7.5(八核的),但stat:S 是什么情况?

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
33 [报告]
发表于 2013-01-23 20:24 |只看该作者
回复 31# 瀚海书香

而且好像D越多,负载越高,负载越高D越多
恶性循环的


   

论坛徽章:
1
天蝎座
日期:2013-12-06 18:23:58
34 [报告]
发表于 2013-01-23 22:01 |只看该作者
负载真心搞不懂

论坛徽章:
0
35 [报告]
发表于 2013-01-23 22:25 |只看该作者
居然有人傻  逼的十分肯定的说永远没有D状态,貌似是被学校的老师给教傻的,还是读代码多实践少?我就遇到过cgroup限制kvm cpu的时候出现了D,当时死活没找到办法干掉这个D状态进程,后来找到了,我想咨询下各位大牛你们遇到D状态的进程是怎么干掉他的呢?

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
36 [报告]
发表于 2013-01-24 07:11 |只看该作者
回复 32# beautifulboylv
但stat:S 是什么情况?

sleep状态,说明进程没事可干
   

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
37 [报告]
发表于 2013-01-24 08:04 |只看该作者
回复 35# itxx
当时死活没找到办法干掉这个D状态进程,后来找到了,我想咨询下各位大牛你们遇到D状态的进程是怎么干掉他的呢?


1.为什么信号不能杀死D状态的进程
内核发送信号唤起进程的流程是:
specific_send_sig_info--->send_signal--->__send_signal--->complete_signal--->signal_wake_up-->wake_up_state
  1. 505 /*                                                                                                            
  2. 506  * Tell a process that it has a new active signal..                                                            
  3. 507  *                                                                                                            
  4. 508  * NOTE! we rely on the previous spin_lock to                                                                  
  5. 509  * lock interrupts for us! We can only be called with                                                         
  6. 510  * "siglock" held, and the local interrupt must                                                               
  7. 511  * have been disabled when that got acquired!                                                                  
  8. 512  *                                                                                                            
  9. 513  * No need to set need_resched since signal event passing                                                      
  10. 514  * goes through ->blocked                                                                                      
  11. 515  */                                                                                                            
  12. 516 void signal_wake_up(struct task_struct *t, int resume)                                                         
  13. 517 {                                                                                                              
  14. 518         unsigned int mask;                                                                                    
  15. 519                                                                                                               
  16. 520         set_tsk_thread_flag(t, TIF_SIGPENDING);                                                               
  17. 521                                                                                                               
  18. 522         /*                                                                                                     
  19. 523          * For SIGKILL, we want to wake it up in the stopped/traced/killable                                   
  20. 524          * case. We don't check t->state here because there is a race with it                                 
  21. 525          * executing another processor and just now entering stopped state.                                    
  22. 526          * By using wake_up_state, we ensure the process will wake up and                                      
  23. 527          * handle its death signal.                                                                           
  24. 528          */                                                                                                   
  25. 529         mask = TASK_INTERRUPTIBLE;                                                                             
  26. 530         if (resume)                                                                                            
  27. 531                 mask |= TASK_WAKEKILL;                                                                        
  28. 532         if (!wake_up_state(t, mask))                                                                           
  29. 533                 kick_process(t);                                                                              
  30. 534 }                                                                                                              
  31. 535   
复制代码
在wake_up_state函数里面,只唤醒处于INTERRUPTIBLE状态的进程,所以处于UNINTERRUPTIBE状态的进程是无法唤醒的。
那么无法唤醒也就意味着不会被调度,不被调度就不会返回到用户态,不反会到用户态就不会处理信号。所以信号对于UNINTERRUPTIBLE(D状态)的进程是无效的。

2.解决方法
目前来说还没有好的解决方案。有些时候只能通过reboot来解决。不过内核已经在考虑如何去掉UNINTERRUPTIBLE状态,用TASK_KILLABLE状态代替。这种状态类似于TASK_UNINTERRUPTIBLE,但是可以处理fatal signals.

参考:
Like most versions of Unix, Linux has two fundamental ways in which a process can be put to sleep. A process which is placed in the TASK_INTERRUPTIBLE state will sleep until either (1) something explicitly wakes it up, or (2) a non-masked signal is received. The TASK_UNINTERRUPTIBLE state, instead, ignores signals; processes in that state will require an explicit wakeup before they can run again.
There are advantages and disadvantages to each type of sleep. Interruptible sleeps enable faster response to signals, but they make the programming harder. Kernel code which uses interruptible sleeps must always check to see whether it woke up as a result of a signal, and, if so, clean up whatever it was doing and return -EINTR back to user space. The user-space side, too, must realize that a system call was interrupted and respond accordingly; not all user-space programmers are known for their diligence in this regard. Making a sleep uninterruptible eliminates these problems, but at the cost of being, well, uninterruptible. If the expected wakeup event does not materialize, the process will wait forever and there is usually nothing that anybody can do about it short of rebooting the system. This is the source of the dreaded, unkillable process which is shown to be in the "D" state by ps.

Given the highly obnoxious nature of unkillable processes, one would think that interruptible sleeps should be used whenever possible. The problem with that idea is that, in many cases, the introduction of interruptible sleeps is likely to lead to application bugs. As recently noted by Alan Cox:

Unix tradition (and thus almost all applications) believe file store writes to be non signal interruptible. It would not be safe or practical to change that guarantee.
So it would seem that we are stuck with the occasional blocked-and-immortal process forever.

Or maybe not. A while back, Matthew Wilcox realized that many of these concerns about application bugs do not really apply if the application is about to be killed anyway. It does not matter if the developer thought about the possibility of an interrupted system call if said system call is doomed to never return to user space. So Matthew created a new sleeping state, called TASK_KILLABLE; it behaves like TASK_UNINTERRUPTIBLE with the exception that fatal signals will interrupt the sleep.

With TASK_KILLABLE comes a new set of primitives for waiting for events and acquiring locks:

        int wait_event_killable(wait_queue_t queue, condition);
        long schedule_timeout_killable(signed long timeout);
        int mutex_lock_killable(struct mutex *lock);
        int wait_for_completion_killable(struct completion *comp);
        int down_killable(struct semaphore *sem);
For each of these functions, the return value will be zero for a normal, successful return, or a negative error code in case of a fatal signal. In the latter case, kernel code should clean up and return, enabling the process to be killed.

The TASK_KILLABLE patch was merged for the 2.6.25 kernel, but that does not mean that the unkillable process problem has gone away. The number of places in the kernel (as of 2.6.26-rc which are actually using this new state is quite small - as in, one need not worry about running out of fingers while counting them. The NFS client code has been converted, which can only be a welcome development. But there are very few other uses of TASK_KILLABLE, and none at all in device drivers, which is often where processes get wedged.

It can take time for a new API to enter widespread use in the kernel, especially when it supplements an existing functionality which works well enough most of the time. Additionally, the benefits of a mass conversion of existing code to killable sleeps are not entirely clear. But there are almost certainly places in the kernel which could be improved by this change, if users and developers could identify the spots where processes get hung. It also makes sense to use killable sleeps in new code unless there is some pressing reason to disallow interruptions altogether.



   

论坛徽章:
2
酉鸡
日期:2013-09-26 11:11:15摩羯座
日期:2014-01-08 13:45:19
38 [报告]
发表于 2013-01-24 10:16 |只看该作者
回复 35# itxx
如果排除代码bug的问题,就只能找到进程处于D状态的原因,让他得到等待的资源才行,否则kill -9 之类的是不行的


   

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
39 [报告]
发表于 2013-01-24 18:43 |只看该作者
创建一个目录, 在里面创建20万个子目录, 然后你继续循环创建, 必须出D.

论坛徽章:
0
40 [报告]
发表于 2013-01-24 23:28 |只看该作者
回复 37# 瀚海书香

我说说我之前遇到D状态的处理办法,虽然当时问题是被处理掉了,但是我似乎还是不知其所以然,希望大牛解释下原理。当时虚拟机进程出现D状态的时候,我没有找到如何满足该进程所需资源的方法,但是我使用了另外一个方法,就是重新启动一个该虚拟机的进程,这个新的进程使用的资源应该是在很多地方和D状态的那个进程一样的资源,相当于这个新的进程强制抢占了D状态进程的资源,就导致D状态的进程被干掉了,新的进程继续跑,但是这里肯定会导致数据丢失的风险存在。求点评。
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP