news 2026/5/6 23:54:45

KiExitDispatcher为什么要判断Prcb->DpcRoutineActive == FALSE和KiRetireDpcList设置Prcb->DpcRoutineActive有关--重要

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
KiExitDispatcher为什么要判断Prcb->DpcRoutineActive == FALSE和KiRetireDpcList设置Prcb->DpcRoutineActive有关--重要

nt!KiExitDispatcher函数中为什么要判断Prcb->DpcRoutineActive == FALSE和KiRetireDpcList函数中处理KDPC时设置Prcb->DpcRoutineActive=TURE有关

第一部分:
VOID
FASTCALL
KiExitDispatcher (
IN KIRQL OldIrql
)
{

if (OldIrql < DISPATCH_LEVEL) {

//
// If there is a new thread selected for execution, then switch
// context to the new thread.
//

if (Prcb->NextThread != NULL) {
KiAcquirePrcbLock(Prcb);
NewThread = Prcb->NextThread;
CurrentThread = Prcb->CurrentThread;
KiSetContextSwapBusy(CurrentThread);
Prcb->NextThread = NULL;
Prcb->CurrentThread = NewThread;
NewThread->State = Running;
KxQueueReadyThread(CurrentThread, Prcb);
CurrentThread->WaitIrql = OldIrql;
Pending = KiSwapContext(CurrentThread, NewThread);
if (Pending != FALSE) {
KeLowerIrql(APC_LEVEL);
KiDeliverApc(KernelMode, NULL, NULL);

ASSERT(OldIrql == 0);
}
}

} else if ((Prcb->NextThread != NULL) &&
(Prcb->DpcRoutineActive == FALSE)) {

KiRequestSoftwareInterrupt(DISPATCH_LEVEL);
}

nt!KiExitDispatcher+0x42 是个好断点


0: kd> kc 3
#
00 nt!KiProcessDeferredReadyList
01 nt!KiExitDispatcher
02 nt!KiTimerExpiration
0: kd> kv 3
# ChildEBP RetAddr Args to Child
00 f789eed4 80a4002e f789ef90 00000046 00000000 nt!KiProcessDeferredReadyList (FPO: [0,0,0]) (CONV: fastcall) [d:\srv03rtm\base\ntos\ke\thredsup.c @ 825]
01 f789eef8 80a40fe2 ffdff980 00000000 ffdff120 nt!KiExitDispatcher+0x42 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\ke\waitsup.c @ 80]
02 f789ef9c 80a413bc 00000000 00000000 025ee7e3 nt!KiTimerExpiration+0x3e4 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ke\dpcsup.c @ 770]
0: kd> bp 80a4002e

0: kd> g
Breakpoint 49 hit
eax=ffdff9bc ebx=804edc6c ecx=ffdff120 edx=00000000 esi=00000000 edi=ffdff120
eip=80a4002e esp=f789eedc ebp=f789eef8 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
nt!KiExitDispatcher+0x42:
80a4002e 807dfc02 cmp byte ptr [ebp-4],2 ss:0010:f789eef4=02

} else if ((Prcb->NextThread != NULL) &&
(Prcb->DpcRoutineActive == FALSE)) {

KiRequestSoftwareInterrupt(DISPATCH_LEVEL);
}


为什么要与上条件 && (Prcb->DpcRoutineActive == FALSE)
因为如果Prcb->DpcRoutineActive=1,则有DPC需要处理,那么此时正在处理DPC!!!
irql=DISPATCH_LEVEL,不能再请求软件中断了!!!

第二部分:

1: kd> dx -id 0,0,8954e020 -r1 ((ntkrnlmp!_KPRCB *)0xffdff120)
((ntkrnlmp!_KPRCB *)0xffdff120) : 0xffdff120 [Type: _KPRCB *]
[+0x000] MinorVersion : 0x1 [Type: unsigned short]
[+0x002] MajorVersion : 0x1 [Type: unsigned short]
[+0x004] CurrentThread : 0x895f2a78 [Type: _KTHREAD *]
[+0x008] NextThread : 0x89555268 [Type: _KTHREAD *]

[+0x860] DpcData [Type: _KDPC_DATA [2]]
[+0x888] DpcStack : 0xf789f000 [Type: void *]
[+0x88c] MaximumDpcQueueDepth : 0x4 [Type: unsigned long]
[+0x890] DpcRequestRate : 0x0 [Type: unsigned long]
[+0x894] MinimumDpcRate : 0x3 [Type: unsigned long]
[+0x898] DpcInterruptRequested : 0x1 [Type: unsigned char]
[+0x899] DpcThreadRequested : 0x0 [Type: unsigned char]
[+0x89a] DpcRoutineActive : 0x1 [Type: unsigned char]


1: kd> dx -id 0,0,8954e020 -r1 (*((ntkrnlmp!_KDPC_DATA (*)[2])0xffdff980))
(*((ntkrnlmp!_KDPC_DATA (*)[2])0xffdff980)) [Type: _KDPC_DATA [2]]
[0] [Type: _KDPC_DATA]
[1] [Type: _KDPC_DATA]
1: kd> dx -id 0,0,8954e020 -r1 (*((ntkrnlmp!_KDPC_DATA *)0xffdff980))
(*((ntkrnlmp!_KDPC_DATA *)0xffdff980)) [Type: _KDPC_DATA]
[+0x000] DpcListHead [Type: _LIST_ENTRY]
[+0x008] DpcLock : 0x0 [Type: unsigned long]
[+0x00c] DpcQueueDepth : 0x5 [Type: unsigned long]
[+0x010] DpcCount : 0x13e8 [Type: unsigned long]
1: kd> dx -id 0,0,8954e020 -r1 (*((ntkrnlmp!_LIST_ENTRY *)0xffdff980))
(*((ntkrnlmp!_LIST_ENTRY *)0xffdff980)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0x895350fc [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x895420a8 [Type: _LIST_ENTRY *]
1: kd> dx -id 0,0,8954e020 -r1 ((ntkrnlmp!_LIST_ENTRY *)0x895350fc)
((ntkrnlmp!_LIST_ENTRY *)0x895350fc) : 0x895350fc [Type: _LIST_ENTRY *]
[+0x000] Flink : 0x898ac7b0 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0xffdff980 [Type: _LIST_ENTRY *]
1: kd> dx -id 0,0,8954e020 -r1 ((ntkrnlmp!_LIST_ENTRY *)0x898ac7b0)
((ntkrnlmp!_LIST_ENTRY *)0x898ac7b0) : 0x898ac7b0 [Type: _LIST_ENTRY *]
[+0x000] Flink : 0x89858274 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x895350fc [Type: _LIST_ENTRY *]
1: kd> dx -id 0,0,8954e020 -r1 ((ntkrnlmp!_LIST_ENTRY *)0x89858274)
((ntkrnlmp!_LIST_ENTRY *)0x89858274) : 0x89858274 [Type: _LIST_ENTRY *]
[+0x000] Flink : 0x895690a8 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x898ac7b0 [Type: _LIST_ENTRY *]
1: kd> dx -id 0,0,8954e020 -r1 ((ntkrnlmp!_LIST_ENTRY *)0x895690a8)
((ntkrnlmp!_LIST_ENTRY *)0x895690a8) : 0x895690a8 [Type: _LIST_ENTRY *]
[+0x000] Flink : 0x895420a8 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x89858274 [Type: _LIST_ENTRY *]
1: kd> dx -id 0,0,8954e020 -r1 ((ntkrnlmp!_LIST_ENTRY *)0x895420a8)
((ntkrnlmp!_LIST_ENTRY *)0x895420a8) : 0x895420a8 [Type: _LIST_ENTRY *]
[+0x000] Flink : 0xffdff980 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x895690a8 [Type: _LIST_ENTRY *]

0: kd> dt KDPC 0x895350fc-4
CSRSRV!KDPC
+0x000 Type : 0n19
+0x002 Number : 0 ''
+0x003 Importance : 0 ''
+0x004 DpcListEntry : _LIST_ENTRY [ 0x898ac7b0 - 0xffdff980 ]
+0x00c DeferredRoutine : 0xf7119206 void NDIS!ndisMDpcX+0
+0x010 DeferredContext : 0x895350e4 Void
+0x014 SystemArgument1 : (null)
+0x018 SystemArgument2 : (null)
+0x01c DpcData : 0xffdff980 Void
0: kd> u f7119206
NDIS!ndisMDpcX [d:\srv03rtm\net\ndis\sys\timerm.c @ 1189]:
f7119206 55 push ebp
f7119207 8bec mov ebp,esp
f7119209 53 push ebx
f711920a 56 push esi
f711920b 57 push edi
f711920c 8b7d0c mov edi,dword ptr [ebp+0Ch]
f711920f 8b7734 mov esi,dword ptr [edi+34h]
f7119212 8b4710 mov eax,dword ptr [edi+10h]


0: kd> dt KDPC 0x898ac7b0-4
CSRSRV!KDPC
+0x000 Type : 0n19
+0x002 Number : 0 ''
+0x003 Importance : 0x1 ''
+0x004 DpcListEntry : _LIST_ENTRY [ 0x89858274 - 0x895350fc ]
+0x00c DeferredRoutine : 0xbafe4310 void i8042prt!I8042KeyboardIsrDpc+0
+0x010 DeferredContext : 0x898ac508 Void
+0x014 SystemArgument1 : (null)
+0x018 SystemArgument2 : (null)
+0x01c DpcData : 0xffdff980 Void
0: kd> u bafe4310
i8042prt!I8042KeyboardIsrDpc [d:\srv03rtm\drivers\input\pnpi8042\kbdcmn.c @ 69]:
bafe4310 55 push ebp
bafe4311 8bec mov ebp,esp
bafe4313 83ec40 sub esp,40h
bafe4316 53 push ebx
bafe4317 56 push esi
bafe4318 57 push edi
bafe4319 33ff xor edi,edi
bafe431b f60541a3feba20 test byte ptr [i8042prt!Globals+0x1 (bafea341)],20h


0: kd> dt KDPC 0x89858274-4
CSRSRV!KDPC
+0x000 Type : 0n19
+0x002 Number : 0 ''
+0x003 Importance : 0x1 ''
+0x004 DpcListEntry : _LIST_ENTRY [ 0x895690a8 - 0x898ac7b0 ]
+0x00c DeferredRoutine : 0xbaff61f8 void i8042prt!I8042MouseIsrDpc+0
+0x010 DeferredContext : 0x89858020 Void
+0x014 SystemArgument1 : (null)
+0x018 SystemArgument2 : (null)
+0x01c DpcData : 0xffdff980 Void
0: kd> u baff61f8
i8042prt!I8042MouseIsrDpc [d:\srv03rtm\drivers\input\pnpi8042\moucmn.c @ 76]:
baff61f8 55 push ebp
baff61f9 8bec mov ebp,esp
baff61fb 83ec40 sub esp,40h
baff61fe 56 push esi
baff61ff 57 push edi
baff6200 33ff xor edi,edi
baff6202 f60541a3feba20 test byte ptr [i8042prt!Globals+0x1 (bafea341)],20h
baff6209 897dfc mov dword ptr [ebp-4],edi


0: kd> dt KDPC 0x895690a8-4
CSRSRV!KDPC
+0x000 Type : 0n19
+0x002 Number : 0 ''
+0x003 Importance : 0x1 ''
+0x004 DpcListEntry : _LIST_ENTRY [ 0x895420a8 - 0x89858274 ]
+0x00c DeferredRoutine : 0xf72abd08 void atapi!IdePortCompletionDpc+0
+0x010 DeferredContext : 0x89569030 Void
+0x014 SystemArgument1 : (null)
+0x018 SystemArgument2 : (null)
+0x01c DpcData : 0xffdff980 Void
0: kd> u f72abd08
atapi!IdePortCompletionDpc [d:\srv03rtm\drivers\storage\ide\atapi\internal.c @ 1206]:
f72abd08 55 push ebp
f72abd09 8bec mov ebp,esp
f72abd0b 83ec5c sub esp,5Ch
f72abd0e 8b450c mov eax,dword ptr [ebp+0Ch]
f72abd11 56 push esi
f72abd12 8b7028 mov esi,dword ptr [eax+28h]
f72abd15 57 push edi
f72abd16 8dbee0000000 lea edi,[esi+0E0h]


0: kd> dt KDPC 0x895420a8-4
CSRSRV!KDPC
+0x000 Type : 0n19
+0x002 Number : 0 ''
+0x003 Importance : 0x1 ''
+0x004 DpcListEntry : _LIST_ENTRY [ 0xffdff980 - 0x895690a8 ]
+0x00c DeferredRoutine : 0xf72abd08 void atapi!IdePortCompletionDpc+0
+0x010 DeferredContext : 0x89542030 Void
+0x014 SystemArgument1 : (null)
+0x018 SystemArgument2 : (null)
+0x01c DpcData : 0xffdff980 Void
0: kd> u f72abd08
atapi!IdePortCompletionDpc [d:\srv03rtm\drivers\storage\ide\atapi\internal.c @ 1206]:
f72abd08 55 push ebp
f72abd09 8bec mov ebp,esp
f72abd0b 83ec5c sub esp,5Ch
f72abd0e 8b450c mov eax,dword ptr [ebp+0Ch]
f72abd11 56 push esi
f72abd12 8b7028 mov esi,dword ptr [eax+28h]
f72abd15 57 push edi
f72abd16 8dbee0000000 lea edi,[esi+0E0h]

第三部分:

0: kd> kc
#
00 hal!HalRequestSoftwareInterrupt
01 nt!KeUpdateRunTime
02 nt!KeUpdateSystemTime
03 hal!WRITE_PORT_USHORT
04 ACPI!DefPortWriteAcpiRegister
05 ACPI!CLEAR_PM1_STATUS_BITS
06 ACPI!ACPIInterruptServiceRoutine
07 nt!KiInterruptDispatch
08 hal!WRITE_PORT_USHORT
09 usbuhci!UhciInterruptDpc
0a USBPORT!USBPORT_IsrDpc
0b nt!KiRetireDpcList
0c nt!KiDispatchInterrupt
WARNING: Frame IP not in any known module. Following frames may be wrong.
0d 0x0
0: kd> kv
# ChildEBP RetAddr Args to Child
00 f789edf8 80affd03 105ee86a 80affb39 8000000a hal!HalRequestSoftwareInterrupt (FPO: [0,0,0]) [d:\srv03rtm\base\hals\halmps\i386\mpswint.asm @ 84]
01 f789ee00 80affb39 8000000a 8000000a 000000d1 nt!KeUpdateRunTime+0x183 (FPO: [1,1,0]) [d:\srv03rtm\base\ntos\ke\i386\clockint.asm @ 527]
02 f789ee00 804f4d7e 8000000a 8000000a 000000d1 nt!KeUpdateSystemTime+0x111 (FPO: [0,2] TrapFrame @ f789ee14) [d:\srv03rtm\base\ntos\ke\i386\clockint.asm @ 302]
03 f789ee84 f7429ee0 00001000 00000001 f789eea8 hal!WRITE_PORT_USHORT+0xa (FPO: [2,0,0]) [d:\srv03rtm\base\hals\halx86\i386\xxioacc.asm @ 264]
04 f789ee94 f7429b65 00000002 00000000 00000001 ACPI!DefPortWriteAcpiRegister+0x68 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\busdrv\acpi\driver\shared\acpiio.c @ 469]
05 f789eea8 f7409b45 00000001 89906968 89906bcc ACPI!CLEAR_PM1_STATUS_BITS+0x1b (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\busdrv\acpi\driver\shared\acpiio.c @ 102]
06 f789eec8 80b003ed 89906968 89981a18 0001000a ACPI!ACPIInterruptServiceRoutine+0x35 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\busdrv\acpi\driver\nt\interupt.c @ 735]
07 f789eec8 804f4d7e 89906968 89981a18 0001000a nt!KiInterruptDispatch+0x8d (FPO: [0,2] TrapFrame @ f789eeec) [d:\srv03rtm\base\ntos\ke\i386\intsup.asm @ 777]
08 f789ef5c f754e57a 000020c4 0000000f 898d40e8 hal!WRITE_PORT_USHORT+0xa (FPO: [2,0,0]) [d:\srv03rtm\base\hals\halx86\i386\xxioacc.asm @ 264]
09 f789ef78 baed76f4 000020c0 6b6c5001 ffdff980 usbuhci!UhciInterruptDpc+0x82 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\drivers\wdm\usb\hcd\miniport\usbuhci\int.c @ 276]
0a f789ef9c 80a41432 898d4608 898d4030 00000000 USBPORT!USBPORT_IsrDpc+0x19e (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\drivers\wdm\usb\hcd\usbport\int.c @ 320]
0b f789eff4 80b00756 ba1b0bf8 00000000 00000000 nt!KiRetireDpcList+0xd6 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\ke\dpcsup.c @ 1076]
0c f789eff8 ba1b0bf8 00000000 00000000 00000000 nt!KiDispatchInterrupt+0x36 (FPO: [Uses EBP] [0,0,1]) [d:\srv03rtm\base\ntos\ke\i386\ctxswap.asm @ 226]
WARNING: Frame IP not in any known module. Following frames may be wrong.
0d 80b00756 00000000 00000009 bb837775 00000128 0xba1b0bf8

