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=29…
==============================================================================
--- 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;
}