Author: mnordell Date: Tue Oct 23 14:05:40 2007 New Revision: 29826
URL: http://svn.reactos.org/svn/reactos?rev=29826&view=rev Log: First small attempt at implementing process memory quota. Currently disabled without explicit code modification (enabled by macro) to not modify behaviour of trunk.
Modified: trunk/reactos/ntoskrnl/ps/quota.c
Modified: trunk/reactos/ntoskrnl/ps/quota.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/quota.c?rev=298... ============================================================================== --- trunk/reactos/ntoskrnl/ps/quota.c (original) +++ trunk/reactos/ntoskrnl/ps/quota.c Tue Oct 23 14:05:40 2007 @@ -15,6 +15,12 @@
EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock;
+ +/* Define this macro to enable quota code testing. Once quota code is */ +/* stable and verified, remove this macro and checks for it. */ +/*#define PS_QUOTA_ENABLE_QUOTA_CODE*/ + + /* FUNCTIONS ***************************************************************/
VOID @@ -66,9 +72,29 @@ { /* Don't do anything for the system process */ if (Process == PsInitialSystemProcess) return STATUS_SUCCESS; - + +#ifdef PS_QUOTA_ENABLE_QUOTA_CODE + if (Process) + { + /* TODO: Check with Process->QuotaBlock if this can be satisfied, */ + /* assuming this indeed is the place to check it. */ + /* Probably something like: + if (Process->QuotaUsage[2] + Amount > + Process->QuotaBlock->QuotaEntry[2].Limit) + { + refuse + } + */ + Process->QuotaUsage[2] += Amount; + if (Process->QuotaPeak[2] < Process->QuotaUsage[2]) + { + Process->QuotaPeak[2] = Process->QuotaUsage[2]; + } + } +#else /* Otherwise, not implemented */ UNIMPLEMENTED; +#endif return STATUS_SUCCESS; }
@@ -115,6 +141,38 @@ return PsChargeProcessPoolQuota(Process, PagedPool, Amount); }
+#ifdef PS_QUOTA_ENABLE_QUOTA_CODE +/* + * Internal helper function. + * Returns the index of the Quota* member in EPROCESS for + * a specified pool type, or -1 on failure. + */ +static +INT +PspPoolQuotaIndexFromPoolType(POOL_TYPE PoolType) +{ + switch (PoolType) + { + case NonPagedPool: + case NonPagedPoolMustSucceed: + case NonPagedPoolCacheAligned: + case NonPagedPoolCacheAlignedMustS: + case NonPagedPoolSession: + case NonPagedPoolMustSucceedSession: + case NonPagedPoolCacheAlignedSession: + case NonPagedPoolCacheAlignedMustSSession: + return 1; + case PagedPool: + case PagedPoolCacheAligned: + case PagedPoolSession: + case PagedPoolCacheAlignedSession: + return 0; + default: + return -1; + } +} +#endif + /* * @implemented */ @@ -124,10 +182,32 @@ IN POOL_TYPE PoolType, IN ULONG Amount) { + INT PoolIndex; /* Don't do anything for the system process */ if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
- UNIMPLEMENTED; +#ifdef PS_QUOTA_ENABLE_QUOTA_CODE + PoolIndex = PspPoolQuotaIndexFromPoolType(PoolType); + if (Process && PoolIndex != -1) + { + /* TODO: Check with Process->QuotaBlock if this can be satisfied, */ + /* assuming this indeed is the place to check it. */ + /* Probably something like: + if (Process->QuotaUsage[PoolIndex] + Amount > + Process->QuotaBlock->QuotaEntry[PoolIndex].Limit) + { + refuse + } + */ + Process->QuotaUsage[PoolIndex] += Amount; + if (Process->QuotaPeak[PoolIndex] < Process->QuotaUsage[PoolIndex]) + { + Process->QuotaPeak[PoolIndex] = Process->QuotaUsage[PoolIndex]; + } + } +#else + UNIMPLEMENTED; +#endif return STATUS_SUCCESS; }
@@ -140,10 +220,26 @@ IN POOL_TYPE PoolType, IN ULONG_PTR Amount) { + INT PoolIndex; /* Don't do anything for the system process */ if (Process == PsInitialSystemProcess) return;
- UNIMPLEMENTED; +#ifdef PS_QUOTA_ENABLE_QUOTA_CODE + PoolIndex = PspPoolQuotaIndexFromPoolType(PoolType); + if (Process && PoolIndex != -1) + { + if (Process->QuotaUsage[PoolIndex] < Amount) + { + DPRINT1("WARNING: Process->QuotaUsage sanity check failed.\n"); + } + else + { + Process->QuotaUsage[PoolIndex] -= Amount; + } + } +#else + UNIMPLEMENTED; +#endif }
/* @@ -157,7 +253,11 @@ /* Don't do anything for the system process */ if (Process == PsInitialSystemProcess) return;
- UNIMPLEMENTED; +#ifdef PS_QUOTA_ENABLE_QUOTA_CODE + PsReturnPoolQuota(Process, NonPagedPool, Amount); +#else + UNIMPLEMENTED; +#endif }
/* @@ -171,7 +271,11 @@ /* Don't do anything for the system process */ if (Process == PsInitialSystemProcess) return;
- UNIMPLEMENTED; +#ifdef PS_QUOTA_ENABLE_QUOTA_CODE + PsReturnPoolQuota(Process, PagedPool, Amount); +#else + UNIMPLEMENTED; +#endif }
NTSTATUS @@ -182,8 +286,22 @@ /* Don't do anything for the system process */ if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
+#ifdef PS_QUOTA_ENABLE_QUOTA_CODE + if (Process) + { + if (Process->QuotaUsage[2] < Amount) + { + DPRINT1("WARNING: Process PageFileQuotaUsage sanity check failed.\n"); + } + else + { + Process->QuotaUsage[2] -= Amount; + } + } +#else /* Otherwise, not implemented */ UNIMPLEMENTED; +#endif return STATUS_SUCCESS; }