第四部分:


什么时候设置Prcb->DpcRoutineActive = TRUE


F:\srv03rtm>grep "DpcRoutineActive =" -nr F:\srv03rtm\base\ntos\ke |grep -v "inary"
F:\srv03rtm\base\ntos\ke/dpcobj.c:365: if ((Prcb->DpcRoutineActive == FALSE) &&
F:\srv03rtm\base\ntos\ke/dpcsup.c:1007: Prcb->DpcRoutineActive = TRUE;
F:\srv03rtm\base\ntos\ke/dpcsup.c:1103: Prcb->DpcRoutineActive = FALSE;
F:\srv03rtm\base\ntos\ke/ia64/clock.c:291: (Prcb->DpcRoutineActive == 0)) {
F:\srv03rtm\base\ntos\ke/ia64/clock.c:327: if (Prcb->DpcData[DPC_NORMAL].DpcQueueDepth != 0 && Prcb->DpcRoutineActive == 0) {
F:\srv03rtm\base\ntos\ke/kiinit.c:184: Prcb->DpcRoutineActive = 0;
F:\srv03rtm\base\ntos\ke/waitsup.c:107: (Prcb->DpcRoutineActive == FALSE)) {


VOID
FASTCALL
KiRetireDpcList (
PKPRCB Prcb
)
{


do {
Prcb->DpcRoutineActive = TRUE;

第五部分:


参考:

;
; If the current DPC queue depth is not zero, a DPC routine is not active,
; and a DPC interrupt has not been requested, then request a dispatch
; interrupt, decrement the maximum DPC queue depth, and reset the threshold
; counter if appropriate.
;

如果当前DPC队列深度不为零,DPC例程未处于活动状态,并且没有请求DPC中断,
则请求调度中断,减少最大DPC队列深度,并在适当的情况下重置阈值计数器。

cmp dword ptr [eax].PcPrcbData.PbDpcQueueDepth, 0 ; check queue depth
je short Kutp53 ; if eq, DPC queue depth is zero
cmp byte ptr [eax].PcPrcbData.PbDpcRoutineActive, 0 ; check if DPC active
jne short Kutp53 ; if ne, DPC routine active
cmp byte ptr [eax].PcPrcbData.PbDpcInterruptRequested, 0 ; check if interrupt
jne short Kutp53 ; if ne, DPC routine active
mov ecx, DISPATCH_LEVEL ; request a dispatch interrupt
fstCall HalRequestSoftwareInterrupt ;

参考:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/29 15:13:16

【EI复现】参与调峰的储能系统配置方案及经济性分析附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码及仿真咨询…

作者头像 李华
网站建设 2026/5/5 9:51:39

Langchain-Chatchat打造智慧图书馆服务体系

基于 Langchain-Chatchat 构建智慧图书馆服务体系 在高校与公共图书馆数字化转型的浪潮中&#xff0c;一个长期存在的矛盾日益凸显&#xff1a;馆藏资源越来越丰富&#xff0c;但读者“找得到却读不懂”“查得着却用不上”的问题却愈发严重。传统的关键词检索系统面对“贾宝玉的…

作者头像 李华
网站建设 2026/5/2 23:57:39

Vision Studio C#程序设计基础--多态函数重载、多态符号重载、抽象类、虚方法、密封类和静态类

多态函数重载面向对象四个特性: 封装 继承 多态 抽象多态: 同一个方法不同形态体现多态分静态多态和动态多态静态多态: 函数重载和符号重载动态多态:抽象和虚方法静态多态的函数重载:在同一个范围内,函数名一样,参数的类型不一样、参数的个数不一样,这样的函数就是重载仅仅只有…

作者头像 李华
网站建设 2026/5/4 16:02:32

计算机Java毕设实战-基于springboot的智能民宿预定与游玩系统设计与实现 “住宿 + 游玩” 一体化服务【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华