diff --git a/src/core/worker.c b/src/core/worker.c
index 6338834413..db9977a91f 100644
--- a/src/core/worker.c
+++ b/src/core/worker.c
@@ -96,13 +96,10 @@ QuicWorkerInitialize(
Worker->ExecutionContext.NextTimeUs = UINT64_MAX;
Worker->ExecutionContext.Ready = TRUE;
-#ifndef _KERNEL_MODE // Not supported on kernel mode
if (ExecProfile != QUIC_EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT) {
Worker->IsExternal = TRUE;
CxPlatAddExecutionContext(&MsQuicLib.WorkerPool, &Worker->ExecutionContext, PartitionIndex);
- } else
-#endif // _KERNEL_MODE
- {
+ } else {
uint16_t ThreadFlags;
switch (ExecProfile) {
default:
diff --git a/src/inc/quic_platform.h b/src/inc/quic_platform.h
index 4b265bf302..a0643d3110 100644
--- a/src/inc/quic_platform.h
+++ b/src/inc/quic_platform.h
@@ -436,11 +436,13 @@ typedef struct CXPLAT_WORKER_POOL {
} CXPLAT_WORKER_POOL;
+_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatWorkerPoolInit(
_In_ CXPLAT_WORKER_POOL* WorkerPool
);
+_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatWorkerPoolUninit(
_In_ CXPLAT_WORKER_POOL* WorkerPool
@@ -519,6 +521,7 @@ typedef struct CXPLAT_EXECUTION_CONTEXT {
} CXPLAT_EXECUTION_CONTEXT;
+_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatAddExecutionContext(
_In_ CXPLAT_WORKER_POOL* WorkerPool,
@@ -526,6 +529,7 @@ CxPlatAddExecutionContext(
_In_ uint16_t Index // Into the execution config processor array
);
+_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatWakeExecutionContext(
_In_ CXPLAT_EXECUTION_CONTEXT* Context
diff --git a/src/inc/quic_platform_winkernel.h b/src/inc/quic_platform_winkernel.h
index 18840d5be6..60fbdecc4b 100644
--- a/src/inc/quic_platform_winkernel.h
+++ b/src/inc/quic_platform_winkernel.h
@@ -514,6 +514,7 @@ typedef struct CXPLAT_SQE {
XDP_OVERLAPPED Overlapped;
} CXPLAT_SQE;
+_IRQL_requires_max_(PASSIVE_LEVEL)
inline
BOOLEAN
CxPlatEventQInitialize(
@@ -526,6 +527,7 @@ CxPlatEventQInitialize(
return TRUE;
}
+_IRQL_requires_max_(PASSIVE_LEVEL)
inline
void
CxPlatEventQCleanup(
@@ -537,6 +539,7 @@ CxPlatEventQCleanup(
CxPlatLockUninitialize(&queue->Lock);
}
+_IRQL_requires_max_(PASSIVE_LEVEL)
inline
BOOLEAN
CxPlatEventQAssociateHandle(
@@ -578,6 +581,7 @@ CxPlatEventQEnqueue(
return TRUE;
}
+_IRQL_requires_max_(PASSIVE_LEVEL)
inline
uint32_t
CxPlatEventQDequeue(
@@ -617,6 +621,7 @@ CxPlatEventQDequeue(
return EventsDequeued;
}
+_IRQL_requires_max_(PASSIVE_LEVEL)
inline
void
CxPlatEventQReturn(
diff --git a/src/platform/datapath_winkernel.c b/src/platform/datapath_winkernel.c
index d06ec1e963..f61bda2ff8 100644
--- a/src/platform/datapath_winkernel.c
+++ b/src/platform/datapath_winkernel.c
@@ -688,6 +688,11 @@ DataPathInitialize(
goto Exit;
}
+ if (!CxPlatWorkerPoolLazyStart(WorkerPool, Config)) {
+ Status = QUIC_STATUS_OUT_OF_MEMORY;
+ goto Exit;
+ }
+
DatapathLength =
sizeof(CXPLAT_DATAPATH) +
CxPlatProcCount() * sizeof(CXPLAT_DATAPATH_PROC_CONTEXT);
diff --git a/src/platform/platform.kernel.vcxproj b/src/platform/platform.kernel.vcxproj
index 03e1df6a61..5676ee7fb6 100644
--- a/src/platform/platform.kernel.vcxproj
+++ b/src/platform/platform.kernel.vcxproj
@@ -30,10 +30,10 @@
-
+
diff --git a/src/platform/platform_internal.h b/src/platform/platform_internal.h
index e5815aba69..50a7b6adfd 100644
--- a/src/platform/platform_internal.h
+++ b/src/platform/platform_internal.h
@@ -802,8 +802,9 @@ CxPlatCryptUninitialize(
//
// Platform Worker APIs
-//
+//
+_IRQL_requires_max_(PASSIVE_LEVEL)
BOOLEAN
CxPlatWorkerPoolLazyStart(
_In_ CXPLAT_WORKER_POOL* WorkerPool,
diff --git a/src/platform/platform_worker.c b/src/platform/platform_worker.c
index 8645efb626..d65fab8c6a 100644
--- a/src/platform/platform_worker.c
+++ b/src/platform/platform_worker.c
@@ -106,6 +106,7 @@ typedef struct QUIC_CACHEALIGN CXPLAT_WORKER {
CXPLAT_THREAD_CALLBACK(CxPlatWorkerThread, Context);
+_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatWorkerPoolInit(
_In_ CXPLAT_WORKER_POOL* WorkerPool
@@ -323,7 +324,7 @@ CxPlatWorkerPoolUninit(
CxPlatLockUninitialize(&WorkerPool->WorkerLock);
}
-#ifndef _KERNEL_MODE
+#ifndef _KERNEL_MODE // Not supported on kernel mode
#define DYNAMIC_POOL_PROCESSING_PERIOD 1000000 // 1 second
#define DYNAMIC_POOL_PRUNE_COUNT 8
@@ -387,7 +388,7 @@ CxPlatProcessDynamicPoolAllocators(
CxPlatLockRelease(&Worker->ECLock);
}
-#endif
+#endif // _KERNEL_MODE
CXPLAT_EVENTQ*
CxPlatWorkerPoolGetEventQ(
@@ -400,6 +401,7 @@ CxPlatWorkerPoolGetEventQ(
return &WorkerPool->Workers[Index].EventQ;
}
+_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatAddExecutionContext(
_In_ CXPLAT_WORKER_POOL* WorkerPool,
@@ -426,6 +428,7 @@ CxPlatAddExecutionContext(
}
}
+_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatWakeExecutionContext(
_In_ CXPLAT_EXECUTION_CONTEXT* Context
@@ -437,6 +440,7 @@ CxPlatWakeExecutionContext(
}
}
+_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatUpdateExecutionContexts(
_In_ CXPLAT_WORKER* Worker
@@ -458,6 +462,7 @@ CxPlatUpdateExecutionContexts(
}
}
+_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatRunExecutionContexts(
_In_ CXPLAT_WORKER* Worker,
@@ -515,6 +520,7 @@ CxPlatRunExecutionContexts(
}
}
+_IRQL_requires_max_(PASSIVE_LEVEL)
BOOLEAN
CxPlatProcessEvents(
_In_ CXPLAT_WORKER* Worker,
@@ -599,12 +605,12 @@ CXPLAT_THREAD_CALLBACK(CxPlatWorkerThread, Context)
State.NoWorkCount = 0;
}
-#ifndef _KERNEL_MODE
+#ifndef _KERNEL_MODE // Unnecessary on kernel mode
if (State.TimeNow - State.LastPoolProcessTime > DYNAMIC_POOL_PROCESSING_PERIOD) {
CxPlatProcessDynamicPoolAllocators(Worker);
State.LastPoolProcessTime = State.TimeNow;
}
-#endif
+#endif // _KERNEL_MODE
}
Shutdown: