Advanced Debugging
About AdvDbg Consult Train Services Products Tools Community Contact  
欢迎光临 高端调试 登录 | 注册 | FAQ
 
  ACPI调试
Linux内核调试
Windows内核调试
 
  调试战役
调试原理
新工具观察
 
  Linux
Windows Vista
Windows
 
  Linux驱动
WDF
WDM
 
  PCI Express
PCI/PCI-X
USB
无线通信协议
 
  64位CPU
ARM
IA-32
  CPU Info Center
 
  ACPI标准
系统认证
Desktop
服务器
 
  Embedded Linux
嵌入式开发工具
VxWorks
WinCE
嵌入式Windows
 
  格蠹调试套件(GDK)
  格蠹学院
  小朱书店
  老雷的微博
  《软件调试》
  《格蠹汇编》
  《软件调试(第二版)》
沪ICP备11027180号-1

Windows内核调试

帖子发起人: Thomson   发起时间: 2008-09-02 23:35 下午   回复: 8

Print Search
帖子排序:    
   2008-09-02, 23:35 下午
Thomson 离线,最后访问时间: 2013/3/31 11:42:42 Thomson

发帖数前10位
注册: 2008-07-03
发 贴: 211
Confused [*-)] DPC是怎么执行到的呢
Reply Quote
在设备的ISR里面可以扣队一个DPC,让中断时间不至于太长,当IRQL降到DPC level就可以执行.
那么IRQL降低应该只是set KPCR里面的一个变量,是什么机制保证了这个IRQL降低了后,DPC就被执行到呢?
IP 地址: 已记录   报告
   2008-09-03, 08:41 上午
Coding 离线,最后访问时间: 2010/2/20 12:12:52 Coding

发帖数前10位
注册: 2008-05-31
发 贴: 103
Re: DPC是怎么执行到的呢
Reply Quote
简单来说,kernel queues a DPC时,其实是request了一个DISPATCH_LEVEL的软中断,当IRQL降低到小于DISPATCH_LEVEL时,中断被触发,这个中断级别的dispatcher被调用,并且执行在队列里面的每一个DPC object.
IP 地址: 已记录   报告
   2008-09-03, 09:38 上午
WANGyu 离线,最后访问时间: 2012/9/10 3:34:00 王宇

发帖数前10位
男
注册: 2007-05-08
发 贴: 306
Re: DPC是怎么执行到的呢
Reply Quote
很复杂的问题... 我来抛块砖~

我认为具体的实现机制要根据不同的情况讨论,比如:DPC优先级的高低、是否在发出ISR的处理器上、TimerDPC等等。在同一处理器高/中优先级的DPC会直接触发DPC/Dispatch中断(即总是激发);在同一处理器低优先级的DPC需要等待阀值(队列长度);在不同处理器高优先级的DPC,内核会发出IPI通知其他CPU;而TimerDPC则是在nt!KiTimerListExpire()时call你的DPC例程(大致是nt!KiRetireDpcList-->nt!KiTimerExpiration-->nt!KiTimerListExpire()-->你的CustomTimerDPC),等等。

详细的语言描述可以参见Mark E. Russinovich的《Microsoft Windows Internals》3.1节“Trap Dispatching”

DPC priorities can affect system behavior another way. The kernel usually initiates DPC queue draining with a DPC/dispatch-level interrupt. The kernel generates such an interrupt only if the DPC is directed at the processor the ISR is requested on and the DPC has a high or medium priority. If the DPC has a low priority, the kernel requests the interrupt only if the number of outstanding DPC requests for the processor rises above a threshold or if the number of DPCs requested on the processor within a time window is low. If a DPC is targeted at a CPU different from the one on which the ISR is running and the DPC's priority is high, the kernel immediately signals the target CPU (by sending it a dispatch IPI) to drain its DPC queue. If the priority is medium or low, the number of DPCs queued on the target processor must exceed a threshold for the kernel to trigger a DPC/dispatch interrupt. The system idle thread also drains the DPC queue for the processor it runs on. Although DPC targeting and priority levels are flexible, device drivers rarely need to change the default behavior of their DPC objects. Table 3-1 summarizes the situations that initiate DPC queue draining.

特别是表3.1 它总结了DPC/Dispatch中断的产生规则,我这里就不列了。


关于代码实现要参看\ntos\ke\dpcsup.c,重要的有KiExecuteDpc()、KiRetireDpcList() / KiTimerExpiration() / KiTimerListExpire()。

另外要注意,Phase 1 的时候,PspInitPhase0() 创建了线程 Phase1Initialization() 而 Phase1Initialization() call 了 Phase1InitializationDiscard(),Discard里面的一个步骤是:
//
// Initialize OB, EX, KE, and KD.
//

