Skip to content

Commit f41dde7

Browse files
author
Sir Richard
committed
[NTOS]: Write missing color code in certain PFN functions, and fix existing code where needed. Add some debugging. For now, turned off until testing succeeds.
[NTOS]: Redocument which MMPFN fields are violated by ReactOS-internal values. This has gotten much better than before. svn path=/trunk/; revision=48925
1 parent 119639a commit f41dde7

File tree

3 files changed

+137
-33
lines changed

3 files changed

+137
-33
lines changed

reactos/ntoskrnl/include/internal/mm.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,30 +306,30 @@ typedef struct _MMPFNENTRY
306306
USHORT Modified:1;
307307
USHORT ReadInProgress:1; // StartOfAllocation
308308
USHORT WriteInProgress:1; // EndOfAllocation
309-
USHORT PrototypePte:1; // Zero
310-
USHORT PageColor:4; // LockCount
311-
USHORT PageLocation:3; // Consumer
309+
USHORT PrototypePte:1;
310+
USHORT PageColor:4;
311+
USHORT PageLocation:3;
312312
USHORT RemovalRequested:1;
313-
USHORT CacheAttribute:2; // Type
313+
USHORT CacheAttribute:2;
314314
USHORT Rom:1;
315-
USHORT ParityError:1;
315+
USHORT ParityError:1; // HasRmap
316316
} MMPFNENTRY;
317317

