Skip to content

Commit cf9f92d

Browse files
authored
Merge pull request #534 from michbern-ms/Main
Add support to Query-JobLimits.ps1 for querying CPU rate controls
2 parents c521791 + 52cc47d commit cf9f92d

2 files changed

Lines changed: 168 additions & 6 deletions

File tree

helpful_tools/Query-JobLimits/Query-JobLimits.ps1

Lines changed: 112 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
############################################################
22
# Script to query the job limits inside a process-isolated container
33
############################################################
4+
45
<#
56
.NOTES
67
Copyright (c) Microsoft Corporation. All rights reserved.
@@ -19,8 +20,11 @@
1920
.DESCRIPTION
2021
Queries the job limits from inside a process-isolated container
2122
22-
.PARAMETER Verbose
23-
If passed, dump verbose output
23+
.PARAMETER LimitType
24+
Determines the type of limit to query. The following values are supported:
25+
- JobMemoryLimit: Returns the job memory limit in bytes
26+
- PeakJobMemoryUsed: Returns the peak job memory used in bytes
27+
- CpuRateControl: Returns the CPU rate control, if enabled, which is generally a cycle count out of a total of 10000
2428
2529
.EXAMPLE
2630
.\Query-JobLimits.ps1
@@ -30,7 +34,7 @@
3034
[CmdletBinding(DefaultParameterSetName="Standard")]
3135
param(
3236
[Parameter(Mandatory=$True)]
33-
[ValidateSet("JobMemoryLimit", "PeakJobMemoryUsed")]
37+
[ValidateSet("JobMemoryLimit", "PeakJobMemoryUsed", "CpuRateControl")]
3438
[string]$LimitType
3539
)
3640

@@ -55,6 +59,11 @@ Add-Type @"
5559
JobObjectBasicAndIoAccountingInformation,
5660
JobObjectExtendedLimitInformation,
5761
JobObjectJobSetInformation,
62+
JobObjectGroupInformation,
63+
JobObjectNotificationLimitInformation,
64+
JobObjectLimitViolationInformation,
65+
JobObjectGroupInformationEx,
66+
JobObjectCpuRateControlInformation,
5867
MaxJobObjectInfoClass,
5968
}
6069
@@ -80,6 +89,14 @@ Add-Type @"
8089
public const UInt32 JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK = 0x00001000;
8190
public const UInt32 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000;
8291
92+
//
93+
// CPU Rate Control Flags
94+
//
95+
public const UInt32 JOB_OBJECT_CPU_RATE_CONTROL_ENABLE = 0x00000001;
96+
public const UInt32 JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED = 0x00000002;
97+
public const UInt32 JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP = 0x00000004;
98+
public const UInt32 JOB_OBJECT_CPU_RATE_CONTROL_NOTIFY = 0x00000008;
99+
83100
[StructLayout(LayoutKind.Sequential)]
84101
public struct JOBOBJECT_BASIC_LIMIT_INFORMATION
85102
{
@@ -116,6 +133,13 @@ Add-Type @"
116133
public UIntPtr PeakJobMemoryUsed;
117134
}
118135
136+
[StructLayout(LayoutKind.Sequential)]
137+
public struct JOBOBJECT_CPU_RATE_CONTROL_INFORMATION
138+
{
139+
public UInt32 ControlFlags;
140+
public UInt32 Data;
141+
}
142+
119143
[DllImport("kernel32.dll", CharSet = CharSet.Auto, EntryPoint = "QueryInformationJobObject", SetLastError = true)]
120144
public static extern bool QueryInformationJobObject(
121145
IntPtr handleJob,
@@ -137,7 +161,7 @@ Add-Type @"
137161
{
138162
// Marshal.AllocHGlobal will throw on failure, so we do not need to
139163
// check for allocation failure.
140-
ptrData = Marshal.AllocHGlobal( inSize );
164+
ptrData = Marshal.AllocHGlobal( inSize );
141165
UInt32 outSize = 0;
142166
143167
// Query the job object for its extended limits
@@ -168,21 +192,103 @@ Add-Type @"
168192
}
169193
}
170194
}
195+
196+
// Query the CPU rate control info for the running job
197+
// If this is run outside of an executing job, or if the CPU rates are not set,
198+
// the script will return zero.
199+
public static JOBOBJECT_CPU_RATE_CONTROL_INFORMATION QueryCPURateControlInformation()
200+
{
201+
// Allocate an JOBOBJECT_CPU_RATE_CONTROL_INFORMATION
202+
int inSize = Marshal.SizeOf(typeof(Api.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION));
203+
IntPtr ptrData = IntPtr.Zero;
204+
try
205+
{
206+
// Marshal.AllocHGlobal will throw on failure, so we do not need to
207+
// check for allocation failure.
208+
ptrData = Marshal.AllocHGlobal( inSize );
209+
UInt32 outSize = 0;
210+
211+
// Query the job object for its extended limits
212+
bool result = Api.QueryInformationJobObject(IntPtr.Zero,
213+
Api.JOBOBJECTINFOCLASS.JobObjectCpuRateControlInformation,
214+
ptrData,
215+
(UInt32)inSize,
216+
ref outSize);
217+
if (result)
218+
{
219+
// Marshal the result data into a .NET structure
220+
Api.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION jobinfo =
221+
(Api.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION)Marshal.PtrToStructure(ptrData, typeof(Api.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION));
222+
223+
// Return the extended limit information to the caller
224+
return jobinfo;
225+
}
226+
else
227+
{
228+
throw new Win32Exception(Marshal.GetLastWin32Error());
229+
}
230+
}
231+
finally
232+
{
233+
if (ptrData != IntPtr.Zero)
234+
{
235+
Marshal.FreeHGlobal( ptrData );
236+
}
237+
}
238+
}
239+
240+
public static UInt32 GetCpuLimit()
241+
{
242+
JOBOBJECT_CPU_RATE_CONTROL_INFORMATION cpuRateControl = QueryCPURateControlInformation();
243+
244+
// Is CPU rate control enabled?
245+
if ((cpuRateControl.ControlFlags & JOB_OBJECT_CPU_RATE_CONTROL_ENABLE) == 0)
246+
{
247+
Console.WriteLine("# CPU rate control is not enabled.");
248+
return 0;
249+
}
250+
251+
// Is CPU rate control weight-based?
252+
if ((cpuRateControl.ControlFlags & JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED) != 0)
253+
{
254+
Console.WriteLine("# CPU rate control is weight-based.");
255+
return cpuRateControl.Data;
256+
}
257+
258+
// Is CPU rate control hard cap?
259+
if ((cpuRateControl.ControlFlags & JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP) != 0)
260+
{
261+
Console.WriteLine("# CPU rate control is hard cap.");
262+
return cpuRateControl.Data;
263+
}
264+
265+
// Otherwise, default to zero.
266+
return 0;
267+
}
171268
}
172269
173270
"@
174271

