00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "mi.h"
00023
00024
#if (_MSC_VER >= 800)
00025
#pragma warning(disable:4010)
00026
#endif
00027
00028 extern ULONG
MmSystemCodePage;
00029 extern ULONG
MmSystemCachePage;
00030 extern ULONG
MmPagedPoolPage;
00031 extern ULONG
MmSystemDriverPage;
00032
00033
#if DBG
00034
ULONG MmNumberOfInserts;
00035
#endif
00036
00037 ULONG
00038
MiLookupWsleHashIndex (
00039 IN ULONG_PTR WsleEntry,
00040 IN
PMMWSL WorkingSetList
00041 );
00042
00043
VOID
00044
MiCheckWsleHash (
00045 IN
PMMWSL WorkingSetList
00046 );
00047
00048
00049
VOID
00050
FASTCALL
00051 MiInsertWsle (
00052 IN WSLE_NUMBER Entry,
00053 IN
PMMWSL WorkingSetList
00054 )
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 {
00080 PVOID VirtualAddress;
00081
PMMWSLE Wsle;
00082
PMMSUPPORT WsInfo;
00083
WSLE_NUMBER Hash;
00084
PMMWSLE_HASH Table;
00085
WSLE_NUMBER j;
00086
PMMPTE PointerPte;
00087
WSLE_NUMBER Index;
00088 LARGE_INTEGER
TickCount;
00089 ULONG
Size;
00090
#if defined(_ALPHA_) && !defined(_AXP64_)
00091
KIRQL OldIrql;
00092
#endif
00093
00094 Wsle = WorkingSetList->Wsle;
00095
00096 VirtualAddress =
PAGE_ALIGN(Wsle[Entry].u1.
VirtualAddress);
00097
00098
#if DBG
00099
if (MmDebug &
MM_DBG_PTE_UPDATE) {
00100
DbgPrint(
"inserting element %lx %lx\n", Entry, Wsle[Entry].u1.
Long);
00101 }
00102
00103
ASSERT (Wsle[Entry].u1.
e1.
Valid == 1);
00104
ASSERT (Wsle[Entry].u1.
e1.
Direct != 1);
00105
#endif //DBG
00106
00107 WorkingSetList->NonDirectCount += 1;
00108
00109
if ((Table = WorkingSetList->HashTable) ==
NULL) {
00110
return;
00111 }
00112
00113
#if DBG
00114
MmNumberOfInserts += 1;
00115
#endif //DBG
00116
00117 Hash =
MI_WSLE_HASH(Wsle[Entry].u1.
Long, WorkingSetList);
00118
00119
00120
00121
00122
00123
00124
if ((WorkingSetList->NonDirectCount + 10 +
00125 (WorkingSetList->HashTableSize >> 4)) >
00126 WorkingSetList->HashTableSize) {
00127
00128
if (WorkingSetList ==
MmWorkingSetList) {
00129 WsInfo = &
PsGetCurrentProcess()->Vm;
00130
ASSERT (WsInfo->
u.Flags.SessionSpace == 0);
00131 }
00132
else if (WorkingSetList ==
MmSystemCacheWorkingSetList) {
00133 WsInfo = &
MmSystemCacheWs;
00134
ASSERT (WsInfo->
u.Flags.SessionSpace == 0);
00135 }
00136
else {
00137 WsInfo = &
MmSessionSpace->
Vm;
00138
ASSERT (WsInfo->
u.Flags.SessionSpace == 1);
00139 }
00140
00141
if ((Table + WorkingSetList->HashTableSize + ((2*
PAGE_SIZE) /
sizeof (
MMWSLE_HASH)) <= (
PMMWSLE_HASH)WorkingSetList->HighestPermittedHashAddress) &&
00142 (WsInfo->
AllowWorkingSetAdjustment)) {
00143
00144
#if defined(_ALPHA_) && !defined(_AXP64_)
00145
LOCK_EXPANSION_IF_ALPHA (OldIrql);
00146
#endif
00147
WsInfo->
AllowWorkingSetAdjustment =
MM_GROW_WSLE_HASH;
00148
#if defined(_ALPHA_) && !defined(_AXP64_)
00149
UNLOCK_EXPANSION_IF_ALPHA (OldIrql);
00150
#endif
00151
}
00152
00153
if ((WorkingSetList->NonDirectCount +
00154 (WorkingSetList->HashTableSize >> 4)) >
00155 WorkingSetList->HashTableSize) {
00156
00157
00158
00159
00160
00161
00162
KeQueryTickCount(&
TickCount);
00163 j = Hash + (
TickCount.LowPart & 0xF);
00164
00165
Size = WorkingSetList->HashTableSize;
00166
00167
if (j >=
Size) {
00168 j =
TickCount.LowPart & 0xF;
00169 }
00170
00171
do {
00172
if (Table[j].
Key != 0) {
00173
PERFINFO_PAGE_INFO_DECL();
00174
00175 PointerPte =
MiGetPteAddress (Table[j].
Key);
00176
Index = WorkingSetList->HashTable[j].Index;
00177
ASSERT (Wsle[
Index].u1.e1.Valid == 1);
00178 PointerPte =
MiGetPteAddress (Wsle[
Index].u1.VirtualAddress);
00179
00180
PERFINFO_GET_PAGE_INFO(PointerPte);
00181
if (
MiFreeWsle (
Index, WsInfo, PointerPte)) {
00182
PERFINFO_LOG_WS_REMOVAL(PERFINFO_LOG_TYPE_OUTWS_HASHFULL, WsInfo);
00183
break;
00184 }
00185 }
00186 j += 1;
00187
if (j >=
Size) {
00188 j = 0;
00189 }
00190 }
while (
TRUE);
00191 }
00192 }
00193
00194
00195
00196
00197
00198
while (Table[Hash].
Key != 0) {
00199 Hash += 1;
00200
if (Hash >= WorkingSetList->HashTableSize) {
00201 Hash = 0;
00202 }
00203 }
00204
00205 Table[Hash].
Key = Wsle[Entry].
u1.Long & ~(
PAGE_SIZE - 1);
00206 Table[Hash].
Index = Entry;
00207
00208
#if DBG
00209
if ((MmNumberOfInserts % 1000) == 0) {
00210
MiCheckWsleHash (WorkingSetList);
00211 }
00212
#endif //DBG
00213
return;
00214 }
00215
00216
#if DBG
00217
VOID
00218
MiCheckWsleHash (
00219 IN
PMMWSL WorkingSetList
00220 )
00221
00222 {
00223 ULONG j;
00224 ULONG found = 0;
00225
PMMWSLE Wsle;
00226
00227 Wsle = WorkingSetList->Wsle;
00228
00229
for (j =0; j < WorkingSetList->HashTableSize ; j++ ) {
00230
if (WorkingSetList->HashTable[j].Key != 0) {
00231 found += 1;
00232
ASSERT (WorkingSetList->HashTable[j].Key ==
00233 (Wsle[WorkingSetList->HashTable[j].Index].u1.Long &
00234 ~(PAGE_SIZE -1)));
00235 }
00236 }
00237
if (found != WorkingSetList->NonDirectCount) {
00238
DbgPrint(
"MMWSLE: Found %lx, nondirect %lx\n",
00239 found, WorkingSetList->NonDirectCount);
00240 DbgBreakPoint();
00241 }
00242 }
00243
#endif //dbg
00244
00245
00246
WSLE_NUMBER
00247
FASTCALL
00248 MiLocateWsle (
00249 IN PVOID VirtualAddress,
00250 IN
PMMWSL WorkingSetList,
00251 IN WSLE_NUMBER WsPfnIndex
00252 )
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 {
00281
WSLE_NUMBER i;
00282
PMMWSLE Wsle;
00283 ULONG Hash;
00284
PMMWSLE_HASH Table;
00285 ULONG Tries;
00286
WSLE_NUMBER WsPteIndex;
00287
PMMPTE PointerPte;
00288
00289 Wsle = WorkingSetList->Wsle;
00290
00291 VirtualAddress =
PAGE_ALIGN(VirtualAddress);
00292
00293
#if defined (_WIN64)
00294
PointerPte =
MiGetPteAddress (VirtualAddress);
00295 WsPteIndex =
MI_GET_WORKING_SET_FROM_PTE (PointerPte);
00296
if (WsPteIndex != 0) {
00297
while (WsPteIndex <= WorkingSetList->LastInitializedWsle) {
00298
if ((VirtualAddress ==
PAGE_ALIGN(Wsle[WsPteIndex].u1.
VirtualAddress)) &&
00299 (Wsle[WsPteIndex].
u1.e1.Valid == 1)) {
00300
return WsPteIndex;
00301 }
00302 WsPteIndex +=
MI_MAXIMUM_PTE_WORKING_SET_INDEX;
00303 }
00304
00305
00306
00307
00308
00309
KeBugCheckEx (MEMORY_MANAGEMENT,
00310 0x41283,
00311 (ULONG_PTR)VirtualAddress,
00312 PointerPte->
u.Long,
00313 (ULONG_PTR)WorkingSetList);
00314 }
00315
#endif
00316
00317
if (WsPfnIndex <= WorkingSetList->LastInitializedWsle) {
00318
if ((VirtualAddress ==
PAGE_ALIGN(Wsle[WsPfnIndex].u1.
VirtualAddress)) &&
00319 (Wsle[WsPfnIndex].
u1.e1.Valid == 1)) {
00320
return WsPfnIndex;
00321 }
00322 }
00323
00324
if (WorkingSetList->HashTable) {
00325 Tries = 0;
00326 Table = WorkingSetList->HashTable;
00327
00328 Hash =
MI_WSLE_HASH(VirtualAddress, WorkingSetList);
00329
00330
while (Table[Hash].
Key != (ULONG_PTR)VirtualAddress) {
00331 Hash += 1;
00332
if (Hash >= WorkingSetList->HashTableSize) {
00333 Hash = 0;
00334
if (Tries != 0) {
00335
KeBugCheckEx (MEMORY_MANAGEMENT,
00336 0x41284,
00337 (ULONG_PTR)VirtualAddress,
00338 WsPfnIndex,
00339 (ULONG_PTR)WorkingSetList);
00340 }
00341 Tries = 1;
00342 }
00343 }
00344
ASSERT (WorkingSetList->Wsle[Table[Hash].
Index].u1.e1.Direct == 0);
00345
return Table[Hash].
Index;
00346 }
00347
00348 i = 0;
00349
00350
for (; ; ) {
00351
if ((VirtualAddress ==
PAGE_ALIGN(Wsle[i].u1.
VirtualAddress)) &&
00352 (Wsle[i].
u1.e1.Valid == 1)) {
00353
ASSERT (WorkingSetList->Wsle[i].u1.e1.Direct == 0);
00354
return i;
00355 }
00356 i += 1;
00357 }
00358 }
00359
00360
00361
#if 0
00362
00363 ULONG
00364 MiLocateWsleAndParent (
00365 IN PVOID VirtualAddress,
00366 OUT PULONG Parent,
00367 IN
PMMWSL WorkingSetList,
00368 IN ULONG WsPfnIndex
00369 )
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 {
00400 ULONG Previous;
00401 ULONG Entry;
00402
PMMWSLE Wsle;
00403
00404 Wsle = WorkingSetList->Wsle;
00405
00406
00407
00408
00409
00410
00411
if (WsPfnIndex <= WorkingSetList->LastInitializedWsle) {
00412
if (VirtualAddress ==
PAGE_ALIGN(Wsle[WsPfnIndex].u1.VirtualAddress)) {
00413
00414
00415
00416
00417
00418
00419
00420
if (Wsle[WsPfnIndex].u2.BothPointers == 0) {
00421
00422
00423
00424
00425
00426 *Parent =
WSLE_NULL_INDEX;
00427
return WsPfnIndex;
00428 }
00429 }
00430 }
00431
00432
00433
00434
00435
00436 Entry = WorkingSetList->Root;
00437 Previous = Entry;
00438
00439
for (;;) {
00440
00441
ASSERT (Entry != WSLE_NULL_INDEX);
00442
00443
if (VirtualAddress ==
PAGE_ALIGN(Wsle[Entry].u1.VirtualAddress)) {
00444
break;
00445 }
00446
00447
if (VirtualAddress <
PAGE_ALIGN(Wsle[Entry].u1.VirtualAddress)) {
00448 Previous = Entry;
00449 Entry = Wsle[Entry].u2.s.LeftChild;
00450 }
else {
00451 Previous = Entry;
00452 Entry = Wsle[Entry].u2.s.RightChild;
00453 }
00454 }
00455
00456 *Parent = Previous;
00457
return Entry;
00458 }
00459
#endif //0
00460
00461
00462
VOID
00463
FASTCALL
00464 MiRemoveWsle (
00465 IN WSLE_NUMBER Entry,
00466 IN
PMMWSL WorkingSetList
00467 )
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 {
00491
PMMWSLE Wsle;
00492 PVOID VirtualAddress;
00493
PMMWSLE_HASH Table;
00494 ULONG Hash;
00495 ULONG Tries;
00496
00497 Wsle = WorkingSetList->Wsle;
00498
00499
00500
00501
00502
00503
#if DBG
00504
if (MmDebug &
MM_DBG_PTE_UPDATE) {
00505
DbgPrint(
"removing wsle %lx %lx\n",
00506 Entry, Wsle[Entry].u1.
Long);
00507 }
00508
if (MmDebug &
MM_DBG_DUMP_WSL) {
00509
MiDumpWsl();
00510
DbgPrint(
" \n");
00511 }
00512
00513
#endif //DBG
00514
00515
ASSERT (Wsle[Entry].u1.
e1.
Valid == 1);
00516
00517 VirtualAddress =
PAGE_ALIGN (Wsle[Entry].u1.
VirtualAddress);
00518
00519
if (WorkingSetList ==
MmSystemCacheWorkingSetList) {
00520
00521
00522
00523
00524
00525
#if defined(_X86_)
00526
if (
MI_IS_SYSTEM_CACHE_ADDRESS(VirtualAddress)) {
00527
MmSystemCachePage -= 1;
00528 }
else
00529
#endif
00530
if (VirtualAddress <
MmSystemCacheStart) {
00531
MmSystemCodePage -= 1;
00532 }
else if (VirtualAddress <
MM_PAGED_POOL_START) {
00533
MmSystemCachePage -= 1;
00534 }
else if (VirtualAddress <
MmNonPagedSystemStart) {
00535
MmPagedPoolPage -= 1;
00536 }
else {
00537
MmSystemDriverPage -= 1;
00538 }
00539 }
00540
00541 Wsle[Entry].
u1.e1.Valid = 0;
00542
00543
if (Wsle[Entry].
u1.e1.Direct == 0) {
00544
00545 WorkingSetList->NonDirectCount -= 1;
00546
00547
if (WorkingSetList->HashTable) {
00548 Hash =
MI_WSLE_HASH(Wsle[Entry].u1.
Long, WorkingSetList);
00549 Table = WorkingSetList->HashTable;
00550 Tries = 0;
00551
00552
while (Table[Hash].
Key != (ULONG_PTR)VirtualAddress) {
00553 Hash += 1;
00554
if (Hash >= WorkingSetList->HashTableSize) {
00555 Hash = 0;
00556
if (Tries != 0) {
00557
KeBugCheckEx (MEMORY_MANAGEMENT,
00558 0x41784,
00559 (ULONG_PTR)VirtualAddress,
00560 Entry,
00561 (ULONG_PTR)WorkingSetList);
00562 }
00563 Tries = 1;
00564 }
00565 }
00566 Table[Hash].
Key = 0;
00567
00568 }
00569 }
00570
00571
return;
00572 }
00573
00574
00575
VOID
00576 MiSwapWslEntries (
00577 IN WSLE_NUMBER SwapEntry,
00578 IN WSLE_NUMBER Entry,
00579 IN
PMMSUPPORT WsInfo
00580 )
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 {
00611
MMWSLE WsleEntry;
00612
MMWSLE WsleSwap;
00613
PMMPTE PointerPte;
00614
PMMPFN Pfn1;
00615
PMMWSLE Wsle;
00616
PMMWSL WorkingSetList;
00617
PMMWSLE_HASH Table;
00618
#if DBG
00619
WSLE_NUMBER CurrentSize = WsInfo->WorkingSetSize;
00620
#endif //DBG
00621
#if PFN_CONSISTENCY
00622
KIRQL OldIrql;
00623
#endif
00624
00625 WorkingSetList = WsInfo->VmWorkingSetList;
00626 Wsle = WorkingSetList->
Wsle;
00627
00628 WsleSwap = Wsle[SwapEntry];
00629
00630
ASSERT (WsleSwap.
u1.e1.Valid != 0);
00631
00632 WsleEntry = Wsle[Entry];
00633
00634 Table = WorkingSetList->
HashTable;
00635
00636
if (WsleEntry.
u1.e1.Valid == 0) {
00637
00638
00639
00640
00641
00642
MiRemoveWsleFromFreeList (Entry, Wsle, WorkingSetList);
00643
00644
00645
00646
00647
00648 Wsle[Entry] = WsleSwap;
00649
00650 PointerPte =
MiGetPteAddress (WsleSwap.u1.VirtualAddress);
00651
00652
if (WsleSwap.u1.e1.Direct) {
00653 Pfn1 =
MI_PFN_ELEMENT (PointerPte->
u.Hard.PageFrameNumber);
00654
#if PFN_CONSISTENCY
00655
OldIrql = 99;
00656
if (PFN_LOCK_OWNED_BY_ME() == 0) {
00657
LOCK_PFN (OldIrql);
00658 }
00659
#endif
00660
Pfn1->
u1.WsIndex = Entry;
00661
#if PFN_CONSISTENCY
00662
if (OldIrql != 99) {
00663
UNLOCK_PFN (OldIrql);
00664 }
00665
#endif
00666
}
else {
00667
00668
00669
00670
00671
00672
if (Table) {
00673 Table [
MiLookupWsleHashIndex (WsleSwap.u1.Long,
00674 WorkingSetList)].
Index = Entry;
00675 }
00676 }
00677
00678
MI_SET_PTE_IN_WORKING_SET (PointerPte, Entry);
00679
00680
00681
00682
00683
00684
ASSERT (WorkingSetList->
FirstFree <= WorkingSetList->
LastInitializedWsle);
00685 Wsle[SwapEntry].u1.Long = WorkingSetList->
FirstFree <<
MM_FREE_WSLE_SHIFT;
00686 WorkingSetList->
FirstFree = SwapEntry;
00687
ASSERT ((WorkingSetList->
FirstFree <= WorkingSetList->
LastInitializedWsle) ||
00688 (WorkingSetList->
FirstFree ==
WSLE_NULL_INDEX));
00689
00690 }
else {
00691
00692
00693
00694
00695
00696 Wsle[SwapEntry] = WsleEntry;
00697
00698 PointerPte =
MiGetPteAddress (WsleEntry.u1.VirtualAddress);
00699
00700
if (WsleEntry.u1.e1.Direct) {
00701
00702
00703
00704
00705
00706 Pfn1 =
MI_PFN_ELEMENT (PointerPte->
u.Hard.PageFrameNumber);
00707
#if PFN_CONSISTENCY
00708
OldIrql = 99;
00709
if (PFN_LOCK_OWNED_BY_ME() == 0) {
00710
LOCK_PFN (OldIrql);
00711 }
00712
#endif
00713
Pfn1->
u1.WsIndex = SwapEntry;
00714
#if PFN_CONSISTENCY
00715
if (OldIrql != 99) {
00716
UNLOCK_PFN (OldIrql);
00717 }
00718
#endif
00719
}
else {
00720
00721
00722
00723
00724
00725
if (Table) {
00726 Table[
MiLookupWsleHashIndex (WsleEntry.u1.Long,
00727 WorkingSetList)].
Index = SwapEntry;
00728 }
00729 }
00730
00731
MI_SET_PTE_IN_WORKING_SET (PointerPte, SwapEntry);
00732
00733 Wsle[Entry] = WsleSwap;
00734
00735 PointerPte =
MiGetPteAddress (WsleSwap.u1.VirtualAddress);
00736
00737
if (WsleSwap.u1.e1.Direct) {
00738
00739 Pfn1 =
MI_PFN_ELEMENT (PointerPte->
u.Hard.PageFrameNumber);
00740
#if PFN_CONSISTENCY
00741
OldIrql = 99;
00742
if (PFN_LOCK_OWNED_BY_ME() == 0) {
00743
LOCK_PFN (OldIrql);
00744 }
00745
#endif
00746
Pfn1->
u1.WsIndex = Entry;
00747
#if PFN_CONSISTENCY
00748
if (OldIrql != 99) {
00749
UNLOCK_PFN (OldIrql);
00750 }
00751
#endif
00752
}
else {
00753
if (Table) {
00754 Table[
MiLookupWsleHashIndex (WsleSwap.u1.Long,
00755 WorkingSetList)].
Index = Entry;
00756 }
00757 }
00758
MI_SET_PTE_IN_WORKING_SET (PointerPte, Entry);
00759 }
00760
ASSERT (CurrentSize == WsInfo->WorkingSetSize);
00761
return;
00762 }
00763
00764 ULONG
00765 MiLookupWsleHashIndex (
00766 IN ULONG_PTR WsleEntry,
00767 IN
PMMWSL WorkingSetList
00768 )
00769
00770 {
00771 ULONG Hash;
00772 ULONG_PTR VirtualAddress;
00773
PMMWSLE_HASH Table;
00774 ULONG Tries = 0;
00775
00776 Table = WorkingSetList->HashTable;
00777 VirtualAddress = WsleEntry & ~(
PAGE_SIZE - 1);
00778
00779 Hash =
MI_WSLE_HASH(WsleEntry, WorkingSetList);
00780
00781
while (Table[Hash].
Key != (ULONG_PTR)VirtualAddress) {
00782 Hash += 1;
00783
if (Hash >= WorkingSetList->HashTableSize) {
00784 Hash = 0;
00785
if (Tries != 0) {
00786
KeBugCheckEx (MEMORY_MANAGEMENT,
00787 0x41884,
00788 (ULONG_PTR)VirtualAddress,
00789 WsleEntry,
00790 (ULONG_PTR)WorkingSetList);
00791 }
00792 Tries = 1;
00793 }
00794 }
00795
return Hash;
00796 }
00797
00798
VOID
00799 MiRemoveWsleFromFreeList (
00800 IN ULONG Entry,
00801 IN
PMMWSLE Wsle,
00802 IN
PMMWSL WorkingSetList
00803 )
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831 {
00832
WSLE_NUMBER Free;
00833
WSLE_NUMBER ParentFree;
00834
00835 Free = WorkingSetList->FirstFree;
00836
00837
if (Entry == Free) {
00838
ASSERT ((Wsle[Entry].u1.Long >>
MM_FREE_WSLE_SHIFT) <= WorkingSetList->LastInitializedWsle);
00839 WorkingSetList->FirstFree = (
WSLE_NUMBER)(Wsle[Entry].u1.Long >>
MM_FREE_WSLE_SHIFT);
00840
00841 }
else {
00842
do {
00843 ParentFree = Free;
00844
ASSERT (Wsle[Free].u1.e1.Valid == 0);
00845 Free = (
WSLE_NUMBER)(Wsle[Free].u1.Long >>
MM_FREE_WSLE_SHIFT);
00846 }
while (Free != Entry);
00847
00848 Wsle[ParentFree].u1.Long = Wsle[Entry].u1.Long;
00849 }
00850
ASSERT ((WorkingSetList->FirstFree <= WorkingSetList->LastInitializedWsle) ||
00851 (WorkingSetList->FirstFree ==
WSLE_NULL_INDEX));
00852
return;
00853 }
00854
00855
00856
#if 0
00857
00858
VOID
00859
MiSwapWslEntries (
00860 IN ULONG Entry,
00861 IN ULONG Parent,
00862 IN ULONG SwapEntry,
00863 IN
PMMWSL WorkingSetList
00864 )
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 {
00895
00896 ULONG SwapParent;
00897 ULONG SavedRight;
00898 ULONG SavedLeft;
00899 ULONG Free;
00900 ULONG ParentFree;
00901 ULONG SavedLong;
00902 PVOID VirtualAddress;
00903
PMMWSLE Wsle;
00904
PMMPFN Pfn1;
00905
PMMPTE PointerPte;
00906
00907 Wsle = WorkingSetList->Wsle;
00908
00909
if (Wsle[SwapEntry].
u1.e1.Valid == 0) {
00910
00911
00912
00913
00914
00915
00916 Free = WorkingSetList->FirstFree;
00917
00918
if (SwapEntry == Free) {
00919 WorkingSetList->FirstFree = Entry;
00920
ASSERT ((WorkingSetList->FirstFree <= WorkingSetList->LastInitializedWsle) ||
00921 (WorkingSetList->FirstFree == WSLE_NULL_INDEX));
00922
00923 }
else {
00924
00925
while (Free != SwapEntry) {
00926 ParentFree = Free;
00927 Free = Wsle[Free].u2.s.LeftChild;
00928 }
00929
00930 Wsle[ParentFree].u2.s.LeftChild = Entry;
00931 }
00932
00933
00934
00935
00936
00937 SavedLeft = Wsle[Entry].u2.s.LeftChild;
00938 Wsle[Entry].u2.s.LeftChild = Wsle[SwapEntry].u2.s.LeftChild;
00939 Wsle[SwapEntry].u2.s.LeftChild = SavedLeft;
00940 Wsle[SwapEntry].u2.s.RightChild = Wsle[Entry].u2.s.RightChild;
00941 Wsle[SwapEntry].
u1.Long = Wsle[Entry].u1.Long;
00942 Wsle[Entry].u1.Long = 0;
00943
00944
00945
00946
00947
00948
if (Parent ==
WSLE_NULL_INDEX) {
00949
00950
00951
00952
00953
00954 PointerPte =
MiGetPteAddress (Wsle[SwapEntry].u1.VirtualAddress);
00955 Pfn1 =
MI_PFN_ELEMENT (PointerPte->
u.Hard.PageFrameNumber);
00956 Pfn1->
u1.WsIndex = SwapEntry;
00957
return;
00958 }
00959
00960
if (Parent == Entry) {
00961
00962
00963
00964
00965
00966 WorkingSetList->Root = SwapEntry;
00967
00968 }
else {
00969
00970
if (Wsle[Parent].u2.s.LeftChild == Entry) {
00971 Wsle[Parent].u2.s.LeftChild = SwapEntry;
00972 }
else {
00973
ASSERT (Wsle[Parent].u2.s.RightChild == Entry);
00974
00975 Wsle[Parent].u2.s.RightChild = SwapEntry;
00976 }
00977 }
00978
00979 }
else {
00980
00981
if ((Parent ==
WSLE_NULL_INDEX) &&
00982 (Wsle[SwapEntry].u2.BothPointers == 0)) {
00983
00984
00985
00986
00987
00988 SavedLong = Wsle[SwapEntry].
u1.Long;
00989 Wsle[SwapEntry].u1.Long = Wsle[Entry].u1.Long;
00990 Wsle[Entry].u1.Long = SavedLong;
00991
00992 PointerPte =
MiGetPteAddress (Wsle[Entry].u1.VirtualAddress);
00993 Pfn1 =
MI_PFN_ELEMENT (PointerPte->
u.Hard.PageFrameNumber);
00994 Pfn1->
u1.WsIndex = Entry;
00995
00996 PointerPte =
MiGetPteAddress (Wsle[SwapEntry].u1.VirtualAddress);
00997 Pfn1 =
MI_PFN_ELEMENT (PointerPte->
u.Hard.PageFrameNumber);
00998 Pfn1->
u1.WsIndex = SwapEntry;
00999
01000
return;
01001 }
01002
01003
01004
01005
01006
01007
01008 SwapParent = WorkingSetList->Root;
01009
01010
if (SwapParent == SwapEntry) {
01011
01012
01013
01014
01015
01016
if (Wsle[SwapEntry].u2.s.LeftChild == Entry) {
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027 WorkingSetList->Root = Entry;
01028
01029 Wsle[SwapEntry].u2.s.LeftChild = Wsle[Entry].u2.s.LeftChild;
01030 Wsle[Entry].u2.s.LeftChild = SwapEntry;
01031 SavedRight = Wsle[SwapEntry].u2.s.RightChild;
01032 Wsle[SwapEntry].u2.s.RightChild = Wsle[Entry].u2.s.RightChild;
01033 Wsle[Entry].u2.s.RightChild = SavedRight;
01034
01035 SavedLong = Wsle[Entry].
u1.Long;
01036 Wsle[Entry].u1.Long = Wsle[SwapEntry].u1.Long;
01037 Wsle[SwapEntry].u1.Long = SavedLong;
01038
01039
return;
01040
01041 }
else {
01042
01043
if (Wsle[SwapEntry].u2.s.RightChild == Entry) {
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 WorkingSetList->Root = Entry;
01055
01056 Wsle[SwapEntry].u2.s.RightChild = Wsle[Entry].u2.s.RightChild;
01057 Wsle[Entry].u2.s.RightChild = SwapEntry;
01058 SavedLeft = Wsle[SwapEntry].u2.s.LeftChild;
01059 Wsle[SwapEntry].u2.s.LeftChild = Wsle[Entry].u2.s.LeftChild;
01060 Wsle[Entry].u2.s.LeftChild = SavedLeft;
01061
01062
01063 SavedLong = Wsle[Entry].
u1.Long;
01064 Wsle[Entry].u1.Long = Wsle[SwapEntry].u1.Long;
01065 Wsle[SwapEntry].u1.Long = SavedLong;
01066
01067
return;
01068 }
01069 }
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085 WorkingSetList->Root = Entry;
01086
01087 SavedRight = Wsle[SwapEntry].u2.s.RightChild;
01088 Wsle[SwapEntry].u2.s.RightChild = Wsle[Entry].u2.s.RightChild;
01089 Wsle[Entry].u2.s.RightChild = SavedRight;
01090 SavedLeft = Wsle[SwapEntry].u2.s.LeftChild;
01091 Wsle[SwapEntry].u2.s.LeftChild = Wsle[Entry].u2.s.LeftChild;
01092 Wsle[Entry].u2.s.LeftChild = SavedLeft;
01093
01094 SavedLong = Wsle[Entry].
u1.Long;
01095 Wsle[Entry].u1.Long = Wsle[SwapEntry].u1.Long;
01096 Wsle[SwapEntry].u1.Long = SavedLong;
01097
01098
if (Parent ==
WSLE_NULL_INDEX) {
01099
01100
01101
01102
01103
01104 PointerPte =
MiGetPteAddress (Wsle[SwapEntry].u1.VirtualAddress);
01105 Pfn1 =
MI_PFN_ELEMENT (PointerPte->
u.Hard.PageFrameNumber);
01106 Pfn1->
u1.WsIndex = SwapEntry;
01107
return;
01108 }
01109
01110
01111
01112
01113
01114
if (Wsle[Parent].u2.s.RightChild == Entry) {
01115 Wsle[Parent].u2.s.RightChild = SwapEntry;
01116 }
else {
01117 Wsle[Parent].u2.s.LeftChild = SwapEntry;
01118 }
01119
01120
return;
01121
01122 }
01123
01124
01125
01126
01127
01128
if (Wsle[SwapEntry].u2.BothPointers == 0) {
01129
01130
01131
01132
01133 SwapParent =
WSLE_NULL_INDEX;
01134
01135 }
else {
01136
01137 VirtualAddress =
PAGE_ALIGN(Wsle[SwapEntry].u1.VirtualAddress);
01138
01139
for (;;) {
01140
01141
ASSERT (SwapParent != WSLE_NULL_INDEX);
01142
01143
if (Wsle[SwapParent].u2.s.LeftChild == SwapEntry) {
01144
break;
01145 }
01146
if (Wsle[SwapParent].u2.s.RightChild == SwapEntry) {
01147
break;
01148 }
01149
01150
01151
if (VirtualAddress <
PAGE_ALIGN(Wsle[SwapParent].u1.VirtualAddress)) {
01152 SwapParent = Wsle[SwapParent].u2.s.LeftChild;
01153 }
else {
01154 SwapParent = Wsle[SwapParent].u2.s.RightChild;
01155 }
01156 }
01157 }
01158
01159
if (Parent == WorkingSetList->Root) {
01160
01161
01162
01163
01164
01165
if (Wsle[Entry].u2.s.LeftChild == SwapEntry) {
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176 WorkingSetList->Root = SwapEntry;
01177
01178 Wsle[Entry].u2.s.LeftChild = Wsle[SwapEntry].u2.s.LeftChild;
01179 Wsle[SwapEntry].u2.s.LeftChild = Entry;
01180 SavedRight = Wsle[Entry].u2.s.RightChild;
01181 Wsle[Entry].u2.s.RightChild = Wsle[SwapEntry].u2.s.RightChild;
01182 Wsle[SwapEntry].u2.s.RightChild = SavedRight;
01183
01184 SavedLong = Wsle[Entry].
u1.Long;
01185 Wsle[Entry].u1.Long = Wsle[SwapEntry].u1.Long;
01186 Wsle[SwapEntry].u1.Long = SavedLong;
01187
01188
return;
01189
01190 }
else if (Wsle[SwapEntry].u2.s.RightChild == Entry) {
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201 WorkingSetList->Root = Entry;
01202
01203 Wsle[SwapEntry].u2.s.RightChild = Wsle[Entry].u2.s.RightChild;
01204 Wsle[Entry].u2.s.RightChild = SwapEntry;
01205 SavedLeft = Wsle[SwapEntry].u2.s.LeftChild;
01206 Wsle[SwapEntry].u2.s.LeftChild = Wsle[Entry].u2.s.LeftChild;
01207 Wsle[Entry].u2.s.LeftChild = SavedLeft;
01208
01209
01210 SavedLong = Wsle[Entry].
u1.Long;
01211 Wsle[Entry].u1.Long = Wsle[SwapEntry].u1.Long;
01212 Wsle[SwapEntry].u1.Long = SavedLong;
01213
01214
return;
01215 }
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231 WorkingSetList->Root = Entry;
01232
01233 SavedRight = Wsle[SwapEntry].u2.s.RightChild;
01234 Wsle[SwapEntry].u2.s.RightChild = Wsle[Entry].u2.s.RightChild;
01235 Wsle[Entry].u2.s.RightChild = SavedRight;
01236 SavedLeft = Wsle[SwapEntry].u2.s.LeftChild;
01237 Wsle[SwapEntry].u2.s.LeftChild = Wsle[Entry].u2.s.LeftChild;
01238 Wsle[Entry].u2.s.LeftChild = SavedLeft;
01239
01240 SavedLong = Wsle[Entry].
u1.Long;
01241 Wsle[Entry].u1.Long = Wsle[SwapEntry].u1.Long;
01242 Wsle[SwapEntry].u1.Long = SavedLong;
01243
01244
if (SwapParent ==
WSLE_NULL_INDEX) {
01245
01246
01247
01248
01249
01250 PointerPte =
MiGetPteAddress (Wsle[Entry].u1.VirtualAddress);
01251 Pfn1 =
MI_PFN_ELEMENT (PointerPte->
u.Hard.PageFrameNumber);
01252
ASSERT (Pfn1->
u1.WsIndex == SwapEntry);
01253 Pfn1->
u1.WsIndex = Entry;
01254
return;
01255 }
01256
01257
01258
01259
01260
01261
if (Wsle[SwapParent].u2.s.RightChild == SwapEntry) {
01262 Wsle[SwapParent].u2.s.RightChild = Entry;
01263 }
else {
01264 Wsle[SwapParent].u2.s.LeftChild = Entry;
01265 }
01266
01267
return;
01268
01269 }
01270
01271
01272
01273
01274
01275
if (Parent == SwapEntry) {
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
if (Wsle[SwapParent].u2.s.LeftChild == SwapEntry) {
01296 Wsle[SwapParent].u2.s.LeftChild = Entry;
01297 }
else {
01298 Wsle[SwapParent].u2.s.RightChild = Entry;
01299 }
01300
01301
01302
01303
01304
01305
if (Wsle[SwapEntry].u2.s.LeftChild == Entry) {
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321 Wsle[SwapEntry].u2.s.LeftChild = Wsle[Entry].u2.s.LeftChild;
01322 Wsle[Entry].u2.s.LeftChild = SwapEntry;
01323 SavedRight = Wsle[SwapEntry].u2.s.RightChild;
01324 Wsle[SwapEntry].u2.s.RightChild = Wsle[Entry].u2.s.RightChild;
01325 Wsle[Entry].u2.s.RightChild = SavedRight;
01326
01327 SavedLong = Wsle[Entry].
u1.Long;
01328 Wsle[Entry].u1.Long = Wsle[SwapEntry].u1.Long;
01329 Wsle[SwapEntry].u1.Long = SavedLong;
01330
01331
return;
01332
01333 }
else {
01334
01335
ASSERT (Wsle[SwapEntry].u2.s.RightChild == Entry);
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351 Wsle[SwapEntry].u2.s.RightChild = Wsle[Entry].u2.s.RightChild;
01352 Wsle[Entry].u2.s.RightChild = SwapEntry;
01353 SavedLeft = Wsle[SwapEntry].u2.s.LeftChild;
01354 Wsle[SwapEntry].u2.s.LeftChild = Wsle[Entry].u2.s.LeftChild;
01355 Wsle[Entry].u2.s.LeftChild = SavedLeft;
01356
01357
01358 SavedLong = Wsle[Entry].
u1.Long;
01359 Wsle[Entry].u1.Long = Wsle[SwapEntry].u1.Long;
01360 Wsle[SwapEntry].u1.Long = SavedLong;
01361
01362
return;
01363 }
01364
01365
01366 }
01367
if (SwapParent == Entry) {
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
if (Wsle[Parent].u2.s.LeftChild == Entry) {
01388 Wsle[Parent].u2.s.LeftChild = SwapEntry;
01389 }
else {
01390 Wsle[Parent].u2.s.RightChild = SwapEntry;
01391 }
01392
01393
01394
01395
01396
01397
if (Wsle[Entry].u2.s.LeftChild == SwapEntry) {
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413 Wsle[Entry].u2.s.LeftChild = Wsle[SwapEntry].u2.s.LeftChild;
01414 Wsle[SwapEntry].u2.s.LeftChild = Entry;
01415 SavedRight = Wsle[Entry].u2.s.RightChild;
01416 Wsle[Entry].u2.s.RightChild = Wsle[SwapEntry].u2.s.RightChild;
01417 Wsle[SwapEntry].u2.s.RightChild = SavedRight;
01418
01419 SavedLong = Wsle[Entry].
u1.Long;
01420 Wsle[Entry].u1.Long = Wsle[SwapEntry].u1.Long;
01421 Wsle[SwapEntry].u1.Long = SavedLong;
01422
01423
return;
01424
01425 }
else {
01426
01427
ASSERT (Wsle[Entry].u2.s.RightChild == SwapEntry);
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438 Wsle[Entry].u2.s.RightChild = Wsle[SwapEntry].u2.s.RightChild;
01439 Wsle[SwapEntry].u2.s.RightChild = Entry;
01440 SavedLeft = Wsle[SwapEntry].u2.s.LeftChild;
01441 Wsle[SwapEntry].u2.s.LeftChild = Wsle[Entry].u2.s.LeftChild;
01442 Wsle[Entry].u2.s.LeftChild = SavedLeft;
01443
01444 SavedLong = Wsle[Entry].
u1.Long;
01445 Wsle[Entry].u1.Long = Wsle[SwapEntry].u1.Long;
01446 Wsle[SwapEntry].u1.Long = SavedLong;
01447
01448
return;
01449 }
01450
01451 }
01452
01453
01454
01455
01456
01457
01458
if (Parent ==
WSLE_NULL_INDEX) {
01459
01460
01461
01462
01463
01464 PointerPte =
MiGetPteAddress (Wsle[Entry].u1.VirtualAddress);
01465 Pfn1 =
MI_PFN_ELEMENT (PointerPte->
u.Hard.PageFrameNumber);
01466
ASSERT (Pfn1->
u1.WsIndex == Entry);
01467 Pfn1->
u1.WsIndex = SwapEntry;
01468
01469 }
else {
01470
01471
if (Wsle[Parent].u2.s.LeftChild == Entry) {
01472 Wsle[Parent].u2.s.LeftChild = SwapEntry;
01473 }
else {
01474 Wsle[Parent].u2.s.RightChild = SwapEntry;
01475 }
01476 }
01477
01478
if (SwapParent ==
WSLE_NULL_INDEX) {
01479
01480
01481
01482
01483
01484 PointerPte =
MiGetPteAddress (Wsle[SwapEntry].u1.VirtualAddress);
01485 Pfn1 =
MI_PFN_ELEMENT (PointerPte->
u.Hard.PageFrameNumber);
01486
ASSERT (Pfn1->
u1.WsIndex == SwapEntry);
01487 Pfn1->
u1.WsIndex = Entry;
01488 }
else {
01489
01490
if (Wsle[SwapParent].u2.s.LeftChild == SwapEntry) {
01491 Wsle[SwapParent].u2.s.LeftChild = Entry;
01492 }
else {
01493 Wsle[SwapParent].u2.s.RightChild = Entry;
01494 }
01495 }
01496
01497 SavedRight = Wsle[SwapEntry].u2.s.RightChild;
01498 Wsle[SwapEntry].u2.s.RightChild = Wsle[Entry].u2.s.RightChild;
01499 Wsle[Entry].u2.s.RightChild = SavedRight;
01500 SavedLeft = Wsle[SwapEntry].u2.s.LeftChild;
01501 Wsle[SwapEntry].u2.s.LeftChild = Wsle[Entry].u2.s.LeftChild;
01502 Wsle[Entry].u2.s.LeftChild = SavedLeft;
01503
01504 SavedLong = Wsle[Entry].
u1.Long;
01505 Wsle[Entry].u1.Long = Wsle[SwapEntry].u1.Long;
01506 Wsle[SwapEntry].u1.Long = SavedLong;
01507
01508
return;
01509 }
01510 }
01511
#endif //0