318318
typedef struct _MMPFN
319319
{
320320
union
321321
{
322-
PFN_NUMBER Flink; // ListEntry.Flink
323-
ULONG WsIndex;
322+
PFN_NUMBER Flink;
323+
ULONG WsIndex; // SavedSwapEntry
324324
PKEVENT Event;
325325
NTSTATUS ReadStatus;
326326
SINGLE_LIST_ENTRY NextStackPfn;
327327
} u1;
328-
PMMPTE PteAddress; // ListEntry.Blink
328+
PMMPTE PteAddress;
329329
union
330330
{
331331
PFN_NUMBER Blink;
332-
ULONG_PTR ShareCount; // MapCount
332+
ULONG_PTR ShareCount;
333333
} u2;
334334
union
335335
{
@@ -351,7 +351,7 @@ typedef struct _MMPFN
351351
};
352352
union
353353
{
354-
ULONG_PTR EntireFrame; // SavedSwapEntry
354+
ULONG_PTR EntireFrame;
355355
struct
356356
{
357357
ULONG_PTR PteFrame:25;

reactos/ntoskrnl/mm/ARM3/miarm.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -933,12 +933,6 @@ MiUnlinkFreeOrZeroedPage(
933933
IN PMMPFN Entry
934934
);
935935

936-
PMMPFN
937-
NTAPI
938-
MiRemoveHeadList(
939-
IN PMMPFNLIST ListHead
940-
);
941-
942936
PFN_NUMBER
943937
NTAPI
944938
MiAllocatePfn(

reactos/ntoskrnl/mm/ARM3/pfnlist.c

Lines changed: 127 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
7878
PFN_NUMBER OldFlink, OldBlink;
7979
PMMPFNLIST ListHead;
8080
MMLISTS ListName;
81+
#ifdef ARM3_COLORS
82+
ULONG Color;
83+
PMMCOLOR_TABLES ColorTable;
84+
PMMPFN Pfn1;
85+
#endif
8186

8287
/* Make sure the PFN lock is held */
8388
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
@@ -124,13 +129,64 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
124129
/* Set the list head's backlink instead */
125130
ListHead->Flink = OldFlink;
126131
}
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
128186
/* We are not on a list anymore */
129187
Entry->u1.Flink = Entry->u2.Blink = 0;
130188
ASSERT_LIST_INVARIANT(ListHead);
131189

132-
/* FIXME: Deal with color list */
133-
134190
/* See if we hit any thresholds */
135191
if (MmAvailablePages == MmHighMemoryThreshold)
136192
{
@@ -160,9 +216,9 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
160216
MMLISTS ListName;
161217
PFN_NUMBER OldFlink, OldBlink;
162218
ULONG OldColor, OldCache;
163-
#if 0
219+
#ifdef ARM3_COLORS
164220
PMMCOLOR_TABLES ColorTable;
165-
#endif
221+
#endif
166222
/* Make sure PFN lock is held */
167223
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
168224
ASSERT(Color < MmSecondaryColors);
@@ -221,27 +277,31 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
221277
Pfn1->u3.e2.ShortFlags = 0;
222278
Pfn1->u3.e1.PageColor = OldColor;
223279
Pfn1->u3.e1.CacheAttribute = OldCache;
224-
225-
#if 0 // When switching to ARM3
280+
#ifdef ARM3_COLORS
226281
/* Get the first page on the color list */
282+
ASSERT(Color < MmSecondaryColors);
227283
ColorTable = &MmFreePagesByColor[ListName][Color];
228284
ASSERT(ColorTable->Count >= 1);
229285

230286
/* 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);
231289
ColorTable->Flink = Pfn1->OriginalPte.u.Long;
290+
291+
/* Get the first page on the color list */
232292
if (ColorTable->Flink == LIST_HEAD)
233293
{
234294
/* This is the beginning of the list, so set the sentinel value */
235-
ColorTable->Blink = LIST_HEAD;
295+
ColorTable->Blink = (PVOID)LIST_HEAD;
236296
}
237297
else
238298
{
239299
/* The list is empty, so we are the first page */
240300
MiGetPfnEntry(ColorTable->Flink)->u4.PteFrame = -1;
241301
}
242302

243-
/* One more page */
244-
ColorTable->Total++;
303+
/* One less page */
304+
ColorTable->Count--;
245305
#endif
246306
/* See if we hit any thresholds */
247307
if (MmAvailablePages == MmHighMemoryThreshold)
@@ -404,7 +464,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
404464
PMMPFNLIST ListHead;
405465
PFN_NUMBER LastPage;
406466
PMMPFN Pfn1;
407-
#if 0
467+
#ifdef ARM3_COLORS
408468
ULONG Color;
409469
PMMPFN Blink;
410470
PMMCOLOR_TABLES ColorTable;
@@ -473,13 +533,15 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
473533
/* Otherwise check if we reached the high threshold and signal the event */
474534
KeSetEvent(MiHighMemoryEvent, 0, FALSE);
475535
}
476-
477-
#if 0 // When using ARM3 PFN
536+
#ifdef ARM3_COLORS
478537
/* Get the page color */
479538
Color = PageFrameIndex & MmSecondaryColorMask;
539+
DPRINT1("Color: %lx\n", Color);
480540

481541
/* Get the first page on the color list */
482542
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);
483545
if (ColorTable->Flink == LIST_HEAD)
484546
{
485547
/* The list is empty, so we are the first page */
@@ -492,18 +554,24 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
492554
Blink = (PMMPFN)ColorTable->Blink;
493555

494556
/* 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);
496562
Blink->OriginalPte.u.Long = PageFrameIndex;
497563
}
498564

499565
/* Now initialize our own list pointers */
500566
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);
501570
Pfn1->OriginalPte.u.Long = LIST_HEAD;
502571

503572
/* And increase the count in the colored list */
504573
ColorTable->Count++;
505574
#endif
506-
507575
/* Notify zero page thread if enough pages are on the free list now */
508576
if ((ListHead->Total >= 8) && !(MmZeroingPageThreadActive))
509577
{
@@ -522,7 +590,10 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
522590
PFN_NUMBER Flink;
523591
PMMPFN Pfn1, Pfn2;
524592
MMLISTS ListName;
525-
593+
#ifdef ARM3_COLORS
594+
PMMCOLOR_TABLES ColorHead;
595+
ULONG Color;
596+
#endif
526597
/* For free pages, use MiInsertPageInFreeList */
527598
ASSERT(ListHead != &MmFreePageListHead);
528599

@@ -585,8 +656,47 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
585656
/* Otherwise check if we reached the high threshold and signal the event */
586657
KeSetEvent(MiHighMemoryEvent, 0, FALSE);
587658
}
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);
588676

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
590700
}
591701

592702
VOID

0 commit comments

Comments
 (0)