mirror of
https://github.com/reactos/reactos.git
synced 2025-02-21 16:04:57 +00:00
[NTOS:PS] Implement PS_QUOTA_TYPE and let the quota code use it (#3389)
This will replace the PoolIndex variable and as such we'll only be using the PS_QUOTA_TYPE enumeration, as Windows does. Both QuotaEntry, QuotaUsage and QuotaPeak depend explicitly or implicitly on this enumeration. Further details about this enum can be found in the following articles. https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ps/psquota/type.htm?tx=68,143 https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ps/psquota/block.htm?tx=68,142,143 https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ps/eprocess/index.htm (see QuotaPeak and QuotaUsage)
This commit is contained in:
parent
9536f44c81
commit
6170b574f0
4 changed files with 56 additions and 43 deletions
|
@ -1025,12 +1025,12 @@ QSI_DEF(SystemProcessInformation)
|
|||
SpiCurrent->PageFaultCount = Process->Vm.PageFaultCount;
|
||||
SpiCurrent->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize;
|
||||
SpiCurrent->WorkingSetSize = Process->Vm.WorkingSetSize;
|
||||
SpiCurrent->QuotaPeakPagedPoolUsage = Process->QuotaPeak[0];
|
||||
SpiCurrent->QuotaPagedPoolUsage = Process->QuotaUsage[0];
|
||||
SpiCurrent->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1];
|
||||
SpiCurrent->QuotaNonPagedPoolUsage = Process->QuotaUsage[1];
|
||||
SpiCurrent->PagefileUsage = Process->QuotaUsage[2];
|
||||
SpiCurrent->PeakPagefileUsage = Process->QuotaPeak[2];
|
||||
SpiCurrent->QuotaPeakPagedPoolUsage = Process->QuotaPeak[PsPagedPool];
|
||||
SpiCurrent->QuotaPagedPoolUsage = Process->QuotaUsage[PsPagedPool];
|
||||
SpiCurrent->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[PsNonPagedPool];
|
||||
SpiCurrent->QuotaNonPagedPoolUsage = Process->QuotaUsage[PsNonPagedPool];
|
||||
SpiCurrent->PagefileUsage = Process->QuotaUsage[PsPageFile];
|
||||
SpiCurrent->PeakPagefileUsage = Process->QuotaPeak[PsPageFile];
|
||||
SpiCurrent->PrivatePageCount = Process->CommitCharge;
|
||||
ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(SpiCurrent + 1);
|
||||
|
||||
|
|
|
@ -460,12 +460,12 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
|
|||
VmCounters->PageFaultCount = Process->Vm.PageFaultCount;
|
||||
VmCounters->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize;
|
||||
VmCounters->WorkingSetSize = Process->Vm.WorkingSetSize;
|
||||
VmCounters->QuotaPeakPagedPoolUsage = Process->QuotaPeak[0];
|
||||
VmCounters->QuotaPagedPoolUsage = Process->QuotaUsage[0];
|
||||
VmCounters->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1];
|
||||
VmCounters->QuotaNonPagedPoolUsage = Process->QuotaUsage[1];
|
||||
VmCounters->PagefileUsage = Process->QuotaUsage[2] << PAGE_SHIFT;
|
||||
VmCounters->PeakPagefileUsage = Process->QuotaPeak[2] << PAGE_SHIFT;
|
||||
VmCounters->QuotaPeakPagedPoolUsage = Process->QuotaPeak[PsPagedPool];
|
||||
VmCounters->QuotaPagedPoolUsage = Process->QuotaUsage[PsPagedPool];
|
||||
VmCounters->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[PsNonPagedPool];
|
||||
VmCounters->QuotaNonPagedPoolUsage = Process->QuotaUsage[PsNonPagedPool];
|
||||
VmCounters->PagefileUsage = Process->QuotaUsage[PsPageFile] << PAGE_SHIFT;
|
||||
VmCounters->PeakPagefileUsage = Process->QuotaPeak[PsPageFile] << PAGE_SHIFT;
|
||||
//VmCounters->PrivateUsage = Process->CommitCharge << PAGE_SHIFT;
|
||||
//
|
||||
|
||||
|
|
|
@ -28,38 +28,36 @@ static KSPIN_LOCK PspQuotaLock;
|
|||
|
||||
/*
|
||||
* Private helper to charge the specified process quota.
|
||||
* ReturnsSTATUS_QUOTA_EXCEEDED on quota limit check failure.
|
||||
* Updates QuotaPeak as needed for specified PoolIndex.
|
||||
* TODO: Research and possibly add (the undocumented) enum type PS_QUOTA_TYPE
|
||||
* to replace UCHAR for 'PoolIndex'.
|
||||
* Returns STATUS_QUOTA_EXCEEDED on quota limit check failure.
|
||||
* Updates QuotaPeak as needed for specified quota type in PS_QUOTA_TYPE enum.
|
||||
* Notes: Conceptually translation unit local/private.
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PspChargeProcessQuotaSpecifiedPool(IN PEPROCESS Process,
|
||||
IN UCHAR PoolIndex,
|
||||
IN PS_QUOTA_TYPE QuotaType,
|
||||
IN SIZE_T Amount)
|
||||
{
|
||||
ASSERT(Process);
|
||||
ASSERT(Process != PsInitialSystemProcess);
|
||||
ASSERT(PoolIndex <= 2);
|
||||
ASSERT(QuotaType < PsQuotaTypes);
|
||||
ASSERT(Process->QuotaBlock);
|
||||
|
||||
/* Note: Race warning. TODO: Needs to add/use lock for this */
|
||||
if (Process->QuotaUsage[PoolIndex] + Amount >
|
||||
Process->QuotaBlock->QuotaEntry[PoolIndex].Limit)
|
||||
if (Process->QuotaUsage[QuotaType] + Amount >
|
||||
Process->QuotaBlock->QuotaEntry[QuotaType].Limit)
|
||||
{
|
||||
DPRINT1("Quota exceeded, but ROS will let it slide...\n");
|
||||
return STATUS_SUCCESS;
|
||||
//return STATUS_QUOTA_EXCEEDED; /* caller raises the exception */
|
||||
}
|
||||
|
||||
InterlockedExchangeAdd((LONG*)&Process->QuotaUsage[PoolIndex], Amount);
|
||||
InterlockedExchangeAdd((LONG*)&Process->QuotaUsage[QuotaType], Amount);
|
||||
|
||||
/* Note: Race warning. TODO: Needs to add/use lock for this */
|
||||
if (Process->QuotaPeak[PoolIndex] < Process->QuotaUsage[PoolIndex])
|
||||
if (Process->QuotaPeak[QuotaType] < Process->QuotaUsage[QuotaType])
|
||||
{
|
||||
Process->QuotaPeak[PoolIndex] = Process->QuotaUsage[PoolIndex];
|
||||
Process->QuotaPeak[QuotaType] = Process->QuotaUsage[QuotaType];
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -67,27 +65,25 @@ PspChargeProcessQuotaSpecifiedPool(IN PEPROCESS Process,
|
|||
|
||||
/*
|
||||
* Private helper to remove quota charge from the specified process quota.
|
||||
* TODO: Research and possibly add (the undocumented) enum type PS_QUOTA_TYPE
|
||||
* to replace UCHAR for 'PoolIndex'.
|
||||
* Notes: Conceptually translation unit local/private.
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
PspReturnProcessQuotaSpecifiedPool(IN PEPROCESS Process,
|
||||
IN UCHAR PoolIndex,
|
||||
IN PS_QUOTA_TYPE QuotaType,
|
||||
IN SIZE_T Amount)
|
||||
{
|
||||
ASSERT(Process);
|
||||
ASSERT(Process != PsInitialSystemProcess);
|
||||
ASSERT(PoolIndex <= 2);
|
||||
ASSERT(QuotaType < PsQuotaTypes);
|
||||
ASSERT(!(Amount & 0x80000000)); /* we need to be able to negate it */
|
||||
if (Process->QuotaUsage[PoolIndex] < Amount)
|
||||
if (Process->QuotaUsage[QuotaType] < Amount)
|
||||
{
|
||||
DPRINT1("WARNING: Process->QuotaUsage sanity check failed.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
InterlockedExchangeAdd((LONG*)&Process->QuotaUsage[PoolIndex],
|
||||
InterlockedExchangeAdd((LONG*)&Process->QuotaUsage[QuotaType],
|
||||
-(LONG)Amount);
|
||||
}
|
||||
}
|
||||
|
@ -100,9 +96,9 @@ NTAPI
|
|||
PsInitializeQuotaSystem(VOID)
|
||||
{
|
||||
RtlZeroMemory(&PspDefaultQuotaBlock, sizeof(PspDefaultQuotaBlock));
|
||||
PspDefaultQuotaBlock.QuotaEntry[PagedPool].Limit = (SIZE_T)-1;
|
||||
PspDefaultQuotaBlock.QuotaEntry[NonPagedPool].Limit = (SIZE_T)-1;
|
||||
PspDefaultQuotaBlock.QuotaEntry[2].Limit = (SIZE_T)-1; /* Page file */
|
||||
PspDefaultQuotaBlock.QuotaEntry[PsNonPagedPool].Limit = (SIZE_T)-1;
|
||||
PspDefaultQuotaBlock.QuotaEntry[PsPagedPool].Limit = (SIZE_T)-1;
|
||||
PspDefaultQuotaBlock.QuotaEntry[PsPageFile].Limit = (SIZE_T)-1;
|
||||
PsGetCurrentProcess()->QuotaBlock = &PspDefaultQuotaBlock;
|
||||
}
|
||||
|
||||
|
@ -164,7 +160,7 @@ PsChargeProcessPageFileQuota(IN PEPROCESS Process,
|
|||
/* Don't do anything for the system process */
|
||||
if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
|
||||
|
||||
return PspChargeProcessQuotaSpecifiedPool(Process, 2, Amount);
|
||||
return PspChargeProcessQuotaSpecifiedPool(Process, PsPageFile, Amount);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -284,7 +280,7 @@ PsReturnProcessPageFileQuota(IN PEPROCESS Process,
|
|||
/* Don't do anything for the system process */
|
||||
if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
|
||||
|
||||
PspReturnProcessQuotaSpecifiedPool(Process, 2, Amount);
|
||||
PspReturnProcessQuotaSpecifiedPool(Process, PsPageFile, Amount);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -419,12 +415,12 @@ PspSetQuotaLimits(
|
|||
/* Initialize the quota block */
|
||||
QuotaBlock->ReferenceCount = 1;
|
||||
QuotaBlock->ProcessCount = 1;
|
||||
QuotaBlock->QuotaEntry[0].Peak = Process->QuotaPeak[0];
|
||||
QuotaBlock->QuotaEntry[1].Peak = Process->QuotaPeak[1];
|
||||
QuotaBlock->QuotaEntry[2].Peak = Process->QuotaPeak[2];
|
||||
QuotaBlock->QuotaEntry[0].Limit = PspDefaultQuotaBlock.QuotaEntry[0].Limit;
|
||||
QuotaBlock->QuotaEntry[1].Limit = PspDefaultQuotaBlock.QuotaEntry[1].Limit;
|
||||
QuotaBlock->QuotaEntry[2].Limit = PspDefaultQuotaBlock.QuotaEntry[2].Limit;
|
||||
QuotaBlock->QuotaEntry[PsNonPagedPool].Peak = Process->QuotaPeak[PsNonPagedPool];
|
||||
QuotaBlock->QuotaEntry[PsPagedPool].Peak = Process->QuotaPeak[PsPagedPool];
|
||||
QuotaBlock->QuotaEntry[PsPageFile].Peak = Process->QuotaPeak[PsPageFile];
|
||||
QuotaBlock->QuotaEntry[PsNonPagedPool].Limit = PspDefaultQuotaBlock.QuotaEntry[PsNonPagedPool].Limit;
|
||||
QuotaBlock->QuotaEntry[PsPagedPool].Limit = PspDefaultQuotaBlock.QuotaEntry[PsPagedPool].Limit;
|
||||
QuotaBlock->QuotaEntry[PsPageFile].Limit = PspDefaultQuotaBlock.QuotaEntry[PsPageFile].Limit;
|
||||
|
||||
/* Try to exchange the quota block, if that failed, just drop it */
|
||||
OldQuotaBlock = InterlockedCompareExchangePointer((PVOID*)&Process->QuotaBlock,
|
||||
|
|
|
@ -972,6 +972,23 @@ typedef struct _JOB_SET_ARRAY
|
|||
ULONG Flags;
|
||||
} JOB_SET_ARRAY, *PJOB_SET_ARRAY;
|
||||
|
||||
//
|
||||
// Process Quota Type
|
||||
//
|
||||
typedef enum _PS_QUOTA_TYPE
|
||||
{
|
||||
PsNonPagedPool = 0,
|
||||
PsPagedPool,
|
||||
PsPageFile,
|
||||
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
|
||||
PsWorkingSet,
|
||||
#endif
|
||||
#if (NTDDI_VERSION == NTDDI_LONGHORN)
|
||||
PsCpuRate,
|
||||
#endif
|
||||
PsQuotaTypes
|
||||
} PS_QUOTA_TYPE;
|
||||
|
||||
//
|
||||
// EPROCESS Quota Structures
|
||||
//
|
||||
|
@ -985,7 +1002,7 @@ typedef struct _EPROCESS_QUOTA_ENTRY
|
|||
|
||||
typedef struct _EPROCESS_QUOTA_BLOCK
|
||||
{
|
||||
EPROCESS_QUOTA_ENTRY QuotaEntry[3];
|
||||
EPROCESS_QUOTA_ENTRY QuotaEntry[PsQuotaTypes];
|
||||
LIST_ENTRY QuotaList;
|
||||
ULONG ReferenceCount;
|
||||
ULONG ProcessCount;
|
||||
|
@ -1208,8 +1225,8 @@ typedef struct _EPROCESS
|
|||
EX_RUNDOWN_REF RundownProtect;
|
||||
HANDLE UniqueProcessId;
|
||||
LIST_ENTRY ActiveProcessLinks;
|
||||
SIZE_T QuotaUsage[3]; /* 0=PagedPool, 1=NonPagedPool, 2=Pagefile */
|
||||
SIZE_T QuotaPeak[3]; /* ditto */
|
||||
SIZE_T QuotaUsage[PsQuotaTypes];
|
||||
SIZE_T QuotaPeak[PsQuotaTypes];
|
||||
SIZE_T CommitCharge;
|
||||
SIZE_T PeakVirtualSize;
|
||||
SIZE_T VirtualSize;
|
||||
|
|
Loading…
Reference in a new issue