175-
$result = [Api]::QueryExtendedLimitInformation()
176-
177272
switch ($LimitType) {
273+
# Returns the job memory limit in bytes
178274
"JobMemoryLimit" {
275+
$result = [Api]::QueryExtendedLimitInformation()
179276
$result.JobMemoryLimit
180277
}
181278

279+
# Returns the peak job memory used in bytes
182280
"PeakJobMemoryUsed" {
281+
$result = [Api]::QueryExtendedLimitInformation()
183282
$result.PeakJobMemoryUsed
184283
}
185284

285+
# Returns the CPU rate control, if enabled,
286+
# which is generally a cycle count out of a total of 10000
287+
"CpuRateControl" {
288+
$result = [Api]::GetCpuLimit()
289+
$result
290+
}
291+
186292
Default {
187293
Write-Error "Limit type unknown: $LimitType"
188294
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
## Query-JobLimits.ps1
2+
3+
#### NAME
4+
Query-JobLimits.ps1
5+
6+
#### SYNOPSIS
7+
Queries the job limits from inside a process-isolated container
8+
9+
#### SYNTAX
10+
Query-JobLimits.ps1 [-LimitType <String>] [<CommonParameters>]
11+
12+
13+
#### DESCRIPTION
14+
Queries the job limits from inside a process-isolated container
15+
16+
Once the container platform has set a CPU or Memory limit, this utility
17+
can be used to query those limits and potentially pass them to processes
18+
or workloads inside the container.
19+
20+
#### PARAMETERS
21+
-LimitType [<String>]
22+
The limit type to query from within the container
23+
24+
Required? True
25+
Position? named
26+
Default value
27+
Accept pipeline input? false
28+
Accept wildcard characters? false
29+
30+
Determines the type of limit to query. The following values are supported:
31+
- JobMemoryLimit: Returns the job memory limit in bytes
32+
- PeakJobMemoryUsed: Returns the peak job memory used in bytes
33+
- CpuRateControl: Returns the CPU rate control, if enabled, which is generally a cycle count out of a total of
34+
10000
35+
36+
#### NOTES
37+
Copyright (c) Microsoft Corporation. All rights reserved.
38+
39+
Use of this sample source code is subject to the terms of the Microsoft
40+
license agreement under which you licensed this sample source code. If
41+
you did not accept the terms of the license agreement, you are not
42+
authorized to use this sample source code. For the terms of the license,
43+
please see the license agreement between you and Microsoft or, if applicable,
44+
see the LICENSE.RTF on your install media or the root of your tools installation.
45+
THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
46+
47+
#### Examples
48+
49+
PS C:\>.\Query-JobLimits.ps1 -LimitType JobMemoryLimit
50+
51+
PS C:\>.\Query-JobLimits.ps1 -LimitType PeakJobMemoryUsed
52+
53+
PS C:\>.\Query-JobLimits.ps1 -LimitType CpuRateControl
54+
55+
#### Prerequisites
56+
Requires PowerShell version 5.0

0 commit comments

Comments
 (0)