MiProcessWorkingSets
VOID __stdcall MiProcessWorkingSets(_MI_PARTITION *Partition, _MMWS_TRIM_CRITERIA *TrimCriteria){
_MI_PARTITION *v3;
_KEVENT *WorkingSetControl;
int v5;
_LIST_ENTRY *p_Blink;
_MMWS_TRIM_CRITERIA *v7;
__int64 *v8;
int v9;
unsigned __int16 v10;
__int64 *v11;
__int64 v12;
_MMSUPPORT_INSTANCE *v13;
__int64 *v14;
int v15;
_KSPIN_LOCK_QUEUE *volatile Next;
struct _KPRCB *CurrentPrcb;
int v18;
unsigned __int8 CurrentIrql;
int v20;
_MMSUPPORT_FLAGS v21;
__int64 PartitionId;
__int64 v23;
__int64 **v24;
_KGATE *ExitOutswapGate;
_LIST_ENTRY *v26;
_LIST_ENTRY *p_WorkingSetExpansionLinks;
__int64 *v28;
_QWORD *p_Flink;
char v30;
unsigned int v31;
int v32;
__int64 v33;
_BYTE *v34;
_QWORD *v35;
_QWORD *v36;
int Blink;
_MMSUPPORT_INSTANCE *v38;
__int64 v39;
_QWORD *v40;
__int64 v41;
__int64 v42;
__int64 **v43;
unsigned __int64 WorkingSetSize;
unsigned __int64 MinimumWorkingSetSize;
NTSTATUS v46;
unsigned int WorkingSetRequestFlags;
int WorkingSetRequestFlags_4;
unsigned int v49;
int v50;
PRKEVENT Event;
_KLOCK_QUEUE_HANDLE LockHandle;
unsigned __int16 v55;
_MMSUPPORT_FLAGS Flags;
unsigned __int16 v57;
_MMSUPPORT_FLAGS v58;
_MMSUPPORT_FLAGS v59;
v3 = Partition;
memset(&LockHandle, 0, sizeof(LockHandle));
if( Partition->Core.MemoryConfigurationChanged )
MiInitializeWorkingSetManagerParameters(Partition);
if( (v3->Core.u.LongFlags & 0x20) != 0 )
return;
WorkingSetControl = (_KEVENT *)v3->WorkingSetControl;
Event = WorkingSetControl;
MiComputeAgingPercent(v3);
WorkingSetRequestFlags = MiComputeSystemTrimCriteria(v3, TrimCriteria);
v5 = WorkingSetRequestFlags;
MiLogProcessWorkingSetsStart((INT64)v3, (INT64)TrimCriteria, WorkingSetRequestFlags);
if( (WorkingSetRequestFlags & 5) != 0 )
MiDrainZeroLookasides(v3, 0i64, 0i64, 0i64);
WorkingSetRequestFlags_4 = 0;
v49 = 0;
if( (WorkingSetRequestFlags & 5) != 0 )
*((_BYTE *)WorkingSetControl + 52) = 1;
if( (WorkingSetRequestFlags & 2) != 0 )
++*((_DWORD *)WorkingSetControl + 21);
p_Blink = 0i64;
if( (WorkingSetRequestFlags & 0x40) != 0 )
{
if( *((_WORD *)WorkingSetControl + 1173) > 0xAu )
*((_WORD *)WorkingSetControl + 1173) = 10;
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)&stru_140C4DB30 + 522, &LockHandle);
if( *((_BYTE *)WorkingSetControl + 54) == 1 )
{
v34 = v3->gap1AC8;
*((_BYTE *)WorkingSetControl + 54) = 0;
v35 = *(_QWORD **)v3->gap1AC8;
if( v35 != (_QWORD *)v3->gap1AC8 )
{
do
{
v36 = v35;
v35 = (_QWORD *)*v35;
if( v36[9] >= *((_QWORD *)WorkingSetControl + 7) )
{
v39 = *v36;
v40 = (_QWORD *)v36[1];
if( *(_QWORD **)(*v36 + 8i64) != v36
|| (_QWORD *)*v40 != v36
|| (*v40 = v39, *(_QWORD *)(v39 + 8) = v40,
v41 = *(_QWORD *)v34,
*(_BYTE **)(*(_QWORD *)v34 + 8i64) != v34) )
{
LABEL_77:
__fastfail(3u);
}
*v36 = v41;
v36[1] = v34;
*(_QWORD *)(v41 + 8) = v36;
*(_QWORD *)v34 = v36;
}
}
while( v35 != (_QWORD *)v34 );
}
}
}
else
{
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)&stru_140C4DB30 + 522, &LockHandle);
}
v7 = TrimCriteria;
v8 = (__int64 *)v3->gap1AC8;
*((_BYTE *)WorkingSetControl + 53) = 1;
LABEL_13:
while( 2 )
{
v9 = 0;
v50 = v5 & 1;
if( (v5 & 1) != 0 )
{
LODWORD(v42) = MiOrderTrimList(v3, *((unsigned __int8 *)MiTrimPassToAge + (v7->_bf_0 & 0x7F)));
v7 = TrimCriteria;
*(_QWORD *)&TrimCriteria[1].PagesTrimmed = v42;
}
v10 = ++*((_WORD *)WorkingSetControl + 1172);
*(_QWORD *)&v7[1].ClaimDistribution[6] = *(_QWORD *)&v7[1].ClaimDistribution[4] - *(_QWORD *)&v7[1].PagesToTrim;
v55 = v10;
while( 1 )
{
v11 = (__int64 *)*v8;
if( (__int64 *)*v8 == v8 )
goto LABEL_41;
v12 = *v11;
if( (__int64 *)v11[1] != v8 || *(__int64 **)(v12 + 8) != v11 )
goto LABEL_77;
*v8 = v12;
v13 = (_MMSUPPORT_INSTANCE *)(v11 - 3);
*(_QWORD *)(v12 + 8) = v8;
v14 = v11;
*v11 = 0i64;
if( *((_WORD *)v11 + 74) == v10 )
{
v28 = (__int64 *)*v8;
p_Flink = &v13->WorkingSetExpansionLinks.Flink;
if( *(__int64 **)(*v8 + 8) != v8 )
goto LABEL_77;
v3 = Partition;
*p_Flink = v28;
p_Flink[1] = v8;
v28[1] = (__int64)p_Flink;
*v8 = (__int64)p_Flink;
if( !v50 )
goto LABEL_44;
v46 = MiCheckSystemTrimEndCriteria(Partition, v7, &LockHandle);
v7 = TrimCriteria;
WorkingSetControl = Event;
if( v46 )
goto LABEL_44;
goto LABEL_13;
}
v13->LastTrimStamp = v10;
v15 = v5 & 0x40;
if( (v5 & 0x40) != 0 && v13->AgeDistribution[7] < *((_QWORD *)Event + 7) )
break;
if( v13->WorkingSetSize > 1 || (v13->Flags._bf_0 & 7) != 0 )
{
Flags = v13->Flags;
Flags._bf_1 = Flags._bf_1 & 0xF9 | 2;
v13->Flags.u1 = Flags.u1;
if( v7->TrimReason == 2 )
{
WorkingSetSize = v13->WorkingSetSize;
MinimumWorkingSetSize = v13->MinimumWorkingSetSize;
if( WorkingSetSize <= MinimumWorkingSetSize || WorkingSetSize - MinimumWorkingSetSize < 0x40000 )
goto LABEL_30;
}
_m_prefetchw(&LockHandle);
Next = LockHandle.LockQueue.Next;
if( !LockHandle.LockQueue.Next )
{
Next = (_KSPIN_LOCK_QUEUE *volatile)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockHandle.LockQueue.Lock,
0i64,
(signed __int64)&LockHandle);
if( Next == (_KSPIN_LOCK_QUEUE *volatile)&LockHandle )
goto LABEL_25;
Next = KxWaitForLockChainValid(&LockHandle.LockQueue);
v7 = TrimCriteria;
}
LockHandle.LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
LABEL_25:
CurrentPrcb = KeGetCurrentPrcb();
if( CurrentPrcb->SchedulerAssist && CurrentPrcb->NestingLevel <= 1u && !(_DWORD)Next )
v7 = TrimCriteria;
__writecr8(LockHandle.OldIrql);
v5 = WorkingSetRequestFlags;
MiTrimOrAgeWorkingSet(v13, v7, WorkingSetRequestFlags);
v9 = v18;
if( v18 == 1 )
TrimCriteria->AgingPolicy = 2;
LockHandle.LockQueue.Lock = (unsigned __int64 *volatile)((char *)&stru_140C4DB30 + 4176);
LockHandle.LockQueue.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LockHandle.OldIrql = CurrentIrql;
if( _InterlockedExchange64((_QWORD *)&stru_140C4DB30 + 522, (__int64)&LockHandle) )
KxWaitForLockOwnerShip((INT64)&LockHandle);
LABEL_30:
if( !v15 || (v20 = 0, v13->AgeDistribution[7] < *((_QWORD *)Event + 7)) || v13->ExitOutswapGate )
v20 = 1;
v21 = v13->Flags;
LOBYTE(v57) = v21.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0;
if( v20 )
{
HIBYTE(v57) = v21._bf_1 & 0xF9;
v13->Flags.u1 = v57;
PartitionId = v13->PartitionId;
v23 = *(_QWORD *)(*(&stru_140C4DB30 + 267) + 8 * PartitionId) + 6856i64;
v24 = *(__int64 ***)(*(_QWORD *)(*(&stru_140C4DB30 + 267) + 8 * PartitionId) + 6864i64);
if( *v24 != (__int64 *)v23 )
goto LABEL_77;
*v14 = v23;
v14[1] = (__int64)v24;
*v24 = v14;
*(_QWORD *)(v23 + 8) = v14;
ExitOutswapGate = v13->ExitOutswapGate;
if( ExitOutswapGate )
KeSignalGate(ExitOutswapGate, 1i64);
}
else
{
v13->WorkingSetExpansionLinks.Blink = p_Blink;
HIBYTE(v57) = v21._bf_1 | 6;
p_Blink = (_LIST_ENTRY *)&v13->WorkingSetExpansionLinks.Blink;
v13->Flags.u1 = v57;
}
v7 = TrimCriteria;
if( v9 == 1 )
goto LABEL_41;
v10 = v55;
}
else if( v13->ExitOutswapGate )
{
v43 = (__int64 **)v8[1];
if( *v43 != v8 )
goto LABEL_77;
*v14 = (__int64)v8;
v14[1] = (__int64)v43;
*v43 = v14;
v8[1] = (__int64)v14;
}
else
{
v58 = v13->Flags;
v58._bf_1 |= 6u;
v13->Flags.u1 = v58.u1;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
KeRetryOutswapProcess((_KPROCESS *)&v13[-9].AgeDistribution[3]);
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)&stru_140C4DB30 + 522, &LockHandle);
v59 = v13->Flags;
v59._bf_1 &= 0xF9u;
v13->Flags.u1 = v59.u1;
MiReturnWsToExpansionList(v13, 0i64);
v10 = v55;
v7 = TrimCriteria;
v5 = WorkingSetRequestFlags;
}
}
v26 = (_LIST_ENTRY *)v8[1];
p_WorkingSetExpansionLinks = &v13->WorkingSetExpansionLinks;
if( (__int64 *)v26->Flink != v8 )
goto LABEL_77;
p_WorkingSetExpansionLinks->Flink = (_LIST_ENTRY *)v8;
p_WorkingSetExpansionLinks->Blink = v26;
v26->Flink = p_WorkingSetExpansionLinks;
v8[1] = (__int64)p_WorkingSetExpansionLinks;
LABEL_41:
v3 = Partition;
LABEL_44:
if( (v5 & 0x40) != 0 )
{
while( p_Blink )
{
Blink = (int)p_Blink[9].Blink;
v38 = (_MMSUPPORT_INSTANCE *)&p_Blink[-2];
p_Blink = p_Blink->Flink;
v38->Flags.u1 = Blink & 0xF9FF;
MiReturnWsToExpansionList(v38, 1ui64);
}
v7 = TrimCriteria;
}
WorkingSetControl = Event;
v30 = v5 | WorkingSetRequestFlags_4;
WorkingSetRequestFlags_4 |= v5;
if( v9 != 1 )
{
v31 = v5 & 0xFFFFFF3C | v49;
v32 = *((_DWORD *)Event + 10);
v49 = v31;
if( v31 == v32 )
{
*((_BYTE *)Event + 53) = 0;
if( (v30 & 5) != 0 )
*((_BYTE *)Event + 52) = 0;
if( v32 )
{
*((_DWORD *)Event + 10) = 0;
KeSetEvent(Event, 0, 0);
}
if( (v30 & 0x83) != 0 )
{
*((_QWORD *)Event + 302) = *(_QWORD *)TrimCriteria->ClaimDistribution;
*((_QWORD *)Event + 303) = *(_QWORD *)&TrimCriteria->ClaimDistribution[2];
*((_QWORD *)Event + 304) = *(_QWORD *)&TrimCriteria->ClaimDistribution[4];
*((_QWORD *)Event + 305) = *(_QWORD *)&TrimCriteria->ClaimDistribution[6];
*((_QWORD *)Event + 306) = *(_QWORD *)&TrimCriteria->PagesToTrim;
*((_QWORD *)Event + 307) = *(_QWORD *)&TrimCriteria->PagesTrimmed;
*((_QWORD *)Event + 308) = *(_QWORD *)&TrimCriteria[1]._bf_0;
v33 = *(_QWORD *)TrimCriteria[1].ClaimDistribution;
*((_QWORD *)Event + 309) = v33;
*((_QWORD *)Event + 301) = *((_QWORD *)Event + 308) + v33;
}
goto LABEL_53;
}
v5 = v31 ^ v32;
WorkingSetRequestFlags = v5;
if( (v5 & 5) != 0 )
*((_BYTE *)Event + 52) = 1;
v7->TrimReason = 6;
continue;
}
break;
}
*((_BYTE *)Event + 53) = 0;
if( (v30 & 5) != 0 )
*((_BYTE *)Event + 52) = 0;
LABEL_53:
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
MiLogProcessWorkingSetsStop(v3);
}Referenced by:
MiWorkingSetManager