if (!ObInitSystem()) {
KeBugCheck(OBJECT1_INITIALIZATION_FAILED);
}

...

if (!KeInitSystem()) {
KeBugCheckEx(PHASE1_INITIALIZATION_FAILED,STATUS_UNSUCCESSFUL,0,2,0);
}

...

看 KeInitSystem() 的实现:

//
// If threaded DPCs are enabled for the host system, then create a DPC
// thread for each processor.
//
do {
Prcb = KiProcessorBlock[Index];
KeInitializeEvent(&Prcb->DpcEvent, SynchronizationEvent, FALSE);
InitializeListHead(&Prcb->DpcData[DPC_THREADED].DpcListHead);
KeInitializeSpinLock(&Prcb->DpcData[DPC_THREADED].DpcLock);
Prcb->DpcData[DPC_THREADED].DpcQueueDepth = 0;
Status = PsCreateSystemThread(&Handle,
THREAD_ALL_ACCESS,
&ObjectAttributes,
NULL,
NULL,
KiExecuteDpc,
Prcb);

if (!NT_SUCCESS(Status)) {
return FALSE;
}

注意PsCreateSystemThread()创建的KiExecuteDpc()。因为KiExecuteDpc()最后会Call the DPC routine:
//
// Call the DPC routine.
//

(DeferredRoutine)(Dpc,
DeferredContext,
SystemArgument1,
SystemArgument2);


OK~ 先写到这~
IP 地址: 已记录   报告
   2008-09-03, 10:50 上午
Thomson 离线,最后访问时间: 2013/3/31 11:42:42 Thomson

发帖数前10位
注册: 2008-07-03
发 贴: 211
Re: DPC是怎么执行到的呢
Reply Quote
谢谢楼上两位了,

不过我先在System里找start routine是nt!kiexecuteDpc的线程,没有找到,后来在virtual machine里面在nt!kiexecuteDpc上设置 breakpoint,然后启动virtual machine,也没有break到外面的windbg,
我觉得比较奇怪,如果是从这个方法对调用DPC routine的话,应该经常会break才对啊?
IP 地址: 已记录   报告
   2008-09-03, 11:09 上午
WANGyu 离线,最后访问时间: 2012/9/10 3:34:00 王宇

发帖数前10位
男
注册: 2007-05-08
发 贴: 306
Re: DPC是怎么执行到的呢
Reply Quote
这个是2003的代码,您XP的虚拟机吧~
IP 地址: 已记录   报告
   2008-09-03, 11:16 上午
Thomson 离线,最后访问时间: 2013/3/31 11:42:42 Thomson

发帖数前10位
注册: 2008-07-03
发 贴: 211
Re: DPC是怎么执行到的呢
Reply Quote
我是server03的系统,内核是WRK的,
用x能解析到nt!kiexecutedpc
IP 地址: 已记录   报告
   2008-09-03, 12:04 下午
WANGyu 离线,最后访问时间: 2012/9/10 3:34:00 王宇

发帖数前10位
男
注册: 2007-05-08
发 贴: 306
Re: DPC是怎么执行到的呢
Reply Quote
噢 那个是 threaded DPCs,
你实验可能需要下 nt!KiRetireDpcList 的断点。

nt!KiRetireDpcList 的代码片段:
//
// If the DPC list is not empty, then process the DPC list.
//

if (DpcData->DpcQueueDepth != 0) {
........
IP 地址: 已记录   报告
   2008-09-03, 12:11 下午
WANGyu 离线,最后访问时间: 2012/9/10 3:34:00 王宇

发帖数前10位
男
注册: 2007-05-08
发 贴: 306
Re: DPC是怎么执行到的呢
Reply Quote
另,推荐一个DPC实验工具:
http://www.thesycon.de/deu/latency_check.shtml


还有一个微软的文章:
http://www.microsoft.com/whdc/driver/perform/mmdrv.mspx
http://www.microsoft.com/china/whdc/driver/perform/mmdrv.mspx

IP 地址: 已记录   报告
   2008-09-03, 12:35 下午
Raymond 离线,最后访问时间: 2020/7/3 3:40:25 格蠹老雷

发帖数前10位
注册: 2005-12-19
发 贴: 1,303
Re: DPC是怎么执行到的呢
Reply Quote
WinDBG有个扩展命令!dpcs [CPU编号]用来显示DPC队列。

IP 地址: 已记录   报告
高端调试 » 软件调试 » Windows内核调试 » Re: DPC是怎么执行到的呢

 
Legal Notice Privacy Statement Corporate Governance Corporate Governance
(C)2004-2020 ADVDBG.ORG All Rights Reserved.