@@ -78,6 +78,11 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
78
78
PFN_NUMBER OldFlink , OldBlink ;
79
79
PMMPFNLIST ListHead ;
80
80
MMLISTS ListName ;
81
+ #ifdef ARM3_COLORS
82
+ ULONG Color ;
83
+ PMMCOLOR_TABLES ColorTable ;
84
+ PMMPFN Pfn1 ;
85
+ #endif
81
86
82
87
/* Make sure the PFN lock is held */
83
88
ASSERT (KeGetCurrentIrql () == DISPATCH_LEVEL );
@@ -124,13 +129,64 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
124
129
/* Set the list head's backlink instead */
125
130
ListHead -> Flink = OldFlink ;
126
131
}
127
-
132
+ #ifdef ARM3_COLORS
133
+ /* Get the page color */
134
+ OldBlink = MiGetPfnEntryIndex (Entry );
135
+ Color = OldBlink & MmSecondaryColorMask ;
136
+ DPRINT1 ("Color: %lx\n" , Color );
137
+
138
+ /* Get the first page on the color list */
139
+ ColorTable = & MmFreePagesByColor [ListName ][Color ];
140
+ DPRINT1 ("Color table: %p %lx\n" , ColorTable , ColorTable -> Flink );
141
+
142
+ /* Check if this was was actually the head */
143
+ OldFlink = ColorTable -> Flink ;
144
+ if (OldFlink == OldBlink )
145
+ {
146
+ /* Make the table point to the next page this page was linking to */
147
+ ColorTable -> Flink = Entry -> OriginalPte .u .Long ;
148
+ if (ColorTable -> Flink != LIST_HEAD )
149
+ {
150
+ /* And make the previous link point to the head now */
151
+ MiGetPfnEntry (ColorTable -> Flink )-> u4 .PteFrame = -1 ;
152
+ }
153
+ else
154
+ {
155
+ /* And if that page was the head, loop the list back around */
156
+ ColorTable -> Blink = (PVOID )LIST_HEAD ;
157
+ }
158
+ }
159
+ else
160
+ {
161
+ /* This page shouldn't be pointing back to the head */
162
+ ASSERT (Entry -> u4 .PteFrame != -1 );
163
+
164
+ /* Make the back link point to whoever the next page is */
165
+ Pfn1 = MiGetPfnEntry (Entry -> u4 .PteFrame );
166
+ Pfn1 -> OriginalPte .u .Long = Entry -> OriginalPte .u .Long ;
167
+
168
+ /* Check if this page was pointing to the head */
169
+ if (Entry -> OriginalPte .u .Long != LIST_HEAD )
170
+ {
171
+ /* Make the back link point to the head */
172
+ Pfn1 = MiGetPfnEntry (Entry -> OriginalPte .u .Long );
173
+ Pfn1 -> u4 .PteFrame = -1 ;
174
+ }
175
+ else
176
+ {
177
+ /* Then the table is directly back pointing to this page now */
178
+ ColorTable -> Blink = Pfn1 ;
179
+ }
180
+ }
181
+
182
+ /* One less colored page */
183
+ ASSERT (ColorTable -> Count >= 1 );
184
+ ColorTable -> Count -- ;
185
+ #endif
128
186
/* We are not on a list anymore */
129
187
Entry -> u1 .Flink = Entry -> u2 .Blink = 0 ;
130
188
ASSERT_LIST_INVARIANT (ListHead );
131
189
132
- /* FIXME: Deal with color list */
133
-
134
190
/* See if we hit any thresholds */
135
191
if (MmAvailablePages == MmHighMemoryThreshold )
136
192
{
@@ -160,9 +216,9 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
160
216
MMLISTS ListName ;
161
217
PFN_NUMBER OldFlink , OldBlink ;
162
218
ULONG OldColor , OldCache ;
163
- #if 0
219
+ #ifdef ARM3_COLORS
164
220
PMMCOLOR_TABLES ColorTable ;
165
- #endif
221
+ #endif
166
222
/* Make sure PFN lock is held */
167
223
ASSERT (KeGetCurrentIrql () == DISPATCH_LEVEL );
168
224
ASSERT (Color < MmSecondaryColors );
@@ -221,27 +277,31 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
221
277
Pfn1 -> u3 .e2 .ShortFlags = 0 ;
222
278
Pfn1 -> u3 .e1 .PageColor = OldColor ;
223
279
Pfn1 -> u3 .e1 .CacheAttribute = OldCache ;
224
-
225
- #if 0 // When switching to ARM3
280
+ #ifdef ARM3_COLORS
226
281
/* Get the first page on the color list */
282
+ ASSERT (Color < MmSecondaryColors );
227
283
ColorTable = & MmFreePagesByColor [ListName ][Color ];
228
284
ASSERT (ColorTable -> Count >= 1 );
229
285
230
286
/* Set the forward link to whoever we were pointing to */
287
+ DPRINT1 ("Has RMAP: %lx (link: %lx)\n" , Pfn1 -> u3 .e1 .ParityError , Pfn1 -> OriginalPte .u .Long );
288
+ DPRINT1 ("Color table: %p %lx\n" , ColorTable , ColorTable -> Flink );
231
289
ColorTable -> Flink = Pfn1 -> OriginalPte .u .Long ;
290
+
291
+ /* Get the first page on the color list */
232
292
if (ColorTable -> Flink == LIST_HEAD )
233
293
{
234
294
/* This is the beginning of the list, so set the sentinel value */
235
- ColorTable -> Blink = LIST_HEAD ;
295
+ ColorTable -> Blink = ( PVOID ) LIST_HEAD ;
236
296
}
237
297
else
238
298
{
239
299
/* The list is empty, so we are the first page */
240
300
MiGetPfnEntry (ColorTable -> Flink )-> u4 .PteFrame = -1 ;
241
301
}
242
302
243
- /* One more page */
244
- ColorTable -> Total ++ ;
303
+ /* One less page */
304
+ ColorTable -> Count -- ;
245
305
#endif
246
306
/* See if we hit any thresholds */
247
307
if (MmAvailablePages == MmHighMemoryThreshold )
@@ -404,7 +464,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
404
464
PMMPFNLIST ListHead ;
405
465
PFN_NUMBER LastPage ;
406
466
PMMPFN Pfn1 ;
407
- #if 0
467
+ #ifdef ARM3_COLORS
408
468
ULONG Color ;
409
469
PMMPFN Blink ;
410
470
PMMCOLOR_TABLES ColorTable ;
@@ -473,13 +533,15 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
473
533
/* Otherwise check if we reached the high threshold and signal the event */
474
534
KeSetEvent (MiHighMemoryEvent , 0 , FALSE);
475
535
}
476
-
477
- #if 0 // When using ARM3 PFN
536
+ #ifdef ARM3_COLORS
478
537
/* Get the page color */
479
538
Color = PageFrameIndex & MmSecondaryColorMask ;
539
+ DPRINT1 ("Color: %lx\n" , Color );
480
540
481
541
/* Get the first page on the color list */
482
542
ColorTable = & MmFreePagesByColor [FreePageList ][Color ];
543
+ DPRINT1 ("Color table: %p %lx\n" , ColorTable , ColorTable -> Flink );
544
+ DPRINT1 ("Has RMAP: %lx (link: %lx)\n" , Pfn1 -> u3 .e1 .ParityError , Pfn1 -> OriginalPte .u .Long );
483
545
if (ColorTable -> Flink == LIST_HEAD )
484
546
{
485
547
/* The list is empty, so we are the first page */
@@ -492,18 +554,24 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
492
554
Blink = (PMMPFN )ColorTable -> Blink ;
493
555
494
556
/* Make it link to us */
495
- Pfn1 -> u4 .PteFrame = MI_PFNENTRY_TO_PFN (Blink );
557
+ Pfn1 -> u4 .PteFrame = MiGetPfnEntryIndex (Blink );
558
+
559
+ /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
560
+ DPRINT1 ("Has RMAP: %lx (link: %lx)\n" , Blink -> u3 .e1 .ParityError , Blink -> OriginalPte .u .Long );
561
+ ASSERT (Blink -> u3 .e1 .ParityError == FALSE);
496
562
Blink -> OriginalPte .u .Long = PageFrameIndex ;
497
563
}
498
564
499
565
/* Now initialize our own list pointers */
500
566
ColorTable -> Blink = Pfn1 ;
567
+
568
+ /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
569
+ ASSERT (Pfn1 -> u3 .e1 .ParityError == FALSE);
501
570
Pfn1 -> OriginalPte .u .Long = LIST_HEAD ;
502
571
503
572
/* And increase the count in the colored list */
504
573
ColorTable -> Count ++ ;
505
574
#endif
506
-
507
575
/* Notify zero page thread if enough pages are on the free list now */
508
576
if ((ListHead -> Total >= 8 ) && !(MmZeroingPageThreadActive ))
509
577
{
@@ -522,7 +590,10 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
522
590
PFN_NUMBER Flink ;
523
591
PMMPFN Pfn1 , Pfn2 ;
524
592
MMLISTS ListName ;
525
-
593
+ #ifdef ARM3_COLORS
594
+ PMMCOLOR_TABLES ColorHead ;
595
+ ULONG Color ;
596
+ #endif
526
597
/* For free pages, use MiInsertPageInFreeList */
527
598
ASSERT (ListHead != & MmFreePageListHead );
528
599
@@ -585,8 +656,47 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
585
656
/* Otherwise check if we reached the high threshold and signal the event */
586
657
KeSetEvent (MiHighMemoryEvent , 0 , FALSE);
587
658
}
659
+
660
+ #ifdef ARM3_COLORS
661
+ ASSERT (ListName == ZeroedPageList );
662
+ ASSERT (Pfn1 -> u4 .InPageError == 0 );
663
+
664
+ /* Get the page color */
665
+ Color = PageFrameIndex & MmSecondaryColorMask ;
666
+ DPRINT1 ("Color: %lx\n" , Color );
667
+
668
+ /* Get the list for this color */
669
+ ColorHead = & MmFreePagesByColor [ZeroedPageList ][Color ];
670
+
671
+ /* Get the old head */
672
+ Flink = ColorHead -> Flink ;
673
+
674
+ /* If there is an original pte, it should be an old link, NOT a ReactOS RMAP */
675
+ ASSERT (Pfn1 -> u3 .e1 .ParityError == FALSE);
588
676
589
- /* FIXME: Color code handling */
677
+ /* Make this page point back to the list, and point forwards to the old head */
678
+ Pfn1 -> OriginalPte .u .Long = Flink ;
679
+ Pfn1 -> u4 .PteFrame = -1 ;
680
+
681
+ /* Set the new head */
682
+ ColorHead -> Flink = PageFrameIndex ;
683
+
684
+ /* Was the head empty? */
685
+ if (Flink != LIST_HEAD )
686
+ {
687
+ /* No, so make the old head point to this page */
688
+ Pfn2 = MiGetPfnEntry (Flink );
689
+ Pfn2 -> u4 .PteFrame = PageFrameIndex ;
690
+ }
691
+ else
692
+ {
693
+ /* Yes, make it loop back to this page */
694
+ ColorHead -> Blink = (PVOID )Pfn1 ;
695
+ }
696
+
697
+ /* One more paged on the colored list */
698
+ ColorHead -> Count ++ ;
699
+ #endif
590
700
}
591
701
592
702
VOID
0 commit comments