关于NT内核cancel irp的问题

技术分类: 嵌入式系统  | 2008-04-02
作者:bluehacker

引自EDN博客:bluehacker
NT内核中IRP的cancel是一个复杂的问题,很容易出错导致系统崩溃,ddk中的文档其实对这部分说的很详细,只是需要认真体会,osr网站上以前在NT insider杂志中有过2篇文章研究这个问题,总结这些资料,写个贴子罐水如下:
1.为什么要取消IRP
ddk文档中说的很清楚:"Any driver in which IRPs can be held in a pending state for an indefinite interval must have one or more Cancel routines. For example, a keyboard driver might wait indefinitely for a user to press a key."就是说如果你的驱动对于一些irp可能很长时间得不到完成,需要pending相当长的时间那么你就需要写个cancel例程在适合的时候把这些一直pending的irp取消.最常见的一种情况是:issue(触发)这些irp的线程终止了,而这些irp还没来得及完成,这时候就需要取消这些未完成的irp.
2.NT内核如何cancel irp?
根据nt insider的说法,NT IO manager取消irp的过程分成三步.当一个线程要终止了,内核会调用NtTerminateThread()这个native API处理终止线程的事情.NtTerminateThread()会检查该thread的ETHREAD结构中有一个IrpList域,这个是一个list,连接着所有该线程触发的未完成irp.通过遍历这个链表,对每个未完成的irp调用IoCancelIrp()检查有没有注册cancel例程,如果有运行之,这样就完成了三步曲的第一步.
接着开始cancel irp的第二步:这一步会执行一个等待,等待线程的irplist变成空,这说明所有未完成的irp都被各自的cancel routine处理完了(取消了,并从这个irplist链表中remove掉了),但如果有的驱动程序cancel routine出了问题,不能取消irp,则可能导致线程的irplist永远也不会为空.为了避免这种情况导致的死循环,NT内核做了个限定,如果等待了5分钟这个irplist还没有变空,则认为某些驱动出错了,这种情况下,NT会执行三步曲的第3步.
第3步内核会强行将这些未完成的irp从线程的irplist上remove掉,然后尽可能的释放掉线程占用的资源,最终让这个线程终止,但是这些未完成的irp却不会被释放,它们保存在内存种,这样会导致系统内存资源的减少,这些被irp站用的内存永远不会被释放.
3.什么时候需要编写cancel routine?
(1)ddk document说的很清楚:"if a driver will never queue more IRPs than it can complete in five minutes, it probably does not need a Cancel routine. ".就是说如果一个驱动能保证它的irp总是能及时完成,或者说在短时间内(比较几秒)总是会完成,那么根本不需要编写cancel routine.
(2)即使需要编写cancel routine,也不需要弄很复杂的算法,不需要这个cancel routine的效率有多高,弄个简单的cancel routine足够了,原因是:发生这种必须要取消irp的可能性是很少的,不值得为了这偶尔发生的事情花那么大气力去写一个高效的cancel routine
ddk document中给出了一个指导原则:
"The highest-level driver in a chain of layered drivers must have at least one Cancel routine if it queues IRPs or otherwise holds IRPs in a cancelable state. It can have more than one Cancel routine, if necessary. 

Lower-level drivers in which IRPs can be held in a cancelable state for relatively long intervals also should have one or more Cancel routines. 

If a driver manages its own internal queues of IRPs, it should have a separate Cancel routine for each of its queues. "

0
0
(请您对文章做出评价)
1】【2】【3】【4
加载中

对文章的评论

更多评论

剩余字数:  

相关在线研讨会

我要参加

电路设计中可预测和不可预测问题的调试技术

时间:2008-06-02 10:00:00-12:00:00
简介:在嵌入式系统设计中,经常会出现一些可预测和不可预测的问题或者低概率事件信号。快速有效地发现这些问题需要不同的技术。8月15日…

浏览该文章的用户还看过...

  • 文 章

  • 论 坛

  • 博 客

  • 小 组

设计资源与分销

  • 博客推荐

  • 论坛推荐

  • 在线研讨会