App Controlled Execution Config (#3034)

This commit is contained in:
Nick Banks 2022-09-30 17:00:02 -04:00 коммит произвёл GitHub
Родитель 2fc5c34e18
Коммит 5b921c9e18
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
63 изменённых файлов: 1028 добавлений и 1025 удалений

Просмотреть файл

@ -178,15 +178,6 @@ stages:
config: Debug
extraName: 'static'
extraBuildArgs: -EnableTelemetryAsserts -Static -ExtraArtifactDir Static
- template: ./templates/build-config-user.yml
parameters:
image: windows-2019
platform: windows
arch: x64
tls: schannel
config: Debug
extraName: 'shared_ec'
extraBuildArgs: -EnableTelemetryAsserts -SharedEC -ExtraArtifactDir shared_ec
- template: ./templates/build-config-user.yml
parameters:
image: windows-2019
@ -334,15 +325,6 @@ stages:
config: Debug
extraName: 'systemopenssl'
extraBuildArgs: -UseSystemOpenSSLCrypto -ExtraArtifactDir SystemCrypto
- template: ./templates/build-config-user.yml
parameters:
image: ubuntu-latest
platform: linux
arch: x64
tls: openssl
config: Debug
extraName: 'shared_ec'
extraBuildArgs: -SharedEC -ExtraArtifactDir shared_ec
- stage: build_linux_nontest
displayName: Build Linux - Non Tested
@ -689,14 +671,6 @@ stages:
platform: windows
tls: schannel
allocFail: 100
- template: ./templates/run-spinquic.yml
parameters:
image: windows-2022
platform: windows
tls: schannel
allocFail: 100
extraArtifactDir: '_shared_ec'
extraTestArgs: -ExtraArtifactDir shared_ec
- template: ./templates/run-spinquic.yml
parameters:
image: windows-2022
@ -738,14 +712,6 @@ stages:
platform: linux
tls: openssl
allocFail: 100
- template: ./templates/run-spinquic.yml
parameters:
image: ubuntu-latest
platform: linux
tls: openssl
allocFail: 100
extraArtifactDir: '_shared_ec'
extraTestArgs: -ExtraArtifactDir shared_ec
- template: ./templates/run-spinquic.yml
parameters:
image: macOS-12

Просмотреть файл

@ -52,10 +52,6 @@ parameters:
type: boolean
displayName: Windows (Schannel)
default: true
- name: winuser_sharedec
type: boolean
displayName: Windows (SharedEC, Schannel)
default: true
- name: winuser_xdp
type: boolean
displayName: Windows (XDP, Schannel)
@ -68,10 +64,6 @@ parameters:
type: boolean
displayName: Linux (OpenSSL)
default: true
- name: linux_sharedec
type: boolean
displayName: Linux (SharedEC, OpenSSL)
default: true
- name: arch
type: string
displayName: Architecture
@ -172,27 +164,6 @@ stages:
${{ if eq(parameters.pgo_mode, true) }}:
extraBuildArgs: -DisableTest -DisableTools -PGO
- ${{ if eq(parameters.winuser_sharedec, true) }}:
- stage: build_winuser_sharedec
displayName: Build Windows (SharedEC)
dependsOn: []
variables:
runCodesignValidationInjection: false
jobs:
- template: ./templates/build-config-user.yml
parameters:
image: windows-latest
platform: windows
arch: ${{ parameters.arch }}
tls: schannel
config: Release
extraName: 'sharedec'
extraPrepareArgs: -DisableTest
${{ if eq(parameters.pgo_mode, false) }}:
extraBuildArgs: -DisableTest -DisableTools -SharedEC -ExtraArtifactDir SharedEC
${{ if eq(parameters.pgo_mode, true) }}:
extraBuildArgs: -DisableTest -DisableTools -SharedEC -ExtraArtifactDir SharedEC -PGO
- ${{ if eq(parameters.winuser_xdp, true) }}:
- stage: build_winuser_xdp
displayName: Build Windows (XDP)
@ -251,27 +222,6 @@ stages:
extraPrepareArgs: -DisableTest
extraBuildArgs: -DisableTest -DisableTools
- ${{ if eq(parameters.linux_sharedec, true) }}:
- stage: build_linux_sharedec
displayName: Build Linux (SharedEC)
dependsOn: []
variables:
runCodesignValidationInjection: false
jobs:
- template: ./templates/build-config-user.yml
parameters:
image: ubuntu-latest
platform: linux
arch: ${{ parameters.arch }}
tls: openssl
config: Release
extraName: 'sharedec'
extraPrepareArgs: -DisableTest
${{ if eq(parameters.pgo_mode, false) }}:
extraBuildArgs: -DisableTest -DisableTools -SharedEC -ExtraArtifactDir SharedEC
${{ if eq(parameters.pgo_mode, true) }}:
extraBuildArgs: -DisableTest -DisableTools -SharedEC -ExtraArtifactDir SharedEC -PGO
#
# Tests
#
@ -327,33 +277,6 @@ stages:
extraArgs: -PGO
failOnRegression: 0
- ${{ if eq(parameters.winuser_sharedec, true) }}:
- stage: perf_winuser_sharedec
displayName: Performance Testing Windows (SharedEC)
dependsOn:
- build_winuser_sharedec
jobs:
- template: ./templates/run-performance.yml
parameters:
pool: MsQuic-Win-Perf
platform: windows
localTls: schannel
remoteTls: schannel
iterations: ${{ parameters.iterations }}
arch: ${{ parameters.arch }}
protocol: ${{ parameters.protocol }}
logProfile: ${{ parameters.logging }}
timeout: ${{ parameters.timeout }}
extraArtifactDir: '_SharedEC'
extraTestArgs: -ExtraArtifactDir _SharedEC
${{ if ne(parameters.testToRun, 'all') }}:
testToRun: ${{ parameters.testToRun }}
${{ if eq(parameters.pgo_mode, false) }}:
extraArgs: -SharedEC -Publish
${{ if eq(parameters.pgo_mode, true) }}:
extraArgs: -SharedEC -PGO
failOnRegression: 0
- ${{ if eq(parameters.winuser_xdp, true) }}:
- stage: perf_winuser_xdp
displayName: Performance Testing Windows (XDP)
@ -372,14 +295,14 @@ stages:
logProfile: ${{ parameters.logging }}
timeout: ${{ parameters.timeout }}
extraArtifactDir: '_Xdp'
extraTestArgs: -ExtraArtifactDir _Xdp
extraTestArgs: -ExtraArtifactDir _Xdp -XDP
${{ if ne(parameters.testToRun, 'all') }}:
testToRun: ${{ parameters.testToRun }}
testTypes: Remote
${{ if eq(parameters.pgo_mode, false) }}:
extraArgs: -XDP -Publish
extraArgs: -Publish
${{ if eq(parameters.pgo_mode, true) }}:
extraArgs: -XDP -PGO
extraArgs: -PGO
failOnRegression: 0
- ${{ if eq(parameters.winuser_openssl, true) }}:
@ -430,35 +353,6 @@ stages:
extraArgs: -PGO
failOnRegression: 0
- ${{ if eq(parameters.linux_sharedec, true) }}:
- stage: perf_linux_sharedec
displayName: Performance Testing Linux (SharedEC)
dependsOn:
- build_linux_sharedec
jobs:
- template: ./templates/run-performance.yml
parameters:
pool: MsQuic-Linux-Perf
platform: linux
localTls: openssl
remoteTls: openssl
iterations: ${{ parameters.iterations }}
arch: ${{ parameters.arch }}
protocol: ${{ parameters.protocol }}
logProfile: ${{ parameters.logging }}
timeout: ${{ parameters.timeout }}
extraArtifactDir: '_SharedEC'
extraTestArgs: -ExtraArtifactDir _SharedEC
${{ if ne(parameters.testToRun, 'all') }}:
testToRun: ${{ parameters.testToRun }}
testTypes: 'Remote'
${{ if eq(parameters.pgo_mode, false) }}:
extraArgs: -SharedEC -Publish
${{ if eq(parameters.pgo_mode, true) }}:
extraArgs: -SharedEC -PGO
failOnRegression: 0
- ${{ if eq(variables['Build.Reason'], 'IndividualCI') }}:
- stage: perf_post_process
displayName: Perf Post Processing
@ -466,10 +360,8 @@ stages:
dependsOn:
- perf_winkernel
- perf_winuser_schannel
- perf_winuser_sharedec
- perf_winuser_xdp
- perf_winuser_openssl
- perf_linux_openssl
- perf_linux_sharedec
jobs:
- template: ./templates/post-process-performance.yml

Просмотреть файл

@ -53,23 +53,6 @@ stages:
extraPrepareArgs: -DisableTest
extraBuildArgs: -DisableTest -DisableTools -PGO
- stage: build_winuser_sharedec
displayName: Build Windows (SharedEC)
dependsOn: []
variables:
runCodesignValidationInjection: false
jobs:
- template: ./templates/build-config-user.yml
parameters:
image: windows-latest
platform: windows
arch: x64
tls: schannel
config: Release
extraName: 'sharedec'
extraPrepareArgs: -DisableTest
extraBuildArgs: -DisableTest -DisableTools -SharedEC -ExtraArtifactDir SharedEC -PGO
- stage: build_winuser_xdp
displayName: Build Windows (XDP)
dependsOn: []
@ -123,24 +106,6 @@ stages:
extraArgs: -PGO
failOnRegression: 0
- stage: perf_winuser_sharedec
displayName: Performance Testing Windows (SharedEC)
dependsOn:
- build_winuser_sharedec
jobs:
- template: ./templates/run-performance.yml
parameters:
pool: MsQuic-Win-Perf
platform: windows
localTls: schannel
remoteTls: schannel
arch: x64
extraArtifactDir: '_SharedEC'
extraTestArgs: -ExtraArtifactDir _SharedEC
testTypes: Remote
extraArgs: -SharedEC -PGO
failOnRegression: 0
- stage: perf_winuser_xdp
displayName: Performance Testing Windows (XDP)
dependsOn:
@ -154,9 +119,9 @@ stages:
remoteTls: schannel
arch: x64
extraArtifactDir: '_Xdp'
extraTestArgs: -ExtraArtifactDir _Xdp
extraTestArgs: -ExtraArtifactDir _Xdp -XDP
testTypes: Remote
extraArgs: -XDP -PGO
extraArgs: -PGO
failOnRegression: 0
- stage: make_pull_request
@ -164,7 +129,6 @@ stages:
dependsOn:
- perf_winuser_schannel
- perf_winuser_openssl
- perf_winuser_sharedec
- perf_winuser_xdp
jobs:
- template: ./templates/make-pgo-pr.yml

4
.github/workflows/test-down-level.yml поставляемый
Просмотреть файл

@ -69,7 +69,7 @@ jobs:
run: |
chmod +x artifacts/bin/linux/${{matrix.arch}}_Release_${{matrix.tls}}/msquictest
$env:LD_LIBRARY_PATH = Join-Path (Get-Location).Path "artifacts/bin/linux/${{matrix.arch}}_Release_${{matrix.tls}}"
scripts/test.ps1 -AZP -Config Release -Arch ${{ matrix.arch }} -Tls ${{ matrix.tls }} -SkipUnitTests -Filter -*CredValidation*:*ConnectClientCertificate*:Basic.StartTwoListenersSameALPN
scripts/test.ps1 -AZP -Config Release -Arch ${{ matrix.arch }} -Tls ${{ matrix.tls }} -SkipUnitTests -Filter -*CredValidation*:*ConnectClientCertificate*:Basic.StartTwoListenersSameALPN:ParameterValidation.ValidateGlobalParam
- name: Run Tests (Windows)
if: runner.os == 'Windows'
run: scripts/test.ps1 -AZP -Config Release -Arch ${{ matrix.arch }} -Tls ${{ matrix.tls }} -SkipUnitTests -Filter -*ValidateConfiguration:*ValidAlpnLengths:*ResumeRejection*:*ConnectClientCertificate*:Basic.StartTwoListenersSameALPN
run: scripts/test.ps1 -AZP -Config Release -Arch ${{ matrix.arch }} -Tls ${{ matrix.tls }} -SkipUnitTests -Filter -*ValidateConfiguration:*ValidAlpnLengths:*ResumeRejection*:*ConnectClientCertificate*:Basic.StartTwoListenersSameALPN:ParameterValidation.ValidateGlobalParam

Просмотреть файл

@ -99,7 +99,6 @@ option(QUIC_SKIP_CI_CHECKS "Disable CI specific build checks" OFF)
option(QUIC_TELEMETRY_ASSERTS "Enable telemetry asserts in release builds" OFF)
option(QUIC_USE_SYSTEM_LIBCRYPTO "Use system libcrypto if openssl TLS" OFF)
option(QUIC_HIGH_RES_TIMERS "Configure the system to use high resolution timers" OFF)
option(QUIC_SHARED_EC "Use shared execution contexts between QUIC and UDP" OFF)
option(QUIC_USE_XDP "Uses XDP instead of socket APIs" OFF)
option(QUIC_DISABLE_POSIX_GSO "Disable GSO for systems that say they support it but don't" OFF)
set(QUIC_FOLDER_PREFIX "" CACHE STRING "Optional prefix for source group folders when using an IDE generator")
@ -323,21 +322,14 @@ if(QUIC_HIGH_RES_TIMERS)
list(APPEND QUIC_COMMON_DEFINES QUIC_HIGH_RES_TIMERS=1)
endif()
if(QUIC_SHARED_EC)
list(APPEND QUIC_COMMON_DEFINES QUIC_USE_EXECUTION_CONTEXTS=1)
endif()
if(QUIC_USE_XDP)
list(APPEND QUIC_COMMON_DEFINES QUIC_USE_EXECUTION_CONTEXTS=1 QUIC_USE_RAW_DATAPATH=1)
list(APPEND QUIC_COMMON_DEFINES QUIC_USE_RAW_DATAPATH=1)
endif()
if(QUIC_TLS STREQUAL "schannel")
message(STATUS "Enabling Schannel configuration tests")
list(APPEND QUIC_COMMON_DEFINES QUIC_TEST_SCHANNEL_FLAGS=1)
if (NOT QUIC_SHARED_EC)
message(STATUS "Enabling UDP Send Queuing")
list(APPEND QUIC_COMMON_DEFINES CXPLAT_DATAPATH_QUEUE_SENDS=1)
endif()
message(STATUS "Disabling PFX tests")
list(APPEND QUIC_COMMON_DEFINES QUIC_DISABLE_PFX_TESTS)
message(STATUS "Disabling 0-RTT support")
@ -383,6 +375,9 @@ if(WIN32)
message(STATUS "Disabling (client) shared port support")
list(APPEND QUIC_COMMON_DEFINES QUIC_DISABLE_SHARED_PORT_TESTS)
message(STATUS "Enabling UDP Send Queuing")
list(APPEND QUIC_COMMON_DEFINES CXPLAT_DATAPATH_QUEUE_SENDS=1)
if (QUIC_UWP_BUILD)
list(APPEND QUIC_COMMON_DEFINES QUIC_UWP_BUILD QUIC_RESTRICTED_BUILD)
set(CMAKE_CXX_STANDARD_LIBRARIES "")
@ -484,10 +479,7 @@ if(WIN32)
set(QUIC_PGO_NAME "msquic.${QUIC_TLS}.xdp.pgd")
set(QUIC_PGO_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/bin/winuser/pgo_${SYSTEM_PROCESSOR}/${QUIC_PGO_NAME}")
endif()
if(NOT EXISTS "${QUIC_PGO_FILE}" AND QUIC_SHARED_EC)
set(QUIC_PGO_NAME "msquic.${QUIC_TLS}.sharedec.pgd")
set(QUIC_PGO_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/bin/winuser/pgo_${SYSTEM_PROCESSOR}/${QUIC_PGO_NAME}")
endif()
if(NOT EXISTS "${QUIC_PGO_FILE}")
set(QUIC_PGO_NAME "msquic.${QUIC_TLS}.pgd")
set(QUIC_PGO_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/bin/winuser/pgo_${SYSTEM_PROCESSOR}/${QUIC_PGO_NAME}")

Просмотреть файл

@ -106,7 +106,7 @@ These parameters are accessed by calling [GetParam](./api/GetParam.md) or [SetPa
| `QUIC_PARAM_GLOBAL_GLOBAL_SETTINGS`<br> 6 | QUIC_GLOBAL_SETTINGS | Both | Globally change global only settings. |
| `QUIC_PARAM_GLOBAL_VERSION_SETTINGS`<br> 7 | QUIC_VERSIONS_SETTINGS | Both | Globally change version settings for all subsequent connections. |
| `QUIC_PARAM_GLOBAL_LIBRARY_GIT_HASH`<br> 8 | char[64] | Get-only | Git hash used to build MsQuic (null terminated string) |
| `QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS`<br> 9 | uint16_t[] | Both | Globally change the list of CPUs that datapath can use. Must be set before opening registration. |
| `QUIC_PARAM_GLOBAL_EXECUTION_CONFIG`<br> 9 | QUIC_EXECUTION_CONFIG | Both | Globally configure the execution model used for QUIC. Must be set before opening registration. |
| `QUIC_PARAM_GLOBAL_TLS_PROVIDER`<br> 10 | QUIC_TLS_PROVIDER | Get-Only | The TLS provider being used by MsQuic for the TLS handshake. |
## Registration Parameters

Просмотреть файл

@ -12,7 +12,7 @@
"Tls": ["schannel", "openssl"],
"Arch": ["x64", "x86", "arm", "arm64"],
"Exe": "secnetperf",
"Arguments": "-test:Throughput -target:$RemoteAddress -bind:$LocalAddress:4434 -ip:4 -uni:1 -timed:1 -upload:12000 -stats:1"
"Arguments": "-exec:maxtput -test:Throughput -target:$RemoteAddress -bind:$LocalAddress:4434 -ip:4 -uni:1 -timed:1 -upload:12000 -stats:1"
},
"Variables": [
{
@ -46,7 +46,7 @@
"Tls": ["schannel", "openssl"],
"Arch": ["x64", "x86", "arm", "arm64"],
"Exe": "secnetperf",
"Arguments": "-test:Throughput -target:$RemoteAddress -bind:$LocalAddress:4434 -ip:4 -uni:1 -timed:1 -upload:12000 -tcp:1"
"Arguments": "-exec:maxtput -test:Throughput -target:$RemoteAddress -bind:$LocalAddress:4434 -ip:4 -uni:1 -timed:1 -upload:12000 -tcp:1"
},
"Variables": [
],
@ -66,7 +66,7 @@
"Tls": ["openssl"],
"Arch": ["x64", "arm"],
"Exe": "secnetperf",
"Arguments": "-test:Throughput -target:$RemoteAddress -uni:1 -timed:1 -upload:12000 -stats:1"
"Arguments": "-exec:maxtput -test:Throughput -target:$RemoteAddress -uni:1 -timed:1 -upload:12000 -stats:1"
},
"Variables": [
{
@ -100,7 +100,7 @@
"Tls": ["schannel", "openssl"],
"Arch": ["x64", "x86", "arm", "arm64"],
"Exe": "secnetperf",
"Arguments": "-test:Throughput -target:$RemoteAddress -bind:$LocalAddress:4434 -ip:4 -uni:1 -timed:1 -download:12000 -stats:1"
"Arguments": "-exec:maxtput -test:Throughput -target:$RemoteAddress -bind:$LocalAddress:4434 -ip:4 -uni:1 -timed:1 -download:12000 -stats:1"
},
"Variables": [
{
@ -126,7 +126,7 @@
"Tls": ["schannel", "openssl"],
"Arch": ["x64", "x86", "arm", "arm64"],
"Exe": "secnetperf",
"Arguments": "-test:Throughput -target:$RemoteAddress -bind:$LocalAddress:4434 -ip:4 -uni:1 -timed:1 -download:12000 -tcp:1"
"Arguments": "-exec:maxtput -test:Throughput -target:$RemoteAddress -bind:$LocalAddress:4434 -ip:4 -uni:1 -timed:1 -download:12000 -tcp:1"
},
"Variables": [
],
@ -146,7 +146,7 @@
"Tls": ["openssl"],
"Arch": ["x64", "arm"],
"Exe": "secnetperf",
"Arguments": "-test:Throughput -target:$RemoteAddress -uni:1 -timed:1 -download:12000 -stats:1"
"Arguments": "-exec:maxtput -test:Throughput -target:$RemoteAddress -uni:1 -timed:1 -download:12000 -stats:1"
},
"Variables": [
{
@ -172,7 +172,7 @@
"Tls": ["schannel", "openssl"],
"Arch": ["x64", "x86", "arm", "arm64"],
"Exe": "secnetperf",
"Arguments": "-test:RPS -target:$RemoteAddress"
"Arguments": "-exec:lowlat -test:RPS -target:$RemoteAddress"
},
"Variables": [
{
@ -217,7 +217,7 @@
"Tls": ["openssl"],
"Arch": ["x64", "arm"],
"Exe": "secnetperf",
"Arguments": "-test:RPS -target:$RemoteAddress"
"Arguments": "-exec:lowlat -test:RPS -target:$RemoteAddress"
},
"Variables": [
{
@ -262,7 +262,7 @@
"Tls": ["schannel", "openssl"],
"Arch": ["x64", "x86", "arm", "arm64"],
"Exe": "secnetperf",
"Arguments": "-test:HPS -target:$RemoteAddress -incrementtarget:1"
"Arguments": "-exec:maxtput -test:HPS -target:$RemoteAddress -incrementtarget:1"
},
"Variables": [],
"AllowLoopback": false,
@ -279,7 +279,7 @@
"Tls": ["openssl"],
"Arch": ["x64", "arm"],
"Exe": "secnetperf",
"Arguments": "-test:HPS -target:$RemoteAddress"
"Arguments": "-exec:maxtput -test:HPS -target:$RemoteAddress"
},
"Variables": [],
"AllowLoopback": false,

Просмотреть файл

@ -84,9 +84,6 @@ This script provides helpers for building msquic.
.PARAMETER EnableHighResolutionTimers
Configures the system to use high resolution timers.
.PARAMETER SharedEC
Uses shared execution contexts (threads) where possible.
.PARAMETER UseXdp
Use XDP for the datapath instead of system socket APIs.
@ -193,9 +190,6 @@ param (
[Parameter(Mandatory = $false)]
[switch]$EnableHighResolutionTimers = $false,
[Parameter(Mandatory = $false)]
[switch]$SharedEC = $false,
[Parameter(Mandatory = $false)]
[switch]$UseXdp = $false,
@ -441,9 +435,6 @@ function CMake-Generate {
if ($EnableHighResolutionTimers) {
$Arguments += " -DQUIC_HIGH_RES_TIMERS=on"
}
if ($SharedEC) {
$Arguments += " -DQUIC_SHARED_EC=on"
}
if ($UseXdp) {
$Arguments += " -DQUIC_USE_XDP=on"
}

Просмотреть файл

@ -76,6 +76,7 @@ Invoke-Expression "$ToolExe $FullArgs"
-replace " QUIC_RECEIVE_FLAG_", " " `
-replace " QUIC_SEND_FLAG_", " " `
-replace " QUIC_DATAGRAM_SEND_", " " `
-replace " QUIC_EXECUTION_CONFIG_FLAG_", " " `
-replace "QUIC_TLS_PROTOCOL_1_3", "TLS_1_3" `
-replace " QUIC_TLS_PROTOCOL_", " " `
-replace " QUIC_CIPHER_ALGORITHM_", " " `

Просмотреть файл

@ -42,7 +42,6 @@ git checkout -b $BranchName
Copy-Item -Path artifacts/PerfDataResults/performance/windows/$($Arch)_$($Config)_schannel/msquic.pgd src/bin/winuser/pgo_$($Arch)/msquic.schannel.pgd -Force
Copy-Item -Path artifacts/PerfDataResults/performance/windows/$($Arch)_$($Config)_openssl/msquic.pgd src/bin/winuser/pgo_$($Arch)/msquic.openssl.pgd -Force
Copy-Item -Path artifacts/PerfDataResults/performance/windows/$($Arch)_$($Config)_schannel_SharedEC/msquic.pgd src/bin/winuser/pgo_$($Arch)/msquic.schannel.sharedec.pgd -Force
Copy-Item -Path artifacts/PerfDataResults/performance/windows/$($Arch)_$($Config)_schannel_Xdp/msquic.pgd src/bin/winuser/pgo_$($Arch)/msquic.schannel.xdp.pgd -Force
# Commit the new PGD files.

Просмотреть файл

@ -6,13 +6,12 @@ $ProgressPreference = 'SilentlyContinue'
function Set-ScriptVariables {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
param ($Local, $LocalTls, $LocalArch, $RemoteTls, $RemoteArch, $SharedEC, $XDP, $Config, $Publish, $Record, $LogProfile, $RemoteAddress, $Session, $Kernel, $FailOnRegression, $PGO)
param ($Local, $LocalTls, $LocalArch, $RemoteTls, $RemoteArch, $XDP, $Config, $Publish, $Record, $LogProfile, $RemoteAddress, $Session, $Kernel, $FailOnRegression, $PGO)
$script:Local = $Local
$script:LocalTls = $LocalTls
$script:LocalArch = $LocalArch
$script:RemoteTls = $RemoteTls
$script:RemoteArch = $RemoteArch
$script:SharedEC = $SharedEC
$script:XDP = $XDP
$script:PGO = $PGO
$script:Config = $Config
@ -1184,7 +1183,6 @@ class TestRunDefinition {
[boolean]$Loopback;
[boolean]$AllowLoopback;
[string]$FailureDefault;
[boolean]$SharedEC;
[boolean]$XDP;
[string[]]$Formats;
[double]$RegressionThreshold;
@ -1208,7 +1206,6 @@ class TestRunDefinition {
$this.AllowLoopback = $existingDef.AllowLoopback
$this.Formats = $existingDef.Formats
$this.RegressionThreshold = $existingDef.RegressionThreshold
$this.SharedEC = $script:SharedEC
$this.XDP = $script:XDP
$this.FailureDefault = $existingDef.FailureDefault
}
@ -1237,7 +1234,6 @@ class TestRunDefinition {
$this.VariableName += ("_" + $Var.Name + "_" + $Var.Value)
}
$this.Local = [ExecutableRunSpec]::new($existingDef.Local, $BaseArgs)
$this.SharedEC = $script:SharedEC
$this.XDP = $script:XDP
}
@ -1258,7 +1254,6 @@ class TestRunDefinition {
$this.AllowLoopback = $existingDef.AllowLoopback
$this.Formats = $existingDef.Formats
$this.RegressionThreshold = $existingDef.RegressionThreshold
$this.SharedEC = $script:SharedEC
$this.XDP = $script:XDP
$this.FailureDefault = $existingDef.FailureDefault
}
@ -1281,12 +1276,6 @@ class TestRunDefinition {
if ($script:Kernel -and $this.Local.Platform -eq "Windows") {
$Platform = 'Winkernel'
}
if ($script:SharedEC -and $this.Local.Platform -eq "Windows") {
$Platform = 'WinSharedEC'
}
if ($script:SharedEC -and $this.Local.Platform -eq "Linux") {
$Platform = 'LinuxSharedEC'
}
if ($script:XDP -and $this.Local.Platform -eq "Windows") {
$Platform = 'WinXDP'
}
@ -1559,9 +1548,6 @@ function Test-CanRunTest {
if ($script:Kernel -and $Test.SkipKernel) {
return $false
}
if ($script:SharedEC -and $Test.TestName.Contains("Tcp")) {
return $false
}
if ($script:XDP -and $Test.TestName.Contains("Tcp")) {
return $false
}

Просмотреть файл

@ -116,9 +116,6 @@ param (
[Parameter(Mandatory = $false)]
[switch]$PGO = $false,
[Parameter(Mandatory = $false)]
[switch]$SharedEC = $false,
[Parameter(Mandatory = $false)]
[switch]$XDP = $false,
@ -154,9 +151,6 @@ if ($Kernel) {
if ($PGO) {
Write-Error "'-PGO' is not supported in kernel mode!"
}
if ($SharedEC) {
Write-Error "'-SharedEC' is not supported in kernel mode!"
}
if ($XDP) {
Write-Error "'-XDP' is not supported in kernel mode!"
}
@ -252,7 +246,6 @@ Set-ScriptVariables -Local $Local `
-LocalArch $LocalArch `
-RemoteTls $RemoteTls `
-RemoteArch $RemoteArch `
-SharedEC $SharedEC `
-XDP $XDP `
-Config $Config `
-Publish $Publish `
@ -426,6 +419,14 @@ function Invoke-Test {
$RemoteArguments += " -stats:1"
}
if ($LocalArguments.Contains("-exec:maxtput")) {
$RemoteArguments += " -exec:maxtput"
}
if ($LocalArguments.Contains("-exec:lowlat")) {
$RemoteArguments += " -exec:lowlat"
}
if ($XDP) {
$RemoteArguments += " -cpu:-1"
$LocalArguments += " -cpu:-1"

Просмотреть файл

@ -202,7 +202,7 @@ function Start-Executable {
}
}
if ($Debugger) {
$pinfo.FileName = "windbg"
$pinfo.FileName = "windbgx"
if ($InitialBreak) {
$pinfo.Arguments = "-G $($Path) $($Arguments)"
} else {

Просмотреть файл

@ -1,3 +1,3 @@
{
"path" : "https://github.com/microsoft/xdp-for-windows/releases/download/v0.16.3/xdp-devkit-x64-0.16.3-prerelease.zip"
"path" : "https://github.com/microsoft/xdp-for-windows/releases/download/v0.16.4/xdp-devkit-x64-0.16.4-prerelease.zip"
}

Двоичные данные
src/bin/winuser/pgo_x64/msquic.openssl.pgd

Двоичный файл не отображается.

Двоичные данные
src/bin/winuser/pgo_x64/msquic.schannel.pgd

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичные данные
src/bin/winuser/pgo_x64/msquic.schannel.xdp.pgd

Двоичный файл не отображается.

Просмотреть файл

@ -5438,12 +5438,6 @@ QuicConnRecvDatagrams(
uint32_t ReleaseChainCount = 0;
QUIC_RECEIVE_PROCESSING_STATE RecvState = { FALSE, FALSE, 0 };
RecvState.PartitionIndex = QuicPartitionIdGetIndex(Connection->PartitionID);
if (Connection->Registration && Connection->Registration->SplitPartitioning) {
RecvState.PartitionIndex =
QuicPartitionIndexDecrement(
RecvState.PartitionIndex,
QUIC_MAX_THROUGHPUT_PARTITION_OFFSET);
}
UNREFERENCED_PARAMETER(DatagramChainCount);
@ -5697,13 +5691,6 @@ QuicConnRecvDatagrams(
Connection->State.Connected &&
RecvState.UpdatePartitionId) {
CXPLAT_DBG_ASSERT(!Connection->Registration->NoPartitioning);
if (Connection->Registration->SplitPartitioning) {
// TODO - Constrain PartitionID to the same NUMA node?
RecvState.PartitionIndex =
QuicPartitionIndexIncrement(
RecvState.PartitionIndex,
QUIC_MAX_THROUGHPUT_PARTITION_OFFSET);
}
CXPLAT_DBG_ASSERT(RecvState.PartitionIndex != QuicPartitionIdGetIndex(Connection->PartitionID));
Connection->PartitionID = QuicPartitionIdCreate(RecvState.PartitionIndex);
QuicConnGenerateNewSourceCids(Connection, TRUE);

Просмотреть файл

@ -499,11 +499,6 @@ MsQuicLibraryUninitialize(
#endif
CxPlatDataPathUninitialize(MsQuicLib.Datapath);
MsQuicLib.Datapath = NULL;
if (MsQuicLib.DataPathProcList != NULL) {
CXPLAT_FREE(MsQuicLib.DataPathProcList, QUIC_POOL_RAW_DATAPATH_PROCS);
MsQuicLib.DataPathProcList = NULL;
MsQuicLib.DataPathProcListLength = 0;
}
}
if (MsQuicLib.Storage != NULL) {
@ -560,6 +555,11 @@ MsQuicLibraryUninitialize(
CXPLAT_FREE(MsQuicLib.DefaultCompatibilityList, QUIC_POOL_DEFAULT_COMPAT_VER_LIST);
MsQuicLib.DefaultCompatibilityList = NULL;
if (MsQuicLib.ExecutionConfig != NULL) {
CXPLAT_FREE(MsQuicLib.ExecutionConfig, QUIC_POOL_EXECUTION_CONFIG);
MsQuicLib.ExecutionConfig = NULL;
}
QuicTraceEvent(
LibraryUninitialized,
"[ lib] Uninitialized");
@ -634,6 +634,48 @@ MsQuicRelease(
CxPlatLockRelease(&MsQuicLib.Lock);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicLibraryEnsureExecutionContext(
void
)
{
const CXPLAT_UDP_DATAPATH_CALLBACKS DatapathCallbacks = {
QuicBindingReceive,
QuicBindingUnreachable,
};
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
CxPlatLockAcquire(&MsQuicLib.Lock);
if (MsQuicLib.Datapath == NULL) {
Status =
CxPlatDataPathInitialize(
sizeof(CXPLAT_RECV_PACKET),
&DatapathCallbacks,
NULL, // TcpCallbacks
MsQuicLib.ExecutionConfig,
&MsQuicLib.Datapath);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Status,
"CxPlatDataPathInitialize");
} else {
QuicTraceEvent(
DataPathInitialized,
"[data] Initialized, DatapathFeatures=%u",
CxPlatDataPathGetSupportedFeatures(MsQuicLib.Datapath));
}
}
CxPlatLockRelease(&MsQuicLib.Lock);
return Status;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
QUIC_API
@ -900,72 +942,62 @@ QuicLibrarySetGlobalParam(
break;
case QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS: {
case QUIC_PARAM_GLOBAL_EXECUTION_CONFIG: {
if (BufferLength == 0) {
if (MsQuicLib.DataPathProcList != NULL) {
CXPLAT_FREE(MsQuicLib.DataPathProcList, QUIC_POOL_RAW_DATAPATH_PROCS);
MsQuicLib.DataPathProcList = NULL;
MsQuicLib.DataPathProcListLength = 0;
if (MsQuicLib.ExecutionConfig != NULL) {
CXPLAT_FREE(MsQuicLib.ExecutionConfig, QUIC_POOL_EXECUTION_CONFIG);
MsQuicLib.ExecutionConfig = NULL;
}
Status = QUIC_STATUS_SUCCESS;
break;
return QUIC_STATUS_SUCCESS;
}
if (Buffer == NULL || BufferLength < sizeof(uint16_t) || BufferLength % sizeof(uint16_t) != 0) {
Status = QUIC_STATUS_INVALID_PARAMETER;
break;
if (Buffer == NULL || BufferLength < QUIC_EXECUTION_CONFIG_MIN_SIZE) {
return QUIC_STATUS_INVALID_PARAMETER;
}
QUIC_EXECUTION_CONFIG* Config = (QUIC_EXECUTION_CONFIG*)Buffer;
if (BufferLength < QUIC_EXECUTION_CONFIG_MIN_SIZE + sizeof(uint16_t) * Config->ProcessorCount) {
return QUIC_STATUS_INVALID_PARAMETER;
}
for (uint32_t i = 0; i < Config->ProcessorCount; ++i) {
if (Config->ProcessorList[i] >= CxPlatProcMaxCount()) {
return QUIC_STATUS_INVALID_PARAMETER;
}
}
if (MsQuicLib.Datapath != NULL) {
QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"Tried to change raw datapath procs after datapath initialization");
"Tried to change execution config after datapath initialization");
Status = QUIC_STATUS_INVALID_STATE;
break;
}
uint32_t DataPathProcListLength = BufferLength / sizeof(uint16_t);
uint16_t* Cpus = (uint16_t*)Buffer;
for (uint32_t i = 0; i < DataPathProcListLength; ++i) {
if (*(Cpus + i) >= CxPlatProcActiveCount()) {
Status = QUIC_STATUS_INVALID_PARAMETER;
break;
}
}
if (Status == QUIC_STATUS_INVALID_PARAMETER) {
QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"Tried to set invalid raw datapath procs");
break;
}
uint16_t* DataPathProcList = CXPLAT_ALLOC_NONPAGED(BufferLength, QUIC_POOL_RAW_DATAPATH_PROCS);
if (DataPathProcList == NULL) {
QUIC_EXECUTION_CONFIG* NewConfig =
CXPLAT_ALLOC_NONPAGED(BufferLength, QUIC_POOL_EXECUTION_CONFIG);
if (NewConfig == NULL) {
QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"Raw datapath procs",
"Execution config",
BufferLength);
Status = QUIC_STATUS_OUT_OF_MEMORY;
break;
}
if (MsQuicLib.DataPathProcList != NULL) {
CXPLAT_FREE(MsQuicLib.DataPathProcList, QUIC_POOL_RAW_DATAPATH_PROCS);
MsQuicLib.DataPathProcList = NULL;
MsQuicLib.DataPathProcListLength = 0;
if (MsQuicLib.ExecutionConfig != NULL) {
CXPLAT_FREE(MsQuicLib.ExecutionConfig, QUIC_POOL_EXECUTION_CONFIG);
}
CxPlatCopyMemory(DataPathProcList, Buffer, BufferLength);
MsQuicLib.DataPathProcList = DataPathProcList;
MsQuicLib.DataPathProcListLength = DataPathProcListLength;
CxPlatCopyMemory(NewConfig, Config, BufferLength);
MsQuicLib.ExecutionConfig = NewConfig;
QuicTraceLogInfo(
LibraryDataPathProcsSet,
"[ lib] Setting datapath procs");
LibraryExecutionConfigSet,
"[ lib] Setting execution config");
Status = QUIC_STATUS_SUCCESS;
break;
@ -1199,14 +1231,19 @@ QuicLibraryGetGlobalParam(
Status = QUIC_STATUS_SUCCESS;
break;
case QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS:
if (*BufferLength == 0 && MsQuicLib.DataPathProcListLength == 0) {
case QUIC_PARAM_GLOBAL_EXECUTION_CONFIG: {
if (MsQuicLib.ExecutionConfig == NULL) {
*BufferLength = 0;
Status = QUIC_STATUS_SUCCESS;
break;
}
if (*BufferLength < sizeof(uint16_t) * MsQuicLib.DataPathProcListLength) {
*BufferLength = sizeof(uint16_t) * MsQuicLib.DataPathProcListLength;
const uint32_t ConfigLength =
QUIC_EXECUTION_CONFIG_MIN_SIZE +
sizeof(uint16_t) * MsQuicLib.ExecutionConfig->ProcessorCount;
if (*BufferLength < ConfigLength) {
*BufferLength = ConfigLength;
Status = QUIC_STATUS_BUFFER_TOO_SMALL;
break;
}
@ -1216,12 +1253,11 @@ QuicLibraryGetGlobalParam(
break;
}
*BufferLength = sizeof(uint16_t) * MsQuicLib.DataPathProcListLength;
if (MsQuicLib.DataPathProcList != NULL) {
CxPlatCopyMemory(Buffer, MsQuicLib.DataPathProcList, *BufferLength);
}
*BufferLength = ConfigLength;
CxPlatCopyMemory(Buffer, MsQuicLib.ExecutionConfig, ConfigLength);
Status = QUIC_STATUS_SUCCESS;
break;
}
case QUIC_PARAM_GLOBAL_TLS_PROVIDER:

Просмотреть файл

@ -206,10 +206,9 @@ typedef struct QUIC_LIBRARY {
CXPLAT_STORAGE* Storage;
//
// Processor candidates for raw datapath threads.
// Configuration for execution of the library (optionally set by the app).
//
uint16_t* DataPathProcList;
uint32_t DataPathProcListLength;
QUIC_EXECUTION_CONFIG* ExecutionConfig;
//
// Datapath instance for the library.
@ -521,6 +520,15 @@ QuicLibraryTryAddRefBinding(
_In_ QUIC_BINDING* Binding
);
//
// The function initializes the library execution context if not already done.
//
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicLibraryEnsureExecutionContext(
void
);
//
// Releases a reference on the binding and uninitializes it if it's the last
// one. DO NOT call this on a datapath upcall thread, as it will deadlock or

Просмотреть файл

@ -35,17 +35,11 @@ MsQuicRegistrationOpen(
{
QUIC_STATUS Status;
QUIC_REGISTRATION* Registration = NULL;
size_t AppNameLength = 0;
const CXPLAT_UDP_DATAPATH_CALLBACKS DatapathCallbacks = {
QuicBindingReceive,
QuicBindingUnreachable,
};
const BOOLEAN ExternalRegistration =
Config == NULL || Config->ExecutionProfile != QUIC_EXECUTION_PROFILE_TYPE_INTERNAL;
if (Config != NULL && Config->AppName != NULL) {
AppNameLength = strlen(Config->AppName);
}
const size_t AppNameLength =
(Config != NULL && Config->AppName != NULL) ? strlen(Config->AppName) : 0;
const size_t RegistrationSize = sizeof(QUIC_REGISTRATION) + AppNameLength + 1;
QuicTraceEvent(
ApiEnter,
@ -58,43 +52,16 @@ MsQuicRegistrationOpen(
goto Error;
}
CXPLAT_DBG_ASSERT(ExternalRegistration || MsQuicLib.Datapath != NULL);
if (ExternalRegistration) {
CxPlatLockAcquire(&MsQuicLib.Lock);
if (MsQuicLib.Datapath == NULL) {
CXPLAT_DATAPATH_CONFIG DataPathConfig = {
MsQuicLib.DataPathProcList,
MsQuicLib.DataPathProcListLength
};
Status =
CxPlatDataPathInitialize(
sizeof(CXPLAT_RECV_PACKET),
&DatapathCallbacks,
NULL, // TcpCallbacks
&DataPathConfig,
&MsQuicLib.Datapath);
if (QUIC_FAILED(Status)) {
CxPlatLockRelease(&MsQuicLib.Lock);
QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Status,
"CxPlatDataPathInitialize");
goto Error;
}
QuicTraceEvent(
DataPathInitialized,
"[data] Initialized, DatapathFeatures=%u",
CxPlatDataPathGetSupportedFeatures(MsQuicLib.Datapath));
Status = QuicLibraryEnsureExecutionContext();
if (QUIC_FAILED(Status)) {
goto Error;
}
CxPlatLockRelease(&MsQuicLib.Lock);
}
Registration =
CXPLAT_ALLOC_NONPAGED(
sizeof(QUIC_REGISTRATION) + AppNameLength + 1,
QUIC_POOL_REGISTRATION);
CXPLAT_DBG_ASSERT(MsQuicLib.Datapath != NULL);
Registration = CXPLAT_ALLOC_NONPAGED(RegistrationSize, QUIC_POOL_REGISTRATION);
if (Registration == NULL) {
QuicTraceEvent(
AllocFailure,
@ -105,14 +72,12 @@ MsQuicRegistrationOpen(
goto Error;
}
CxPlatZeroMemory(Registration, RegistrationSize);
Registration->Type = QUIC_HANDLE_TYPE_REGISTRATION;
Registration->ClientContext = NULL;
Registration->NoPartitioning = FALSE;
Registration->SplitPartitioning = FALSE;
Registration->ExecProfile = Config == NULL ? QUIC_EXECUTION_PROFILE_LOW_LATENCY : Config->ExecutionProfile;
Registration->ShuttingDown = 0;
Registration->ShutdownErrorCode = 0;
Registration->ShutdownFlags = 0;
Registration->ExecProfile =
Config == NULL ? QUIC_EXECUTION_PROFILE_LOW_LATENCY : Config->ExecutionProfile;
Registration->NoPartitioning =
Registration->ExecProfile == QUIC_EXECUTION_PROFILE_TYPE_SCAVENGER;
CxPlatLockInitialize(&Registration->ConfigLock);
CxPlatListInitializeHead(&Registration->Configurations);
CxPlatDispatchLockInitialize(&Registration->ConnectionLock);
@ -121,58 +86,21 @@ MsQuicRegistrationOpen(
Registration->AppNameLength = (uint8_t)(AppNameLength + 1);
if (AppNameLength != 0) {
CxPlatCopyMemory(Registration->AppName, Config->AppName, AppNameLength + 1);
} else {
Registration->AppName[0] = '\0';
}
uint16_t WorkerThreadFlags = 0;
switch (Registration->ExecProfile) {
default:
case QUIC_EXECUTION_PROFILE_LOW_LATENCY:
WorkerThreadFlags = CXPLAT_THREAD_FLAG_NONE;
break;
case QUIC_EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT:
WorkerThreadFlags =
CXPLAT_THREAD_FLAG_SET_AFFINITIZE;
Registration->SplitPartitioning = TRUE;
break;
case QUIC_EXECUTION_PROFILE_TYPE_SCAVENGER:
WorkerThreadFlags = 0;
Registration->NoPartitioning = TRUE;
break;
case QUIC_EXECUTION_PROFILE_TYPE_REAL_TIME:
WorkerThreadFlags =
CXPLAT_THREAD_FLAG_SET_AFFINITIZE;
break;
}
//
// TODO - Figure out how to check to see if hyper-threading was enabled
// first
// When hyper-threading is enabled, better bulk throughput can sometimes
// be gained by sharing the same physical core, but not the logical one.
// The shared one is always one greater than the RSS core.
//
if (Registration->SplitPartitioning &&
MsQuicLib.PartitionCount <= QUIC_MAX_THROUGHPUT_PARTITION_OFFSET) {
Registration->SplitPartitioning = FALSE; // Not enough partitions.
}
Status =
QuicWorkerPoolInitialize(
Registration,
WorkerThreadFlags,
Registration->NoPartitioning ? 1 : MsQuicLib.PartitionCount,
&Registration->WorkerPool);
Registration, Registration->ExecProfile, &Registration->WorkerPool);
if (QUIC_FAILED(Status)) {
goto Error;
}
QuicTraceEvent(
RegistrationCreated,
"[ reg][%p] Created, AppName=%s",
RegistrationCreatedV2,
"[ reg][%p] Created, AppName=%s, ExecProfile=%u",
Registration,
Registration->AppName);
Registration->AppName,
Registration->ExecProfile);
#ifdef CxPlatVerifierEnabledByAddr
#pragma prefast(suppress:6001, "SAL doesn't understand checking whether memory is tracked by Verifier.")
@ -335,10 +263,11 @@ QuicRegistrationTraceRundown(
)
{
QuicTraceEvent(
RegistrationRundown,
"[ reg][%p] Rundown, AppName=%s",
RegistrationRundownV2,
"[ reg][%p] Rundown, AppName=%s, ExecProfile=%u",
Registration,
Registration->AppName);
Registration->AppName,
Registration->ExecProfile);
CxPlatLockAcquire(&Registration->ConfigLock);
@ -388,14 +317,7 @@ QuicRegistrationAcceptConnection(
_In_ QUIC_CONNECTION* Connection
)
{
if (Registration->SplitPartitioning) {
//
// TODO - Constrain PartitionID to the same NUMA node?
//
Connection->PartitionID += QUIC_MAX_THROUGHPUT_PARTITION_OFFSET;
}
uint16_t Index =
const uint16_t Index =
Registration->NoPartitioning ? 0 : QuicPartitionIdGetIndex(Connection->PartitionID);
//

Просмотреть файл

@ -42,11 +42,8 @@ typedef struct QUIC_REGISTRATION {
BOOLEAN NoPartitioning : 1;
//
// Indicates whether if the QUIC worker is partitioned split from the RSS
// core.
// Indicates the registration is in the proces of shutting down.
//
BOOLEAN SplitPartitioning : 1;
BOOLEAN ShuttingDown : 1;
//
@ -54,6 +51,9 @@ typedef struct QUIC_REGISTRATION {
//
QUIC_EXECUTION_PROFILE ExecProfile;
//
// When shutdown, the set of flags passed to each connection for shutdown.
//
QUIC_CONNECTION_SHUTDOWN_FLAGS ShutdownFlags;
//

Просмотреть файл

@ -430,73 +430,84 @@ TEST(SettingsTest, GlobalSettingsSizesSet)
}
}
TEST(SettingsTest, GlobalRawDataPathProcsSetAndGet)
TEST(SettingsTest, GlobalExecutionConfigSetAndGet)
{
uint16_t SetCpus[] = {0, 1};
uint32_t SetCpusSize = ARRAYSIZE(SetCpus);
if (CxPlatProcActiveCount() < 2) {
SetCpusSize = CxPlatProcActiveCount();
uint8_t RawConfig[QUIC_EXECUTION_CONFIG_MIN_SIZE + 2 * sizeof(uint16_t)] = {0};
QUIC_EXECUTION_CONFIG* Config = (QUIC_EXECUTION_CONFIG*)RawConfig;
Config->ProcessorCount = 2;
if (CxPlatProcMaxCount() < 2) {
Config->ProcessorCount = CxPlatProcMaxCount();
}
uint32_t BufferLength = SetCpusSize * sizeof(uint16_t);
Config->ProcessorList[0] = 0;
Config->ProcessorList[1] = 1;
uint32_t BufferLength = sizeof(RawConfig);
ASSERT_EQ(
QUIC_STATUS_SUCCESS,
QuicLibrarySetGlobalParam(
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
BufferLength,
SetCpus));
Config));
BufferLength = 0;
ASSERT_EQ(
QUIC_STATUS_BUFFER_TOO_SMALL,
QuicLibraryGetGlobalParam(
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
&BufferLength,
NULL));
ASSERT_EQ(SetCpusSize, BufferLength / sizeof(uint16_t));
uint16_t GetCpus[ARRAYSIZE(SetCpus)] = {0};
nullptr));
ASSERT_EQ((uint32_t)sizeof(RawConfig), BufferLength);
uint16_t GetRawConfig[sizeof(RawConfig)] = {0};
QUIC_EXECUTION_CONFIG* GetConfig = (QUIC_EXECUTION_CONFIG*)GetRawConfig;
ASSERT_EQ(
QUIC_STATUS_SUCCESS,
QuicLibraryGetGlobalParam(
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
&BufferLength,
GetCpus));
ASSERT_EQ(0, memcmp(GetCpus, SetCpus, SetCpusSize * sizeof(uint16_t)));
GetConfig));
ASSERT_EQ(0, memcmp(GetConfig, Config, BufferLength));
//
// Passing a NULL buffer should clear the proc list.
//
ASSERT_EQ(
QUIC_STATUS_SUCCESS,
QuicLibrarySetGlobalParam(
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
0,
NULL));
nullptr));
BufferLength = 0;
ASSERT_EQ(
QUIC_STATUS_SUCCESS,
QuicLibraryGetGlobalParam(
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
&BufferLength,
NULL));
nullptr));
ASSERT_EQ((uint32_t)0, BufferLength);
//
// Passing an invalid processor number.
//
SetCpus[0] = (uint16_t)CxPlatProcActiveCount();
Config->ProcessorCount = 1;
Config->ProcessorList[0] = (uint16_t)CxPlatProcMaxCount();
ASSERT_EQ(
QUIC_STATUS_INVALID_PARAMETER,
QuicLibrarySetGlobalParam(
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
sizeof(SetCpus),
SetCpus));
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
sizeof(RawConfig),
Config));
}
TEST(SettingsTest, GlobalRawDataPathProcsSetAfterDataPathInit)
{
uint32_t SetCpus[] = {1, 2, 3, 4, 5};
uint8_t RawConfig[QUIC_EXECUTION_CONFIG_MIN_SIZE + 2 * sizeof(uint16_t)] = {0};
QUIC_EXECUTION_CONFIG* Config = (QUIC_EXECUTION_CONFIG*)RawConfig;
Config->ProcessorCount = 2;
Config->ProcessorList[0] = 0;
Config->ProcessorList[1] = 1;
MsQuicLib.Datapath = (CXPLAT_DATAPATH*)1; // Pretend datapath has been initialized
ASSERT_EQ(
QUIC_STATUS_INVALID_STATE,
QuicLibrarySetGlobalParam(
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
sizeof(SetCpus),
SetCpus));
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
sizeof(RawConfig),
Config));
}

Просмотреть файл

@ -30,12 +30,10 @@ QuicWorkerLoop(
_Inout_ CXPLAT_EXECUTION_STATE* State
);
#ifndef QUIC_USE_EXECUTION_CONTEXTS
//
// Thread callback for processing the work queued for the worker.
//
CXPLAT_THREAD_CALLBACK(QuicWorkerThread, Context);
#endif
void
QuicWorkerThreadWake(
@ -43,11 +41,11 @@ QuicWorkerThreadWake(
)
{
Worker->ExecutionContext.Ready = TRUE; // Run the execution context
#ifndef QUIC_USE_EXECUTION_CONTEXTS
CxPlatEventSet(Worker->Ready);
#else
CxPlatWakeExecutionContext(&Worker->ExecutionContext);
#endif
if (Worker->IsExternal) {
CxPlatWakeExecutionContext(&Worker->ExecutionContext);
} else {
CxPlatEventSet(Worker->Ready);
}
}
_IRQL_requires_max_(PASSIVE_LEVEL)
@ -59,28 +57,24 @@ QuicWorkerUninitialize(
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicWorkerInitialize(
_In_opt_ const void* Owner,
_In_ uint16_t ThreadFlags,
_In_ const QUIC_REGISTRATION* Registration,
_In_ QUIC_EXECUTION_PROFILE ExecProfile,
_In_ uint16_t IdealProcessor,
_Inout_ QUIC_WORKER* Worker
)
{
QUIC_STATUS Status;
QuicTraceEvent(
WorkerCreated,
"[wrkr][%p] Created, IdealProc=%hu Owner=%p",
Worker,
IdealProcessor,
Owner);
Registration);
Worker->Enabled = TRUE;
Worker->IdealProcessor = IdealProcessor;
CxPlatDispatchLockInitialize(&Worker->Lock);
CxPlatEventInitialize(&Worker->Done, TRUE, FALSE);
#ifndef QUIC_USE_EXECUTION_CONTEXTS
CxPlatEventInitialize(&Worker->Ready, FALSE, FALSE);
#endif
CxPlatListInitializeHead(&Worker->Connections);
CxPlatListInitializeHead(&Worker->Operations);
CxPlatPoolInitialize(FALSE, sizeof(QUIC_STREAM), QUIC_POOL_STREAM, &Worker->StreamPool);
@ -91,7 +85,7 @@ QuicWorkerInitialize(
CxPlatPoolInitialize(FALSE, sizeof(QUIC_STATELESS_CONTEXT), QUIC_POOL_STATELESS_CTX, &Worker->StatelessContextPool);
CxPlatPoolInitialize(FALSE, sizeof(QUIC_OPERATION), QUIC_POOL_OPER, &Worker->OperPool);
Status = QuicTimerWheelInitialize(&Worker->TimerWheel);
QUIC_STATUS Status = QuicTimerWheelInitialize(&Worker->TimerWheel);
if (QUIC_FAILED(Status)) {
goto Error;
}
@ -101,29 +95,36 @@ QuicWorkerInitialize(
Worker->ExecutionContext.NextTimeUs = UINT64_MAX;
Worker->ExecutionContext.Ready = TRUE;
#ifdef QUIC_USE_EXECUTION_CONTEXTS
UNREFERENCED_PARAMETER(ThreadFlags);
CxPlatAddExecutionContext(&Worker->ExecutionContext, IdealProcessor);
#else
CXPLAT_THREAD_CONFIG ThreadConfig = {
ThreadFlags,
IdealProcessor,
"quic_worker",
QuicWorkerThread,
Worker
};
#ifndef _KERNEL_MODE // Not supported on kernel mode
if (ExecProfile != QUIC_EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT) {
Worker->IsExternal = TRUE;
CxPlatAddExecutionContext(&Worker->ExecutionContext, IdealProcessor);
} else
#endif // _KERNEL_MODE
{
const uint16_t ThreadFlags =
ExecProfile == QUIC_EXECUTION_PROFILE_TYPE_REAL_TIME ?
CXPLAT_THREAD_FLAG_SET_AFFINITIZE : CXPLAT_THREAD_FLAG_NONE;
Status = CxPlatThreadCreate(&ThreadConfig, &Worker->Thread);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
WorkerErrorStatus,
"[wrkr][%p] ERROR, %u, %s.",
Worker,
Status,
"CxPlatThreadCreate");
goto Error;
CXPLAT_THREAD_CONFIG ThreadConfig = {
ThreadFlags,
IdealProcessor,
"quic_worker",
QuicWorkerThread,
Worker
};
Status = CxPlatThreadCreate(&ThreadConfig, &Worker->Thread);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
WorkerErrorStatus,
"[wrkr][%p] ERROR, %u, %s.",
Worker,
Status,
"CxPlatThreadCreate");
goto Error;
}
}
#endif // QUIC_USE_EXECUTION_CONTEXTS
Error:
@ -156,16 +157,16 @@ QuicWorkerUninitialize(
}
CxPlatEventUninitialize(Worker->Done);
#ifndef QUIC_USE_EXECUTION_CONTEXTS
//
// Wait for the thread to finish.
//
if (Worker->Thread) {
CxPlatThreadWait(&Worker->Thread);
CxPlatThreadDelete(&Worker->Thread);
if (!Worker->IsExternal) {
//
// Wait for the thread to finish.
//
if (Worker->Thread) {
CxPlatThreadWait(&Worker->Thread);
CxPlatThreadDelete(&Worker->Thread);
}
CxPlatEventUninitialize(Worker->Ready);
}
CxPlatEventUninitialize(Worker->Ready);
#endif // QUIC_USE_EXECUTION_CONTEXTS
CXPLAT_TEL_ASSERT(CxPlatListIsEmpty(&Worker->Connections));
CXPLAT_TEL_ASSERT(CxPlatListIsEmpty(&Worker->Operations));
@ -718,7 +719,6 @@ QuicWorkerLoop(
return TRUE;
}
#ifndef QUIC_USE_EXECUTION_CONTEXTS
CXPLAT_THREAD_CALLBACK(QuicWorkerThread, Context)
{
QUIC_WORKER* Worker = (QUIC_WORKER*)Context;
@ -758,42 +758,41 @@ CXPLAT_THREAD_CALLBACK(QuicWorkerThread, Context)
Worker);
CXPLAT_THREAD_RETURN(QUIC_STATUS_SUCCESS);
}
#endif // QUIC_USE_EXECUTION_CONTEXTS
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicWorkerPoolInitialize(
_In_opt_ const void* Owner,
_In_ uint16_t ThreadFlags,
_In_ uint16_t WorkerCount,
_In_ const QUIC_REGISTRATION* Registration,
_In_ QUIC_EXECUTION_PROFILE ExecProfile,
_Out_ QUIC_WORKER_POOL** NewWorkerPool
)
{
QUIC_STATUS Status;
const uint16_t WorkerCount =
ExecProfile == QUIC_EXECUTION_PROFILE_TYPE_SCAVENGER ? 1 : MsQuicLib.PartitionCount;
const size_t WorkerPoolSize =
sizeof(QUIC_WORKER_POOL) + WorkerCount * sizeof(QUIC_WORKER);
QUIC_WORKER_POOL* WorkerPool =
CXPLAT_ALLOC_NONPAGED(sizeof(QUIC_WORKER_POOL) + WorkerCount * sizeof(QUIC_WORKER), QUIC_POOL_WORKER);
QUIC_WORKER_POOL* WorkerPool = CXPLAT_ALLOC_NONPAGED(WorkerPoolSize, QUIC_POOL_WORKER);
if (WorkerPool == NULL) {
QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"QUIC_WORKER_POOL",
sizeof(QUIC_WORKER_POOL) + WorkerCount * sizeof(QUIC_WORKER));
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Error;
WorkerPoolSize);
return QUIC_STATUS_OUT_OF_MEMORY;
}
CxPlatZeroMemory(WorkerPool, WorkerPoolSize);
WorkerPool->WorkerCount = WorkerCount;
WorkerPool->LastWorker = 0;
CxPlatZeroMemory(WorkerPool->Workers, sizeof(QUIC_WORKER) * WorkerCount);
//
// Create the set of worker threads and soft affinitize them in order to
// attempt to spread the connection workload out over multiple processors.
//
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
for (uint16_t i = 0; i < WorkerCount; i++) {
Status = QuicWorkerInitialize(Owner, ThreadFlags, i, &WorkerPool->Workers[i]);
Status = QuicWorkerInitialize(Registration, ExecProfile, i, &WorkerPool->Workers[i]);
if (QUIC_FAILED(Status)) {
for (uint16_t j = 0; j < i; j++) {
QuicWorkerUninitialize(&WorkerPool->Workers[j]);
@ -803,14 +802,11 @@ QuicWorkerPoolInitialize(
}
*NewWorkerPool = WorkerPool;
Status = QUIC_STATUS_SUCCESS;
Error:
if (QUIC_FAILED(Status)) {
if (WorkerPool != NULL) {
CXPLAT_FREE(WorkerPool, QUIC_POOL_WORKER);
}
CXPLAT_FREE(WorkerPool, QUIC_POOL_WORKER);
}
return Status;

Просмотреть файл

@ -21,6 +21,11 @@ typedef struct QUIC_CACHEALIGN QUIC_WORKER {
//
CXPLAT_EVENT Done;
//
// Indicates if this work is handled by an external (to QUIC) execution context.
//
BOOLEAN IsExternal;
//
// TRUE if the worker is currently running.
//
@ -53,7 +58,6 @@ typedef struct QUIC_CACHEALIGN QUIC_WORKER {
//
QUIC_TIMER_WHEEL TimerWheel;
#ifndef QUIC_USE_EXECUTION_CONTEXTS
//
// An event to kick the thread.
//
@ -63,7 +67,6 @@ typedef struct QUIC_CACHEALIGN QUIC_WORKER {
// A thread for draining operations from queued connections.
//
CXPLAT_THREAD Thread;
#endif // QUIC_USE_EXECUTION_CONTEXTS
//
// Serializes access to the connection and operation lists.
@ -135,9 +138,8 @@ QuicWorkerIsOverloaded(
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicWorkerPoolInitialize(
_In_opt_ const void* Owner,
_In_ uint16_t ThreadFlags,
_In_ uint16_t WorkerCount,
_In_ const QUIC_REGISTRATION* Registration,
_In_ QUIC_EXECUTION_PROFILE ExecProfile,
_Out_ QUIC_WORKER_POOL** WorkerPool
);

Просмотреть файл

@ -183,6 +183,26 @@ namespace Microsoft.Quic
CANCELED,
}
[System.Flags]
internal enum QUIC_EXECUTION_CONFIG_FLAGS
{
NONE = 0x0000,
}
internal unsafe partial struct QUIC_EXECUTION_CONFIG
{
internal QUIC_EXECUTION_CONFIG_FLAGS Flags;
[NativeTypeName("uint32_t")]
internal uint PollingIdleTimeoutUs;
[NativeTypeName("uint32_t")]
internal uint ProcessorCount;
[NativeTypeName("uint16_t [1]")]
internal fixed ushort ProcessorList[1];
}
internal unsafe partial struct QUIC_REGISTRATION_CONFIG
{
[NativeTypeName("const char *")]
@ -2680,6 +2700,9 @@ namespace Microsoft.Quic
[NativeTypeName("#define QUIC_MAX_RESUMPTION_APP_DATA_LENGTH 1000")]
internal const uint QUIC_MAX_RESUMPTION_APP_DATA_LENGTH = 1000;
[NativeTypeName("#define QUIC_EXECUTION_CONFIG_MIN_SIZE (uint32_t)FIELD_OFFSET(QUIC_EXECUTION_CONFIG, ProcessorList)")]
internal static readonly uint QUIC_EXECUTION_CONFIG_MIN_SIZE = unchecked((uint)((int)(Marshal.OffsetOf<QUIC_EXECUTION_CONFIG>("ProcessorList"))));
[NativeTypeName("#define QUIC_MAX_TICKET_KEY_COUNT 16")]
internal const uint QUIC_MAX_TICKET_KEY_COUNT = 16;
@ -2737,8 +2760,8 @@ namespace Microsoft.Quic
[NativeTypeName("#define QUIC_PARAM_GLOBAL_LIBRARY_GIT_HASH 0x01000008")]
internal const uint QUIC_PARAM_GLOBAL_LIBRARY_GIT_HASH = 0x01000008;
[NativeTypeName("#define QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS 0x01000009")]
internal const uint QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS = 0x01000009;
[NativeTypeName("#define QUIC_PARAM_GLOBAL_EXECUTION_CONFIG 0x01000009")]
internal const uint QUIC_PARAM_GLOBAL_EXECUTION_CONFIG = 0x01000009;
[NativeTypeName("#define QUIC_PARAM_GLOBAL_TLS_PROVIDER 0x0100000A")]
internal const uint QUIC_PARAM_GLOBAL_TLS_PROVIDER = 0x0100000A;

Просмотреть файл

@ -192,15 +192,15 @@ tracepoint(CLOG_LIBRARY_C, LibrarySetSettings );\
/*----------------------------------------------------------
// Decoder Ring for LibraryDataPathProcsSet
// [ lib] Setting datapath procs
// Decoder Ring for LibraryExecutionConfigSet
// [ lib] Setting execution config
// QuicTraceLogInfo(
LibraryDataPathProcsSet,
"[ lib] Setting datapath procs");
LibraryExecutionConfigSet,
"[ lib] Setting execution config");
----------------------------------------------------------*/
#ifndef _clog_2_ARGS_TRACE_LibraryDataPathProcsSet
#define _clog_2_ARGS_TRACE_LibraryDataPathProcsSet(uniqueId, encoded_arg_string)\
tracepoint(CLOG_LIBRARY_C, LibraryDataPathProcsSet );\
#ifndef _clog_2_ARGS_TRACE_LibraryExecutionConfigSet
#define _clog_2_ARGS_TRACE_LibraryExecutionConfigSet(uniqueId, encoded_arg_string)\
tracepoint(CLOG_LIBRARY_C, LibraryExecutionConfigSet );\
#endif
@ -450,14 +450,32 @@ tracepoint(CLOG_LIBRARY_C, LibraryRelease );\
/*----------------------------------------------------------
// Decoder Ring for DataPathInitialized
// [data] Initialized, DatapathFeatures=%u
// QuicTraceEvent(
DataPathInitialized,
"[data] Initialized, DatapathFeatures=%u",
CxPlatDataPathGetSupportedFeatures(MsQuicLib.Datapath));
// arg2 = arg2 = CxPlatDataPathGetSupportedFeatures(MsQuicLib.Datapath) = arg2
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_DataPathInitialized
#define _clog_3_ARGS_TRACE_DataPathInitialized(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_LIBRARY_C, DataPathInitialized , arg2);\
#endif
/*----------------------------------------------------------
// Decoder Ring for LibraryError
// [ lib] ERROR, %s.
// QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"Tried to change raw datapath procs after datapath initialization");
// arg2 = arg2 = "Tried to change raw datapath procs after datapath initialization" = arg2
"Tried to change execution config after datapath initialization");
// arg2 = arg2 = "Tried to change execution config after datapath initialization" = arg2
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_LibraryError
#define _clog_3_ARGS_TRACE_LibraryError(uniqueId, encoded_arg_string, arg2)\

Просмотреть файл

@ -161,13 +161,13 @@ TRACEPOINT_EVENT(CLOG_LIBRARY_C, LibrarySetSettings,
/*----------------------------------------------------------
// Decoder Ring for LibraryDataPathProcsSet
// [ lib] Setting datapath procs
// Decoder Ring for LibraryExecutionConfigSet
// [ lib] Setting execution config
// QuicTraceLogInfo(
LibraryDataPathProcsSet,
"[ lib] Setting datapath procs");
LibraryExecutionConfigSet,
"[ lib] Setting execution config");
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_LIBRARY_C, LibraryDataPathProcsSet,
TRACEPOINT_EVENT(CLOG_LIBRARY_C, LibraryExecutionConfigSet,
TP_ARGS(
),
TP_FIELDS(
@ -434,14 +434,33 @@ TRACEPOINT_EVENT(CLOG_LIBRARY_C, LibraryRelease,
/*----------------------------------------------------------
// Decoder Ring for DataPathInitialized
// [data] Initialized, DatapathFeatures=%u
// QuicTraceEvent(
DataPathInitialized,
"[data] Initialized, DatapathFeatures=%u",
CxPlatDataPathGetSupportedFeatures(MsQuicLib.Datapath));
// arg2 = arg2 = CxPlatDataPathGetSupportedFeatures(MsQuicLib.Datapath) = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_LIBRARY_C, DataPathInitialized,
TP_ARGS(
unsigned int, arg2),
TP_FIELDS(
ctf_integer(unsigned int, arg2, arg2)
)
)
/*----------------------------------------------------------
// Decoder Ring for LibraryError
// [ lib] ERROR, %s.
// QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"Tried to change raw datapath procs after datapath initialization");
// arg2 = arg2 = "Tried to change raw datapath procs after datapath initialization" = arg2
"Tried to change execution config after datapath initialization");
// arg2 = arg2 = "Tried to change execution config after datapath initialization" = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_LIBRARY_C, LibraryError,
TP_ARGS(

Просмотреть файл

@ -117,9 +117,9 @@ tracepoint(CLOG_PLATFORM_POSIX_C, PosixUninitialized );\
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Status,
errno,
"open(/dev/urandom, O_RDONLY|O_CLOEXEC) failed");
// arg2 = arg2 = Status = arg2
// arg2 = arg2 = errno = arg2
// arg3 = arg3 = "open(/dev/urandom, O_RDONLY|O_CLOEXEC) failed" = arg3
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_LibraryErrorStatus

Просмотреть файл

@ -90,9 +90,9 @@ TRACEPOINT_EVENT(CLOG_PLATFORM_POSIX_C, PosixUninitialized,
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Status,
errno,
"open(/dev/urandom, O_RDONLY|O_CLOEXEC) failed");
// arg2 = arg2 = Status = arg2
// arg2 = arg2 = errno = arg2
// arg3 = arg3 = "open(/dev/urandom, O_RDONLY|O_CLOEXEC) failed" = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_PLATFORM_POSIX_C, LibraryErrorStatus,

Просмотреть файл

@ -63,44 +63,6 @@ tracepoint(CLOG_REGISTRATION_C, ApiEnter , arg2, arg3);\
/*----------------------------------------------------------
// Decoder Ring for LibraryErrorStatus
// [ lib] ERROR, %u, %s.
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Status,
"CxPlatDataPathInitialize");
// arg2 = arg2 = Status = arg2
// arg3 = arg3 = "CxPlatDataPathInitialize" = arg3
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_LibraryErrorStatus
#define _clog_4_ARGS_TRACE_LibraryErrorStatus(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_REGISTRATION_C, LibraryErrorStatus , arg2, arg3);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DataPathInitialized
// [data] Initialized, DatapathFeatures=%u
// QuicTraceEvent(
DataPathInitialized,
"[data] Initialized, DatapathFeatures=%u",
CxPlatDataPathGetSupportedFeatures(MsQuicLib.Datapath));
// arg2 = arg2 = CxPlatDataPathGetSupportedFeatures(MsQuicLib.Datapath) = arg2
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_DataPathInitialized
#define _clog_3_ARGS_TRACE_DataPathInitialized(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_REGISTRATION_C, DataPathInitialized , arg2);\
#endif
/*----------------------------------------------------------
// Decoder Ring for AllocFailure
// Allocation of '%s' failed. (%llu bytes)
@ -122,19 +84,21 @@ tracepoint(CLOG_REGISTRATION_C, AllocFailure , arg2, arg3);\
/*----------------------------------------------------------
// Decoder Ring for RegistrationCreated
// [ reg][%p] Created, AppName=%s
// Decoder Ring for RegistrationCreatedV2
// [ reg][%p] Created, AppName=%s, ExecProfile=%u
// QuicTraceEvent(
RegistrationCreated,
"[ reg][%p] Created, AppName=%s",
RegistrationCreatedV2,
"[ reg][%p] Created, AppName=%s, ExecProfile=%u",
Registration,
Registration->AppName);
Registration->AppName,
Registration->ExecProfile);
// arg2 = arg2 = Registration = arg2
// arg3 = arg3 = Registration->AppName = arg3
// arg4 = arg4 = Registration->ExecProfile = arg4
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_RegistrationCreated
#define _clog_4_ARGS_TRACE_RegistrationCreated(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_REGISTRATION_C, RegistrationCreated , arg2, arg3);\
#ifndef _clog_5_ARGS_TRACE_RegistrationCreatedV2
#define _clog_5_ARGS_TRACE_RegistrationCreatedV2(uniqueId, encoded_arg_string, arg2, arg3, arg4)\
tracepoint(CLOG_REGISTRATION_C, RegistrationCreatedV2 , arg2, arg3, arg4);\
#endif
@ -194,19 +158,21 @@ tracepoint(CLOG_REGISTRATION_C, ApiExit );\
/*----------------------------------------------------------
// Decoder Ring for RegistrationRundown
// [ reg][%p] Rundown, AppName=%s
// Decoder Ring for RegistrationRundownV2
// [ reg][%p] Rundown, AppName=%s, ExecProfile=%u
// QuicTraceEvent(
RegistrationRundown,
"[ reg][%p] Rundown, AppName=%s",
RegistrationRundownV2,
"[ reg][%p] Rundown, AppName=%s, ExecProfile=%u",
Registration,
Registration->AppName);
Registration->AppName,
Registration->ExecProfile);
// arg2 = arg2 = Registration = arg2
// arg3 = arg3 = Registration->AppName = arg3
// arg4 = arg4 = Registration->ExecProfile = arg4
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_RegistrationRundown
#define _clog_4_ARGS_TRACE_RegistrationRundown(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_REGISTRATION_C, RegistrationRundown , arg2, arg3);\
#ifndef _clog_5_ARGS_TRACE_RegistrationRundownV2
#define _clog_5_ARGS_TRACE_RegistrationRundownV2(uniqueId, encoded_arg_string, arg2, arg3, arg4)\
tracepoint(CLOG_REGISTRATION_C, RegistrationRundownV2 , arg2, arg3, arg4);\
#endif

Просмотреть файл

@ -43,48 +43,6 @@ TRACEPOINT_EVENT(CLOG_REGISTRATION_C, ApiEnter,
/*----------------------------------------------------------
// Decoder Ring for LibraryErrorStatus
// [ lib] ERROR, %u, %s.
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Status,
"CxPlatDataPathInitialize");
// arg2 = arg2 = Status = arg2
// arg3 = arg3 = "CxPlatDataPathInitialize" = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_REGISTRATION_C, LibraryErrorStatus,
TP_ARGS(
unsigned int, arg2,
const char *, arg3),
TP_FIELDS(
ctf_integer(unsigned int, arg2, arg2)
ctf_string(arg3, arg3)
)
)
/*----------------------------------------------------------
// Decoder Ring for DataPathInitialized
// [data] Initialized, DatapathFeatures=%u
// QuicTraceEvent(
DataPathInitialized,
"[data] Initialized, DatapathFeatures=%u",
CxPlatDataPathGetSupportedFeatures(MsQuicLib.Datapath));
// arg2 = arg2 = CxPlatDataPathGetSupportedFeatures(MsQuicLib.Datapath) = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_REGISTRATION_C, DataPathInitialized,
TP_ARGS(
unsigned int, arg2),
TP_FIELDS(
ctf_integer(unsigned int, arg2, arg2)
)
)
/*----------------------------------------------------------
// Decoder Ring for AllocFailure
// Allocation of '%s' failed. (%llu bytes)
@ -109,23 +67,27 @@ TRACEPOINT_EVENT(CLOG_REGISTRATION_C, AllocFailure,
/*----------------------------------------------------------
// Decoder Ring for RegistrationCreated
// [ reg][%p] Created, AppName=%s
// Decoder Ring for RegistrationCreatedV2
// [ reg][%p] Created, AppName=%s, ExecProfile=%u
// QuicTraceEvent(
RegistrationCreated,
"[ reg][%p] Created, AppName=%s",
RegistrationCreatedV2,
"[ reg][%p] Created, AppName=%s, ExecProfile=%u",
Registration,
Registration->AppName);
Registration->AppName,
Registration->ExecProfile);
// arg2 = arg2 = Registration = arg2
// arg3 = arg3 = Registration->AppName = arg3
// arg4 = arg4 = Registration->ExecProfile = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_REGISTRATION_C, RegistrationCreated,
TRACEPOINT_EVENT(CLOG_REGISTRATION_C, RegistrationCreatedV2,
TP_ARGS(
const void *, arg2,
const char *, arg3),
const char *, arg3,
unsigned int, arg4),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_string(arg3, arg3)
ctf_integer(unsigned int, arg4, arg4)
)
)
@ -186,22 +148,26 @@ TRACEPOINT_EVENT(CLOG_REGISTRATION_C, ApiExit,
/*----------------------------------------------------------
// Decoder Ring for RegistrationRundown
// [ reg][%p] Rundown, AppName=%s
// Decoder Ring for RegistrationRundownV2
// [ reg][%p] Rundown, AppName=%s, ExecProfile=%u
// QuicTraceEvent(
RegistrationRundown,
"[ reg][%p] Rundown, AppName=%s",
RegistrationRundownV2,
"[ reg][%p] Rundown, AppName=%s, ExecProfile=%u",
Registration,
Registration->AppName);
Registration->AppName,
Registration->ExecProfile);
// arg2 = arg2 = Registration = arg2
// arg3 = arg3 = Registration->AppName = arg3
// arg4 = arg4 = Registration->ExecProfile = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_REGISTRATION_C, RegistrationRundown,
TRACEPOINT_EVENT(CLOG_REGISTRATION_C, RegistrationRundownV2,
TP_ARGS(
const void *, arg2,
const char *, arg3),
const char *, arg3,
unsigned int, arg4),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_string(arg3, arg3)
ctf_integer(unsigned int, arg4, arg4)
)
)

Просмотреть файл

@ -69,10 +69,10 @@ tracepoint(CLOG_WORKER_C, AbandonOnLibShutdown , arg1);\
"[wrkr][%p] Created, IdealProc=%hu Owner=%p",
Worker,
IdealProcessor,
Owner);
Registration);
// arg2 = arg2 = Worker = arg2
// arg3 = arg3 = IdealProcessor = arg3
// arg4 = arg4 = Owner = arg4
// arg4 = arg4 = Registration = arg4
----------------------------------------------------------*/
#ifndef _clog_5_ARGS_TRACE_WorkerCreated
#define _clog_5_ARGS_TRACE_WorkerCreated(uniqueId, encoded_arg_string, arg2, arg3, arg4)\
@ -87,11 +87,11 @@ tracepoint(CLOG_WORKER_C, WorkerCreated , arg2, arg3, arg4);\
// Decoder Ring for WorkerErrorStatus
// [wrkr][%p] ERROR, %u, %s.
// QuicTraceEvent(
WorkerErrorStatus,
"[wrkr][%p] ERROR, %u, %s.",
Worker,
Status,
"CxPlatThreadCreate");
WorkerErrorStatus,
"[wrkr][%p] ERROR, %u, %s.",
Worker,
Status,
"CxPlatThreadCreate");
// arg2 = arg2 = Worker = arg2
// arg3 = arg3 = Status = arg3
// arg4 = arg4 = "CxPlatThreadCreate" = arg4
@ -266,9 +266,9 @@ tracepoint(CLOG_WORKER_C, WorkerStop , arg2);\
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"QUIC_WORKER_POOL",
sizeof(QUIC_WORKER_POOL) + WorkerCount * sizeof(QUIC_WORKER));
WorkerPoolSize);
// arg2 = arg2 = "QUIC_WORKER_POOL" = arg2
// arg3 = arg3 = sizeof(QUIC_WORKER_POOL) + WorkerCount * sizeof(QUIC_WORKER) = arg3
// arg3 = arg3 = WorkerPoolSize = arg3
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_AllocFailure
#define _clog_4_ARGS_TRACE_AllocFailure(uniqueId, encoded_arg_string, arg2, arg3)\

Просмотреть файл

@ -47,10 +47,10 @@ TRACEPOINT_EVENT(CLOG_WORKER_C, AbandonOnLibShutdown,
"[wrkr][%p] Created, IdealProc=%hu Owner=%p",
Worker,
IdealProcessor,
Owner);
Registration);
// arg2 = arg2 = Worker = arg2
// arg3 = arg3 = IdealProcessor = arg3
// arg4 = arg4 = Owner = arg4
// arg4 = arg4 = Registration = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_WORKER_C, WorkerCreated,
TP_ARGS(
@ -70,11 +70,11 @@ TRACEPOINT_EVENT(CLOG_WORKER_C, WorkerCreated,
// Decoder Ring for WorkerErrorStatus
// [wrkr][%p] ERROR, %u, %s.
// QuicTraceEvent(
WorkerErrorStatus,
"[wrkr][%p] ERROR, %u, %s.",
Worker,
Status,
"CxPlatThreadCreate");
WorkerErrorStatus,
"[wrkr][%p] ERROR, %u, %s.",
Worker,
Status,
"CxPlatThreadCreate");
// arg2 = arg2 = Worker = arg2
// arg3 = arg3 = Status = arg3
// arg4 = arg4 = "CxPlatThreadCreate" = arg4
@ -272,9 +272,9 @@ TRACEPOINT_EVENT(CLOG_WORKER_C, WorkerStop,
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"QUIC_WORKER_POOL",
sizeof(QUIC_WORKER_POOL) + WorkerCount * sizeof(QUIC_WORKER));
WorkerPoolSize);
// arg2 = arg2 = "QUIC_WORKER_POOL" = arg2
// arg3 = arg3 = sizeof(QUIC_WORKER_POOL) + WorkerCount * sizeof(QUIC_WORKER) = arg3
// arg3 = arg3 = WorkerPoolSize = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_WORKER_C, AllocFailure,
TP_ARGS(

Просмотреть файл

@ -232,6 +232,27 @@ typedef enum QUIC_DATAGRAM_SEND_STATE {
#define QUIC_DATAGRAM_SEND_STATE_IS_FINAL(State) \
((State) >= QUIC_DATAGRAM_SEND_LOST_DISCARDED)
typedef enum QUIC_EXECUTION_CONFIG_FLAGS {
QUIC_EXECUTION_CONFIG_FLAG_NONE = 0x0000,
} QUIC_EXECUTION_CONFIG_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(QUIC_EXECUTION_CONFIG_FLAGS)
//
// A custom configuration for thread execution in QUIC.
//
typedef struct QUIC_EXECUTION_CONFIG {
QUIC_EXECUTION_CONFIG_FLAGS Flags;
uint32_t PollingIdleTimeoutUs; // Time before a polling thread, with no work to do, sleeps.
uint32_t ProcessorCount;
_Field_size_(ProcessorCount)
uint16_t ProcessorList[1]; // List of processors to use for threads.
} QUIC_EXECUTION_CONFIG;
#define QUIC_EXECUTION_CONFIG_MIN_SIZE \
(uint32_t)FIELD_OFFSET(QUIC_EXECUTION_CONFIG, ProcessorList)
typedef struct QUIC_REGISTRATION_CONFIG { // All fields may be NULL/zero.
const char* AppName;
@ -749,7 +770,7 @@ void
#endif
#define QUIC_PARAM_GLOBAL_LIBRARY_GIT_HASH 0x01000008 // char[64]
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
#define QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS 0x01000009 // uint16_t[]
#define QUIC_PARAM_GLOBAL_EXECUTION_CONFIG 0x01000009 // QUIC_EXECUTION_CONFIG
#endif
#define QUIC_PARAM_GLOBAL_TLS_PROVIDER 0x0100000A // QUIC_TLS_PROVIDER

Просмотреть файл

@ -347,11 +347,6 @@ void
typedef CXPLAT_DATAPATH_SEND_COMPLETE *CXPLAT_DATAPATH_SEND_COMPLETE_HANDLER;
typedef struct CXPLAT_DATAPATH_CONFIG {
const uint16_t* DataPathProcList; // Processor index candidates
uint32_t DataPathProcListLength;
} CXPLAT_DATAPATH_CONFIG;
//
// Opens a new handle to the QUIC datapath.
//
@ -361,7 +356,7 @@ CxPlatDataPathInitialize(
_In_ uint32_t ClientRecvContextLength,
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
_In_opt_ CXPLAT_DATAPATH_CONFIG* Config,
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
_Out_ CXPLAT_DATAPATH** NewDatapath
);

Просмотреть файл

@ -143,7 +143,7 @@ typedef struct CXPLAT_SLIST_ENTRY {
#define QUIC_POOL_PLATFORM_WORKER '94cQ' // Qc49 - QUIC platform worker
#define QUIC_POOL_ROUTE_RESOLUTION_WORKER 'A4cQ' // Qc4A - QUIC route resolution worker
#define QUIC_POOL_ROUTE_RESOLUTION_OPER 'B4cQ' // Qc4B - QUIC route resolution operation
#define QUIC_POOL_RAW_DATAPATH_PROCS 'C4cQ' // Qc4C - QUIC raw datapath procs
#define QUIC_POOL_EXECUTION_CONFIG 'C4cQ' // Qc4C - QUIC execution config
typedef enum CXPLAT_THREAD_FLAGS {
CXPLAT_THREAD_FLAG_NONE = 0x0000,
@ -422,6 +422,8 @@ CxPlatGetAllocFailDenominator(
// loops.
//
typedef struct QUIC_EXECUTION_CONFIG QUIC_EXECUTION_CONFIG;
typedef struct CXPLAT_EXECUTION_CONTEXT CXPLAT_EXECUTION_CONTEXT;
typedef struct CXPLAT_EXECUTION_STATE {
@ -460,6 +462,10 @@ typedef struct CXPLAT_EXECUTION_CONTEXT {
} CXPLAT_EXECUTION_CONTEXT;
#ifdef _KERNEL_MODE // Not supported on kernel mode
#define CxPlatAddExecutionContext(Context, IdealProcessor) CXPLAT_FRE_ASSERT(FALSE)
#define CxPlatWakeExecutionContext(Context) CXPLAT_FRE_ASSERT(FALSE)
#else
void
CxPlatAddExecutionContext(
_Inout_ CXPLAT_EXECUTION_CONTEXT* Context,
@ -470,6 +476,7 @@ void
CxPlatWakeExecutionContext(
_In_ CXPLAT_EXECUTION_CONTEXT* Context
);
#endif
//
// The "type" of the completion queue event is stored as the first uint32_t of

Просмотреть файл

@ -535,6 +535,24 @@
value="12"
/>
</valueMap>
<valueMap name="map_QUIC_EXECUTION_PROFILE">
<map
message="$(string.Enum.QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_LOW_LATENCY)"
value="0"
/>
<map
message="$(string.Enum.QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT)"
value="1"
/>
<map
message="$(string.Enum.QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_TYPE_SCAVENGER)"
value="2"
/>
<map
message="$(string.Enum.QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_TYPE_REAL_TIME)"
value="3"
/>
</valueMap>
</maps>
<templates>
<template tid="tid_MESSAGE">
@ -663,6 +681,21 @@
name="AppName"
/>
</template>
<template tid="tid_REGISTRATION_STRING_EXEC">
<data
inType="win:Pointer"
name="Registration"
/>
<data
inType="win:AnsiString"
name="AppName"
/>
<data
inType="win:UInt32"
map="map_QUIC_EXECUTION_PROFILE"
name="ExecProfile"
/>
</template>
<template tid="tid_REGISTRATION_ERROR">
<data
inType="win:Pointer"
@ -2163,6 +2196,24 @@
template="tid_REGISTRATION_FLAGS_ERRORCODE"
value="1030"
/>
<event
keywords="ut:Registration ut:LowVolume"
level="win:Informational"
message="$(string.Etw.RegistrationCreatedV2)"
opcode="Registration"
symbol="QuicRegistrationCreatedV2"
template="tid_REGISTRATION_STRING_EXEC"
value="1031"
/>
<event
keywords="ut:Registration ut:LowVolume"
level="win:Informational"
message="$(string.Etw.RegistrationRundownV2)"
opcode="Registration"
symbol="QuicRegistrationRundownV2"
template="tid_REGISTRATION_STRING_EXEC"
value="1032"
/>
<!-- 2048 - 3071 | Worker Events -->
<event
keywords="ut:Worker ut:LowVolume"
@ -3747,10 +3798,18 @@
id="Etw.RegistrationCreated"
value="[ reg][%1] Created, AppName=%2"
/>
<string
id="Etw.RegistrationCreatedV2"
value="[ reg][%1] Created, AppName=%2, ExecProfile=%3"
/>
<string
id="Etw.RegistrationRundown"
value="[ reg][%1] Rundown, AppName=%2"
/>
<string
id="Etw.RegistrationRundownV2"
value="[ reg][%1] Rundown, AppName=%2, ExecProfile=%3"
/>
<string
id="Etw.RegistrationDestroyed"
value="[ reg][%1] Destroyed"
@ -4396,6 +4455,22 @@
id="Enum.QUIC_SEND_FLUSH_REASON.SCHEDULING"
value="SCHEDULING"
/>
<string
id="Enum.QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_LOW_LATENCY"
value="LOW_LATENCY"
/>
<string
id="Enum.QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT"
value="MAX_THROUGHPUT"
/>
<string
id="Enum.QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_TYPE_SCAVENGER"
value="SCAVENGER"
/>
<string
id="Enum.QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_TYPE_REAL_TIME"
value="REAL_TIME"
/>
<string
id="Etw.ConnNoListenerIp"
value="[conn][%1] No Listener for IP address: %3"

Просмотреть файл

@ -5853,6 +5853,13 @@
],
"macroName": "QuicTraceEvent"
},
"LibraryExecutionConfigSet": {
"ModuleProperites": {},
"TraceString": "[ lib] Setting execution config",
"UniqueId": "LibraryExecutionConfigSet",
"splitArgs": [],
"macroName": "QuicTraceLogInfo"
},
"LibraryInitializedV2": {
"ModuleProperites": {},
"TraceString": "[ lib] Initialized, PartitionCount=%u",
@ -8567,6 +8574,26 @@
],
"macroName": "QuicTraceEvent"
},
"RegistrationCreatedV2": {
"ModuleProperites": {},
"TraceString": "[ reg][%p] Created, AppName=%s, ExecProfile=%u",
"UniqueId": "RegistrationCreatedV2",
"splitArgs": [
{
"DefinationEncoding": "p",
"MacroVariableName": "arg2"
},
{
"DefinationEncoding": "s",
"MacroVariableName": "arg3"
},
{
"DefinationEncoding": "u",
"MacroVariableName": "arg4"
}
],
"macroName": "QuicTraceEvent"
},
"RegistrationRundown": {
"ModuleProperites": {},
"TraceString": "[ reg][%p] Rundown, AppName=%s",
@ -8583,6 +8610,26 @@
],
"macroName": "QuicTraceEvent"
},
"RegistrationRundownV2": {
"ModuleProperites": {},
"TraceString": "[ reg][%p] Rundown, AppName=%s, ExecProfile=%u",
"UniqueId": "RegistrationRundownV2",
"splitArgs": [
{
"DefinationEncoding": "p",
"MacroVariableName": "arg2"
},
{
"DefinationEncoding": "s",
"MacroVariableName": "arg3"
},
{
"DefinationEncoding": "u",
"MacroVariableName": "arg4"
}
],
"macroName": "QuicTraceEvent"
},
"RegistrationVerifierEnabled": {
"ModuleProperites": {},
"TraceString": "[ reg][%p] Verifing enabled!",
@ -13495,6 +13542,11 @@
"TraceID": "LibraryErrorStatus",
"EncodingString": "[ lib] ERROR, %u, %s."
},
{
"UniquenessHash": "e9a6fe1f-54f6-7cc0-0dc8-8e6dfbc8beec",
"TraceID": "LibraryExecutionConfigSet",
"EncodingString": "[ lib] Setting execution config"
},
{
"UniquenessHash": "49364a79-a042-c58c-1024-f2b92b2bf039",
"TraceID": "LibraryInitializedV2",
@ -14405,11 +14457,21 @@
"TraceID": "RegistrationCreated",
"EncodingString": "[ reg][%p] Created, AppName=%s"
},
{
"UniquenessHash": "ac192139-6140-6e50-94ef-26748ce5e25d",
"TraceID": "RegistrationCreatedV2",
"EncodingString": "[ reg][%p] Created, AppName=%s, ExecProfile=%u"
},
{
"UniquenessHash": "6f6956ec-af60-d54a-176e-c9db6ac7a50a",
"TraceID": "RegistrationRundown",
"EncodingString": "[ reg][%p] Rundown, AppName=%s"
},
{
"UniquenessHash": "c62e1ef6-4e2c-d370-bce8-970873aa3979",
"TraceID": "RegistrationRundownV2",
"EncodingString": "[ reg][%p] Rundown, AppName=%s, ExecProfile=%u"
},
{
"UniquenessHash": "cf0f3e68-b28d-2378-09be-480fa6147054",
"TraceID": "RegistrationVerifierEnabled",

Просмотреть файл

@ -95,14 +95,15 @@ public:
HpsWorkerContext Contexts[PERF_MAX_THREAD_COUNT];
MsQuicRegistration Registration {
"secnetperf-client-hps",
QUIC_EXECUTION_PROFILE_LOW_LATENCY,
PerfDefaultExecutionProfile,
false};
MsQuicConfiguration Configuration {
Registration,
MsQuicAlpn(PERF_ALPN),
MsQuicSettings()
.SetDisconnectTimeoutMs(PERF_DEFAULT_DISCONNECT_TIMEOUT)
.SetIdleTimeoutMs(HPS_DEFAULT_IDLE_TIMEOUT),
.SetIdleTimeoutMs(HPS_DEFAULT_IDLE_TIMEOUT)
.SetCongestionControlAlgorithm(PerfDefaultCongestionControl),
MsQuicCredentialConfig(
QUIC_CREDENTIAL_FLAG_CLIENT |
QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION)};

Просмотреть файл

@ -38,3 +38,6 @@ Abstract:
#define HPS_DEFAULT_IDLE_TIMEOUT (5 * 1000)
#define HPS_DEFAULT_PARALLEL_COUNT 100
#define HPS_BINDINGS_PER_WORKER 10
extern QUIC_EXECUTION_PROFILE PerfDefaultExecutionProfile;
extern QUIC_CONGESTION_CONTROL_ALGORITHM PerfDefaultCongestionControl;

Просмотреть файл

@ -18,19 +18,7 @@ Abstract:
class PerfServer : public PerfBase {
public:
PerfServer(const QUIC_CREDENTIAL_CONFIG* CredConfig, QUIC_CONGESTION_CONTROL_ALGORITHM Cc) :
Configuration {
Registration,
Alpn,
MsQuicSettings()
.SetConnFlowControlWindow(PERF_DEFAULT_CONN_FLOW_CONTROL)
.SetPeerBidiStreamCount(PERF_DEFAULT_STREAM_COUNT)
.SetPeerUnidiStreamCount(PERF_DEFAULT_STREAM_COUNT)
.SetDisconnectTimeoutMs(PERF_DEFAULT_DISCONNECT_TIMEOUT)
.SetIdleTimeoutMs(PERF_DEFAULT_IDLE_TIMEOUT)
.SetSendBufferingEnabled(false)
.SetServerResumptionLevel(QUIC_SERVER_RESUME_AND_ZERORTT)
.SetCongestionControlAlgorithm(Cc)},
PerfServer(const QUIC_CREDENTIAL_CONFIG* CredConfig) :
Engine(TcpAcceptCallback, TcpConnectCallback, TcpReceiveCallback, TcpSendCompleteCallback),
Server(&Engine, CredConfig, this) {
CxPlatZeroMemory(&LocalAddr, sizeof(LocalAddr));
@ -138,10 +126,21 @@ private:
QUIC_STATUS InitStatus;
MsQuicRegistration Registration {
"secnetperf-server",
QUIC_EXECUTION_PROFILE_LOW_LATENCY,
PerfDefaultExecutionProfile,
true};
MsQuicAlpn Alpn {PERF_ALPN};
MsQuicConfiguration Configuration;
MsQuicConfiguration Configuration {
Registration,
Alpn,
MsQuicSettings()
.SetConnFlowControlWindow(PERF_DEFAULT_CONN_FLOW_CONTROL)
.SetPeerBidiStreamCount(PERF_DEFAULT_STREAM_COUNT)
.SetPeerUnidiStreamCount(PERF_DEFAULT_STREAM_COUNT)
.SetDisconnectTimeoutMs(PERF_DEFAULT_DISCONNECT_TIMEOUT)
.SetIdleTimeoutMs(PERF_DEFAULT_IDLE_TIMEOUT)
.SetSendBufferingEnabled(false)
.SetServerResumptionLevel(QUIC_SERVER_RESUME_AND_ZERORTT)
.SetCongestionControlAlgorithm(PerfDefaultCongestionControl)};
MsQuicListener Listener {Registration, ListenerCallbackStatic, this};
QUIC_ADDR LocalAddr;
CXPLAT_EVENT* StopEvent {nullptr};

Просмотреть файл

@ -159,7 +159,7 @@ public:
MsQuicRegistration Registration {
"secnetperf-client-rps",
QUIC_EXECUTION_PROFILE_LOW_LATENCY,
PerfDefaultExecutionProfile,
true};
MsQuicConfiguration Configuration {
Registration,
@ -167,7 +167,8 @@ public:
MsQuicSettings()
.SetDisconnectTimeoutMs(PERF_DEFAULT_DISCONNECT_TIMEOUT)
.SetIdleTimeoutMs(PERF_DEFAULT_IDLE_TIMEOUT)
.SetSendBufferingEnabled(false),
.SetSendBufferingEnabled(false)
.SetCongestionControlAlgorithm(PerfDefaultCongestionControl),
MsQuicCredentialConfig(
QUIC_CREDENTIAL_FLAG_CLIENT |
QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION)};

Просмотреть файл

@ -16,10 +16,6 @@ Abstract:
#include "HpsClient.h"
#include "Tcp.h"
#ifndef _KERNEL_MODE
#include <vector>
#endif
#ifdef QUIC_CLOG
#include "SecNetPerfMain.cpp.clog.h"
#endif
@ -29,6 +25,8 @@ volatile int BufferCurrent;
char Buffer[BufferLength];
PerfBase* TestToRun;
QUIC_EXECUTION_PROFILE PerfDefaultExecutionProfile = QUIC_EXECUTION_PROFILE_LOW_LATENCY;
QUIC_CONGESTION_CONTROL_ALGORITHM PerfDefaultCongestionControl = QUIC_CONGESTION_CONTROL_ALGORITHM_CUBIC;
#include "quic_datapath.h"
@ -93,61 +91,20 @@ PrintHelp(
"\n"
" -bind:<addr> A local IP address to bind to.\n"
" -cibir:<hex_bytes> A CIBIR well-known idenfitier.\n"
" -cc:<algo> Congestion control algorithm to use.\n"
"\n"
"Client: secnetperf -TestName:<Throughput|RPS|HPS> [options]\n"
#ifndef _KERNEL_MODE
"Both:\n"
" -cpu:<cpu_index> Specify the processor(s) for the datapath to use.\n"
" -exec:<profile> Execution profile to use {lowlat, maxtput, scavenger, realtime}.\n"
" -cc:<algo> Congestion control algorithm to use {cubic, bbr}.\n"
" -pollidle:<time_us> Amount of time to poll while idle before sleeping (default: 0).\n"
#ifndef _KERNEL_MODE
" -cpu:<cpu_index> Specify the processor(s) to use.\n"
" -cipher:<value> Decimal value of 1 or more QUIC_ALLOWED_CIPHER_SUITE_FLAGS.\n"
#endif // _KERNEL_MODE
"\n"
);
}
#ifdef QUIC_USE_RAW_DATAPATH
CXPLAT_THREAD_CALLBACK(ControlThread, Context)
{
WSADATA WsaData;
WSAStartup(MAKEWORD(2, 2), &WsaData);
CXPLAT_EVENT* Event = static_cast<CXPLAT_EVENT*>(Context);
SOCKADDR_STORAGE Addr = {0};
uint8_t RecvBuf[sizeof(SecNetPerfShutdownGuid)] = {0};
IN4ADDR_SETANY((SOCKADDR_IN*)&Addr);
SS_PORT(&Addr) = htons(9999);
SOCKET Listener = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (bind(Listener, (SOCKADDR*)&Addr, sizeof(Addr)) == SOCKET_ERROR) {
printf("control listener failed to bind with error %d\n", WSAGetLastError());
goto Done;
}
while (true) {
int BytesRcvd =
recvfrom(
Listener, (char*)RecvBuf, sizeof(RecvBuf), 0, NULL, NULL);
if (BytesRcvd == SOCKET_ERROR) {
int Error = WSAGetLastError();
if (Error == WSAEMSGSIZE) {
continue;
}
printf("recvfrom failed with error %d\n", Error);
goto Done;
}
if (BytesRcvd == sizeof(RecvBuf) &&
memcmp(RecvBuf, SecNetPerfShutdownGuid, sizeof(SecNetPerfShutdownGuid)) == 0) {
break;
}
}
Done:
CxPlatEventSet(*Event);
closesocket(Listener);
CXPLAT_THREAD_RETURN(QUIC_STATUS_SUCCESS);
}
#endif
QUIC_STATUS
QuicMainStart(
_In_ int argc,
@ -179,22 +136,6 @@ QuicMainStart(
QUIC_STATUS Status;
#ifdef QUIC_USE_RAW_DATAPATH
if (ServerMode) {
CXPLAT_THREAD_CONFIG ThreadConfig = {
CXPLAT_THREAD_FLAG_NONE,
0,
"ControlThread",
ControlThread,
StopEvent
};
Status = CxPlatThreadCreate(&ThreadConfig, &ControlThreadHandle);
if (QUIC_FAILED(Status)) {
return Status;
}
}
#else
const CXPLAT_UDP_DATAPATH_CALLBACKS DatapathCallbacks = {
DatapathReceive,
DatapathUnreachable
@ -231,7 +172,6 @@ QuicMainStart(
return Status;
}
}
#endif
MsQuic = new(std::nothrow) MsQuicApi;
if (MsQuic == nullptr) {
@ -247,53 +187,76 @@ QuicMainStart(
return Status;
}
uint8_t RawConfig[QUIC_EXECUTION_CONFIG_MIN_SIZE + 256 * sizeof(uint16_t)] = {0};
QUIC_EXECUTION_CONFIG* Config = (QUIC_EXECUTION_CONFIG*)RawConfig;
Config->PollingIdleTimeoutUs = UINT32_MAX; // Default to no sleep.
bool SetConfig = false;
#ifndef _KERNEL_MODE
const char* CpuStr;
if ((CpuStr = GetValue(argc, argv, "cpu")) != nullptr) {
std::vector<uint16_t> ProcList;
SetConfig = true;
if (strtol(CpuStr, nullptr, 10) == -1) {
// Use all procs for raw datapath except proc 0 so that the machine will be in a usable state.
for (uint16_t i = 1; i < CxPlatProcActiveCount(); ++i) {
ProcList.push_back(i);
for (uint16_t i = 0; i < CxPlatProcActiveCount() && Config->ProcessorCount < 256; ++i) {
Config->ProcessorList[Config->ProcessorCount++] = i;
}
} else {
do {
if (*CpuStr == ',') CpuStr++;
ProcList.push_back((uint16_t)strtoul(CpuStr, (char**)&CpuStr, 10));
} while (*CpuStr);
Config->ProcessorList[Config->ProcessorCount++] =
(uint16_t)strtoul(CpuStr, (char**)&CpuStr, 10);
} while (*CpuStr && Config->ProcessorCount < 256);
}
if (QUIC_FAILED(
Status =
MsQuic->SetParam(
nullptr,
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
(uint32_t)ProcList.size() * sizeof(uint16_t),
ProcList.data()))) {
WriteOutput("MsQuic Failed To Set DataPath Procs %d\n", Status);
return Status;
}
}
}
#endif // _KERNEL_MODE
QUIC_CONGESTION_CONTROL_ALGORITHM Cc = QUIC_CONGESTION_CONTROL_ALGORITHM_CUBIC;
if (TryGetValue(argc, argv, "pollidle", &Config->PollingIdleTimeoutUs)) {
SetConfig = true;
}
if (SetConfig &&
QUIC_FAILED(
Status =
MsQuic->SetParam(
nullptr,
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
(uint32_t)QUIC_EXECUTION_CONFIG_MIN_SIZE + Config->ProcessorCount * sizeof(uint16_t),
Config))) {
WriteOutput("Failed to set execution config %d\n", Status);
return Status;
}
const char* ExecStr = GetValue(argc, argv, "exec");
if (ExecStr != nullptr) {
if (IsValue(ExecStr, "lowlat")) {
PerfDefaultExecutionProfile = QUIC_EXECUTION_PROFILE_LOW_LATENCY;
} else if (IsValue(ExecStr, "maxtput")) {
PerfDefaultExecutionProfile = QUIC_EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT;
} else if (IsValue(ExecStr, "scavenger")) {
PerfDefaultExecutionProfile = QUIC_EXECUTION_PROFILE_TYPE_SCAVENGER;
} else if (IsValue(ExecStr, "realtime")) {
PerfDefaultExecutionProfile = QUIC_EXECUTION_PROFILE_TYPE_REAL_TIME;
} else {
WriteOutput("Failed to parse execution profile[%s], use lowlat as default\n", ExecStr);
}
}
const char* CcName = GetValue(argc, argv, "cc");
if (CcName != nullptr) {
if (IsValue(CcName, "cubic")) {
Cc = QUIC_CONGESTION_CONTROL_ALGORITHM_CUBIC;
PerfDefaultCongestionControl = QUIC_CONGESTION_CONTROL_ALGORITHM_CUBIC;
} else if (IsValue(CcName, "bbr")) {
Cc = QUIC_CONGESTION_CONTROL_ALGORITHM_BBR;
PerfDefaultCongestionControl = QUIC_CONGESTION_CONTROL_ALGORITHM_BBR;
} else {
WriteOutput("Failed to parse congestion control algorithm[%s], use cubic as default\n", CcName);
}
}
if (ServerMode) {
TestToRun = new(std::nothrow) PerfServer(SelfSignedCredConfig, Cc);
TestToRun = new(std::nothrow) PerfServer(SelfSignedCredConfig);
} else {
if (IsValue(TestName, "Throughput") || IsValue(TestName, "tput")) {
TestToRun = new(std::nothrow) ThroughputClient(Cc);
TestToRun = new(std::nothrow) ThroughputClient;
} else if (IsValue(TestName, "RPS")) {
TestToRun = new(std::nothrow) RpsClient;
} else if (IsValue(TestName, "HPS")) {
@ -354,17 +317,10 @@ QuicMainFree(
Binding = nullptr;
}
#ifdef QUIC_USE_RAW_DATAPATH
if (ControlThreadHandle) {
CxPlatThreadWait(&ControlThreadHandle);
CxPlatThreadDelete(&ControlThreadHandle);
}
#else
if (Datapath) {
CxPlatDataPathUninitialize(Datapath);
Datapath = nullptr;
}
#endif
delete Watchdog;
Watchdog = nullptr;

Просмотреть файл

@ -19,17 +19,7 @@ Abstract:
class ThroughputClient : public PerfBase {
public:
ThroughputClient(QUIC_CONGESTION_CONTROL_ALGORITHM Cc) :
Configuration {
Registration,
MsQuicAlpn(PERF_ALPN),
MsQuicSettings()
.SetConnFlowControlWindow(PERF_DEFAULT_CONN_FLOW_CONTROL)
.SetIdleTimeoutMs(TPUT_DEFAULT_IDLE_TIMEOUT)
.SetCongestionControlAlgorithm(Cc),
MsQuicCredentialConfig(
QUIC_CREDENTIAL_FLAG_CLIENT |
QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION)},
ThroughputClient() :
Engine(nullptr, TcpConnectCallback, TcpReceiveCallback, TcpSendCompleteCallback) {
CxPlatZeroMemory(&LocalIpAddr, sizeof(LocalIpAddr));
CxPlatLockInitialize(&TcpLock);
@ -119,9 +109,18 @@ private:
MsQuicRegistration Registration {
"secnetperf-client-tput",
QUIC_EXECUTION_PROFILE_LOW_LATENCY,
PerfDefaultExecutionProfile,
true};
MsQuicConfiguration Configuration;
MsQuicConfiguration Configuration {
Registration,
MsQuicAlpn(PERF_ALPN),
MsQuicSettings()
.SetConnFlowControlWindow(PERF_DEFAULT_CONN_FLOW_CONTROL)
.SetIdleTimeoutMs(TPUT_DEFAULT_IDLE_TIMEOUT)
.SetCongestionControlAlgorithm(PerfDefaultCongestionControl),
MsQuicCredentialConfig(
QUIC_CREDENTIAL_FLAG_CLIENT |
QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION)};
QuicPoolAllocator<StreamContext> StreamContextAllocator;
UniquePtr<char[]> TargetData;
CXPLAT_EVENT* StopEvent {nullptr};

Просмотреть файл

@ -354,9 +354,9 @@ typedef struct QUIC_CACHEALIGN CXPLAT_DATAPATH_PROC {
CXPLAT_REF_COUNT RefCount;
//
// The index of the context in the datapath's array.
// The ideal processor of the context.
//
uint32_t Index;
uint16_t IdealProcessor;
#if DEBUG
uint8_t Uninitialized : 1;
@ -420,10 +420,25 @@ typedef struct CXPLAT_DATAPATH {
//
// The per proc datapath contexts.
//
CXPLAT_DATAPATH_PROC DatapathProcs[];
CXPLAT_DATAPATH_PROC Processors[];
} CXPLAT_DATAPATH;
CXPLAT_DATAPATH_PROC*
CxPlatDataPathGetProc(
_In_ CXPLAT_DATAPATH* Datapath,
_In_ uint16_t Processor
)
{
for (uint32_t i = 0; i < Datapath->ProcCount; ++i) {
if (Datapath->Processors[i].IdealProcessor == Processor) {
return &Datapath->Processors[i];
}
}
CXPLAT_FRE_ASSERT(FALSE); // TODO - What now?!
return NULL;
}
QUIC_STATUS
CxPlatSocketSendInternal(
_In_ CXPLAT_SOCKET* Socket,
@ -484,7 +499,7 @@ Error:
void
CxPlatProcessorContextInitialize(
_In_ CXPLAT_DATAPATH* Datapath,
_In_ uint32_t Index,
_In_ uint16_t IdealProcessor,
_In_ uint32_t ClientRecvContextLength,
_Out_ CXPLAT_DATAPATH_PROC* DatapathProc
)
@ -494,9 +509,9 @@ CxPlatProcessorContextInitialize(
CXPLAT_DBG_ASSERT(Datapath != NULL);
DatapathProc->Datapath = Datapath;
DatapathProc->Index = Index;
DatapathProc->IdealProcessor = IdealProcessor;
DatapathProc->EventQ = CxPlatWorkerGetEventQ(IdealProcessor);
CxPlatRefInitialize(&DatapathProc->RefCount);
DatapathProc->EventQ = CxPlatWorkerGetEventQ((uint16_t)Index);
CxPlatPoolInitialize(
TRUE,
@ -525,12 +540,11 @@ CxPlatDataPathInitialize(
_In_ uint32_t ClientRecvContextLength,
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
_In_opt_ CXPLAT_DATAPATH_CONFIG* Config,
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
_Out_ CXPLAT_DATAPATH** NewDataPath
)
{
UNREFERENCED_PARAMETER(TcpCallbacks);
UNREFERENCED_PARAMETER(Config);
if (NewDataPath == NULL) {
return QUIC_STATUS_INVALID_PARAMETER;
}
@ -540,11 +554,25 @@ CxPlatDataPathInitialize(
}
}
const size_t DatapathLength =
sizeof(CXPLAT_DATAPATH) +
CxPlatProcMaxCount() * sizeof(CXPLAT_DATAPATH_PROC);
if (!CxPlatWorkersLazyStart(Config)) {
return QUIC_STATUS_OUT_OF_MEMORY;
}
CXPLAT_DATAPATH* Datapath = (CXPLAT_DATAPATH*)CXPLAT_ALLOC_PAGED(DatapathLength, QUIC_POOL_DATAPATH);
const uint16_t* ProcessorList;
uint32_t ProcessorCount;
if (Config && Config->ProcessorCount) {
ProcessorCount = Config->ProcessorCount;
ProcessorList = Config->ProcessorList;
} else {
ProcessorCount = CxPlatProcMaxCount();
ProcessorList = NULL;
}
const size_t DatapathLength =
sizeof(CXPLAT_DATAPATH) + ProcessorCount * sizeof(CXPLAT_DATAPATH_PROC);
CXPLAT_DATAPATH* Datapath =
(CXPLAT_DATAPATH*)CXPLAT_ALLOC_PAGED(DatapathLength, QUIC_POOL_DATAPATH);
if (Datapath == NULL) {
QuicTraceEvent(
AllocFailure,
@ -558,7 +586,7 @@ CxPlatDataPathInitialize(
if (UdpCallbacks) {
Datapath->UdpHandlers = *UdpCallbacks;
}
Datapath->ProcCount = CxPlatProcMaxCount();
Datapath->ProcCount = ProcessorCount;
Datapath->Features = CXPLAT_DATAPATH_FEATURE_LOCAL_PORT_SHARING;
CxPlatRefInitializeEx(&Datapath->RefCount, Datapath->ProcCount);
@ -574,7 +602,11 @@ CxPlatDataPathInitialize(
// Initialize the per processor contexts.
//
for (uint32_t i = 0; i < Datapath->ProcCount; i++) {
CxPlatProcessorContextInitialize(Datapath, i, ClientRecvContextLength, &Datapath->DatapathProcs[i]);
CxPlatProcessorContextInitialize(
Datapath,
ProcessorList ? ProcessorList[i] : (uint16_t)i,
ClientRecvContextLength,
&Datapath->Processors[i]);
}
CXPLAT_FRE_ASSERT(CxPlatRundownAcquire(&CxPlatWorkerRundown));
@ -631,7 +663,7 @@ CxPlatDataPathUninitialize(
#endif
const uint16_t ProcCount = Datapath->ProcCount;
for (uint32_t i = 0; i < ProcCount; i++) {
CxPlatProcessorContextRelease(&Datapath->DatapathProcs[i]);
CxPlatProcessorContextRelease(&Datapath->Processors[i]);
}
}
}
@ -1512,7 +1544,7 @@ CxPlatSocketContextRecvComplete(
CXPLAT_FRE_ASSERT(FoundLocalAddr);
CXPLAT_FRE_ASSERT(FoundTOS);
RecvPacket->PartitionIndex = SocketContext->DatapathProc->Index;
RecvPacket->PartitionIndex = SocketContext->DatapathProc->IdealProcessor;
QuicTraceEvent(
DatapathRecv,
@ -1817,7 +1849,10 @@ CxPlatSocketCreateUdp(
Binding->SocketContexts[i].RecvIov[j].iov_len =
Binding->Mtu - CXPLAT_MIN_IPV4_HEADER_SIZE - CXPLAT_UDP_HEADER_SIZE;
}
Binding->SocketContexts[i].DatapathProc = &Datapath->DatapathProcs[IsServerSocket ? i : CurrentProc];
Binding->SocketContexts[i].DatapathProc =
IsServerSocket ?
&Datapath->Processors[i] :
CxPlatDataPathGetProc(Datapath, CurrentProc);
CxPlatRefIncrement(&Binding->SocketContexts[i].DatapathProc->RefCount);
CxPlatListInitializeHead(&Binding->SocketContexts[i].PendingSendDataHead);
CxPlatLockInitialize(&Binding->SocketContexts[i].PendingSendDataLock);
@ -2013,7 +2048,7 @@ CxPlatSendDataAlloc(
CXPLAT_DBG_ASSERT(Socket != NULL);
CXPLAT_DATAPATH_PROC* DatapathProc =
&Socket->Datapath->DatapathProcs[CxPlatProcCurrentNumber() % Socket->Datapath->ProcCount];
CxPlatDataPathGetProc(Socket->Datapath, CxPlatProcCurrentNumber());
CXPLAT_SEND_DATA* SendData =
CxPlatPoolAlloc(&DatapathProc->SendDataPool);

Просмотреть файл

@ -319,9 +319,9 @@ typedef struct QUIC_CACHEALIGN CXPLAT_DATAPATH_PROC {
CXPLAT_REF_COUNT RefCount;
//
// The index of the context in the datapath's array.
// The ideal processor of the context.
//
uint32_t Index;
uint16_t IdealProcessor;
#if DEBUG
uint8_t Uninitialized : 1;
@ -386,10 +386,25 @@ typedef struct CXPLAT_DATAPATH {
//
// The per proc datapath contexts.
//
CXPLAT_DATAPATH_PROC DatapathProcs[];
CXPLAT_DATAPATH_PROC Processors[];
} CXPLAT_DATAPATH;
CXPLAT_DATAPATH_PROC*
CxPlatDataPathGetProc(
_In_ CXPLAT_DATAPATH* Datapath,
_In_ uint16_t Processor
)
{
for (uint32_t i = 0; i < Datapath->ProcCount; ++i) {
if (Datapath->Processors[i].IdealProcessor == Processor) {
return &Datapath->Processors[i];
}
}
CXPLAT_FRE_ASSERT(FALSE); // TODO - What now?!
return NULL;
}
QUIC_STATUS
CxPlatSocketSendInternal(
_In_ CXPLAT_SOCKET* Socket,
@ -402,7 +417,7 @@ CxPlatSocketSendInternal(
void
CxPlatProcessorContextInitialize(
_In_ CXPLAT_DATAPATH* Datapath,
_In_ uint32_t Index,
_In_ uint16_t IdealProcessor,
_In_ uint32_t ClientRecvContextLength,
_Out_ CXPLAT_DATAPATH_PROC* DatapathProc
)
@ -412,8 +427,8 @@ CxPlatProcessorContextInitialize(
CXPLAT_DBG_ASSERT(Datapath != NULL);
DatapathProc->Datapath = Datapath;
DatapathProc->Index = Index;
DatapathProc->EventQ = CxPlatWorkerGetEventQ((uint16_t)Index);
DatapathProc->IdealProcessor = IdealProcessor;
DatapathProc->EventQ = CxPlatWorkerGetEventQ(IdealProcessor);
CxPlatRefInitialize(&DatapathProc->RefCount);
CxPlatPoolInitialize(
@ -443,12 +458,11 @@ CxPlatDataPathInitialize(
_In_ uint32_t ClientRecvContextLength,
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
_In_opt_ CXPLAT_DATAPATH_CONFIG* Config,
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
_Out_ CXPLAT_DATAPATH** NewDataPath
)
{
UNREFERENCED_PARAMETER(TcpCallbacks);
UNREFERENCED_PARAMETER(Config);
if (NewDataPath == NULL) {
return QUIC_STATUS_INVALID_PARAMETER;
}
@ -458,9 +472,22 @@ CxPlatDataPathInitialize(
}
}
if (!CxPlatWorkersLazyStart(Config)) {
return QUIC_STATUS_OUT_OF_MEMORY;
}
const uint16_t* ProcessorList;
uint32_t ProcessorCount;
if (Config && Config->ProcessorCount) {
ProcessorCount = Config->ProcessorCount;
ProcessorList = Config->ProcessorList;
} else {
ProcessorCount = CxPlatProcMaxCount();
ProcessorList = NULL;
}
const size_t DatapathLength =
sizeof(CXPLAT_DATAPATH) +
CxPlatProcMaxCount() * sizeof(CXPLAT_DATAPATH_PROC);
sizeof(CXPLAT_DATAPATH) + ProcessorCount * sizeof(CXPLAT_DATAPATH_PROC);
CXPLAT_DATAPATH* Datapath = (CXPLAT_DATAPATH*)CXPLAT_ALLOC_PAGED(DatapathLength, QUIC_POOL_DATAPATH);
if (Datapath == NULL) {
@ -476,11 +503,15 @@ CxPlatDataPathInitialize(
if (UdpCallbacks) {
Datapath->UdpHandlers = *UdpCallbacks;
}
Datapath->ProcCount = 1; //CxPlatProcMaxCount(); // Darwin only supports a single receiver
Datapath->ProcCount = 1; //ProcessorCount; // Darwin only supports a single receiver
CxPlatRefInitializeEx(&Datapath->RefCount, Datapath->ProcCount);
for (uint32_t i = 0; i < Datapath->ProcCount; i++) {
CxPlatProcessorContextInitialize(Datapath, i, ClientRecvContextLength, &Datapath->DatapathProcs[i]);
CxPlatProcessorContextInitialize(
Datapath,
ProcessorList ? ProcessorList[i] : (uint16_t)i,
ClientRecvContextLength,
&Datapath->Processors[i]);
}
CXPLAT_FRE_ASSERT(CxPlatRundownAcquire(&CxPlatWorkerRundown));
@ -537,7 +568,7 @@ CxPlatDataPathUninitialize(
#endif
const uint16_t ProcCount = Datapath->ProcCount;
for (uint32_t i = 0; i < ProcCount; i++) {
CxPlatProcessorContextRelease(&Datapath->DatapathProcs[i]);
CxPlatProcessorContextRelease(&Datapath->Processors[i]);
}
}
}
@ -1309,7 +1340,7 @@ CxPlatSocketContextRecvComplete(
CXPLAT_DBG_ASSERT(BytesTransferred <= RecvPacket->BufferLength);
RecvPacket->BufferLength = BytesTransferred;
RecvPacket->PartitionIndex = SocketContext->DatapathProc->Index;
RecvPacket->PartitionIndex = SocketContext->DatapathProc->IdealProcessor;
if (!SocketContext->Binding->PcpBinding) {
CXPLAT_DBG_ASSERT(SocketContext->Binding->Datapath->UdpHandlers.Receive);
@ -1548,7 +1579,10 @@ CxPlatSocketCreateUdp(
Binding->SocketContexts[i].IoCqeType = CXPLAT_CQE_TYPE_SOCKET_IO;
Binding->SocketContexts[i].RecvIov.iov_len =
Binding->Mtu - CXPLAT_MIN_IPV4_HEADER_SIZE - CXPLAT_UDP_HEADER_SIZE;
Binding->SocketContexts[i].DatapathProc = &Datapath->DatapathProcs[IsServerSocket ? i : CurrentProc];
Binding->SocketContexts[i].DatapathProc =
IsServerSocket ?
&Datapath->Processors[i] :
CxPlatDataPathGetProc(Datapath, CurrentProc);
CxPlatRefIncrement(&Binding->SocketContexts[i].DatapathProc->RefCount);
CxPlatListInitializeHead(&Binding->SocketContexts[i].PendingSendDataHead);
CxPlatLockInitialize(&Binding->SocketContexts[i].PendingSendDataLock);
@ -1733,7 +1767,7 @@ CxPlatSendDataAlloc(
CXPLAT_DBG_ASSERT(Socket != NULL);
CXPLAT_DATAPATH_PROC* DatapathProc =
&Socket->Datapath->DatapathProcs[CxPlatProcCurrentNumber() % Socket->Datapath->ProcCount];
CxPlatDataPathGetProc(Socket->Datapath, CxPlatProcCurrentNumber());
CXPLAT_SEND_DATA* SendData =
CxPlatPoolAlloc(&DatapathProc->SendDataPool);

Просмотреть файл

@ -108,7 +108,7 @@ CxPlatDataPathInitialize(
_In_ uint32_t ClientRecvContextLength,
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
_In_opt_ CXPLAT_DATAPATH_CONFIG* Config,
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
_Out_ CXPLAT_DATAPATH** NewDataPath
)
{
@ -129,6 +129,10 @@ CxPlatDataPathInitialize(
}
}
if (!CxPlatWorkersLazyStart(Config)) {
return QUIC_STATUS_OUT_OF_MEMORY;
}
CXPLAT_DATAPATH* DataPath = CXPLAT_ALLOC_PAGED(DatapathSize, QUIC_POOL_DATAPATH);
if (DataPath == NULL) {
QuicTraceEvent(
@ -168,6 +172,9 @@ CxPlatDataPathInitialize(
Error:
if (DataPath != NULL) {
#if DEBUG
DataPath->Uninitialized = TRUE;
#endif
if (DpRawInitialized) {
CxPlatDpRawUninitialize(DataPath);
} else {

Просмотреть файл

@ -106,7 +106,7 @@ typedef struct CXPLAT_SEND_DATA {
_IRQL_requires_max_(PASSIVE_LEVEL)
size_t
CxPlatDpRawGetDatapathSize(
_In_opt_ const CXPLAT_DATAPATH_CONFIG* Config
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
);
//
@ -117,7 +117,7 @@ QUIC_STATUS
CxPlatDpRawInitialize(
_Inout_ CXPLAT_DATAPATH* Datapath,
_In_ uint32_t ClientRecvContextLength,
_In_opt_ const CXPLAT_DATAPATH_CONFIG* Config
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
);
//

Просмотреть файл

@ -142,7 +142,7 @@ CxPlatDpdkReadConfig(
_IRQL_requires_max_(PASSIVE_LEVEL)
size_t
CxPlatDpRawGetDatapathSize(
_In_opt_ const CXPLAT_DATAPATH_CONFIG* Config
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
)
{
UNREFERENCED_PARAMETER(Config);
@ -154,7 +154,7 @@ QUIC_STATUS
CxPlatDpRawInitialize(
_Inout_ CXPLAT_DATAPATH* Datapath,
_In_ uint32_t ClientRecvContextLength,
_In_opt_ const CXPLAT_DATAPATH_CONFIG* Config
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
)
{
DPDK_DATAPATH* Dpdk = (DPDK_DATAPATH*)Datapath;

Просмотреть файл

@ -977,11 +977,11 @@ CxPlatDpRawInterfaceRemoveRules(
_IRQL_requires_max_(PASSIVE_LEVEL)
size_t
CxPlatDpRawGetDatapathSize(
_In_opt_ const CXPLAT_DATAPATH_CONFIG* Config
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
)
{
const uint32_t WorkerCount =
(Config && Config->DataPathProcList) ? Config->DataPathProcListLength : 1;
(Config && Config->ProcessorCount) ? Config->ProcessorCount : CxPlatProcMaxCount();
return sizeof(XDP_DATAPATH) + (WorkerCount * sizeof(XDP_WORKER));
}
@ -990,20 +990,23 @@ QUIC_STATUS
CxPlatDpRawInitialize(
_Inout_ CXPLAT_DATAPATH* Datapath,
_In_ uint32_t ClientRecvContextLength,
_In_opt_ const CXPLAT_DATAPATH_CONFIG* Config
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
)
{
XDP_DATAPATH* Xdp = (XDP_DATAPATH*)Datapath;
QUIC_STATUS Status;
uint16_t DefaultProc = (uint16_t)(CxPlatProcMaxCount() - 1);
const uint16_t* ProcList =
(Config && Config->DataPathProcList) ? Config->DataPathProcList : &DefaultProc;
const uint16_t* ProcessorList;
CxPlatXdpReadConfig(Xdp);
CxPlatListInitializeHead(&Xdp->Interfaces);
Xdp->WorkerCount =
(Config && Config->DataPathProcList) ? Config->DataPathProcListLength : 1;
if (Config && Config->ProcessorCount) {
Xdp->WorkerCount = Config->ProcessorCount;
ProcessorList = Config->ProcessorList;
} else {
Xdp->WorkerCount = CxPlatProcMaxCount();
ProcessorList = NULL;
}
PIP_ADAPTER_ADDRESSES Adapters = NULL;
ULONG Error;
@ -1114,14 +1117,14 @@ CxPlatDpRawInitialize(
break;
}
Xdp->Workers[i].Xdp = Xdp;
Xdp->Workers[i].ProcIndex = ProcList[i];
Xdp->Workers[i].ProcIndex = ProcessorList ? ProcessorList[i] : (uint16_t)i;
Xdp->Workers[i].Ready = TRUE;
Xdp->Workers[i].NextTimeUs = UINT64_MAX;
Xdp->Workers[i].Callback = CxPlatXdpExecute;
Xdp->Workers[i].Context = &Xdp->Workers[i];
CxPlatRefIncrement(&Xdp->RefCount);
CxPlatAddExecutionContext(
(CXPLAT_EXECUTION_CONTEXT*)&Xdp->Workers[i], ProcList[i]);
(CXPLAT_EXECUTION_CONTEXT*)&Xdp->Workers[i], Xdp->Workers[i].ProcIndex);
}
Status = QUIC_STATUS_SUCCESS;

Просмотреть файл

@ -824,7 +824,7 @@ CxPlatDataPathInitialize(
_In_ uint32_t ClientRecvContextLength,
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
_In_opt_ CXPLAT_DATAPATH_CONFIG* Config,
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
_Out_ CXPLAT_DATAPATH* *NewDataPath
)
{

Просмотреть файл

@ -373,9 +373,9 @@ typedef struct QUIC_CACHEALIGN CXPLAT_DATAPATH_PROC {
CXPLAT_REF_COUNT RefCount;
//
// The index of the context in the datapath's array.
// The index of ideal processor for this datapath.
//
uint16_t Index;
uint16_t IdealProcessor;
#if DEBUG
uint8_t Uninitialized : 1;
@ -515,6 +515,21 @@ CxPlatDataPathDatagramToInternalDatagramContext(
(((PUCHAR)Datagram) + sizeof(CXPLAT_RECV_DATA));
}
CXPLAT_DATAPATH_PROC*
CxPlatDataPathGetProc(
_In_ CXPLAT_DATAPATH* Datapath,
_In_ uint16_t Processor
)
{
for (uint16_t i = 0; i < Datapath->ProcCount; ++i) {
if (Datapath->Processors[i].IdealProcessor == Processor) {
return &Datapath->Processors[i];
}
}
CXPLAT_FRE_ASSERT(FALSE); // TODO - What now?!
return NULL;
}
QUIC_STATUS
CxPlatSocketStartReceive(
_In_ CXPLAT_SOCKET_PROC* SocketProc
@ -769,33 +784,26 @@ CxPlatDataPathInitialize(
_In_ uint32_t ClientRecvContextLength,
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
_In_opt_ CXPLAT_DATAPATH_CONFIG* Config,
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
_Out_ CXPLAT_DATAPATH** NewDataPath
)
{
int WsaError;
QUIC_STATUS Status;
WSADATA WsaData;
CXPLAT_DATAPATH* Datapath;
const uint16_t* ProcessorList;
uint32_t ProcessorCount;
uint32_t DatapathLength;
UNREFERENCED_PARAMETER(Config);
uint32_t MaxProcCount = CxPlatProcActiveCount();
CXPLAT_DBG_ASSERT(MaxProcCount <= UINT16_MAX - 1);
if (MaxProcCount >= UINT16_MAX) {
MaxProcCount = UINT16_MAX - 1;
}
CXPLAT_DATAPATH* Datapath = NULL;
BOOLEAN WsaInitialized = FALSE;
if (NewDataPath == NULL) {
Status = QUIC_STATUS_INVALID_PARAMETER;
Datapath = NULL;
goto Exit;
}
if (UdpCallbacks != NULL) {
if (UdpCallbacks->Receive == NULL || UdpCallbacks->Unreachable == NULL) {
Status = QUIC_STATUS_INVALID_PARAMETER;
Datapath = NULL;
goto Exit;
}
}
@ -805,11 +813,15 @@ CxPlatDataPathInitialize(
TcpCallbacks->Receive == NULL ||
TcpCallbacks->SendComplete == NULL) {
Status = QUIC_STATUS_INVALID_PARAMETER;
Datapath = NULL;
goto Exit;
}
}
if (!CxPlatWorkersLazyStart(Config)) {
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Exit;
}
if ((WsaError = WSAStartup(MAKEWORD(2, 2), &WsaData)) != 0) {
QuicTraceEvent(
LibraryErrorStatus,
@ -817,13 +829,21 @@ CxPlatDataPathInitialize(
WsaError,
"WSAStartup");
Status = HRESULT_FROM_WIN32(WsaError);
Datapath = NULL;
goto Exit;
}
WsaInitialized = TRUE;
if (Config && Config->ProcessorCount) {
ProcessorCount = Config->ProcessorCount;
ProcessorList = Config->ProcessorList;
} else {
ProcessorCount = CxPlatProcMaxCount();
ProcessorList = NULL;
}
DatapathLength =
sizeof(CXPLAT_DATAPATH) +
MaxProcCount * sizeof(CXPLAT_DATAPATH_PROC);
ProcessorCount * sizeof(CXPLAT_DATAPATH_PROC);
Datapath = (CXPLAT_DATAPATH*)CXPLAT_ALLOC_PAGED(DatapathLength, QUIC_POOL_DATAPATH);
if (Datapath == NULL) {
@ -843,7 +863,7 @@ CxPlatDataPathInitialize(
if (TcpCallbacks) {
Datapath->TcpHandlers = *TcpCallbacks;
}
Datapath->ProcCount = (uint16_t)MaxProcCount;
Datapath->ProcCount = (uint16_t)ProcessorCount;
CxPlatRefInitializeEx(&Datapath->RefCount, Datapath->ProcCount);
CxPlatDataPathQueryRssScalabilityInfo(Datapath);
@ -908,8 +928,10 @@ CxPlatDataPathInitialize(
for (uint16_t i = 0; i < Datapath->ProcCount; i++) {
Datapath->Processors[i].Datapath = Datapath;
Datapath->Processors[i].EventQ = CxPlatWorkerGetEventQ(i);
Datapath->Processors[i].Index = i;
Datapath->Processors[i].IdealProcessor =
ProcessorList ? ProcessorList[i] : (uint16_t)i;
Datapath->Processors[i].EventQ =
CxPlatWorkerGetEventQ(Datapath->Processors[i].IdealProcessor);
CxPlatRefInitialize(&Datapath->Processors[i].RefCount);
CxPlatPoolInitialize(
@ -947,7 +969,9 @@ Error:
if (Datapath != NULL) {
CXPLAT_FREE(Datapath, QUIC_POOL_DATAPATH);
}
(void)WSACleanup();
if (WsaInitialized) {
(void)WSACleanup();
}
}
Exit:
@ -1689,7 +1713,8 @@ CxPlatSocketCreateUdp(
QUIC_DISABLED_BY_FUZZER_START;
SocketProc->DatapathProc = &Datapath->Processors[AffinitizedProcessor];
SocketProc->DatapathProc =
CxPlatDataPathGetProc(Datapath, AffinitizedProcessor);
CxPlatRefIncrement(&SocketProc->DatapathProc->RefCount);
if (*SocketProc->DatapathProc->EventQ !=
@ -2044,7 +2069,8 @@ CxPlatSocketCreateTcpInternal(
if (Type != CXPLAT_SOCKET_TCP_SERVER) {
SocketProc->DatapathProc = &Datapath->Processors[AffinitizedProcessor];
SocketProc->DatapathProc =
CxPlatDataPathGetProc(Datapath, AffinitizedProcessor);
CxPlatRefIncrement(&SocketProc->DatapathProc->RefCount);
if (*SocketProc->DatapathProc->EventQ !=
@ -2781,7 +2807,7 @@ CxPlatDataPathAcceptComplete(
}
AcceptSocketProc->DatapathProc =
&ListenerSocketProc->Parent->Datapath->Processors[AffinitizedProcessor];
CxPlatDataPathGetProc(ListenerSocketProc->Parent->Datapath, AffinitizedProcessor);
CxPlatRefIncrement(&AcceptSocketProc->DatapathProc->RefCount);
if (*AcceptSocketProc->DatapathProc->EventQ !=
@ -3190,7 +3216,7 @@ CxPlatDataPathUdpRecvComplete(
Datagram->Buffer = RecvPayload;
Datagram->BufferLength = MessageLength;
Datagram->Route = &RecvContext->Route;
Datagram->PartitionIndex = SocketProc->DatapathProc->Index;
Datagram->PartitionIndex = SocketProc->DatapathProc->IdealProcessor;
Datagram->TypeOfService = (uint8_t)ECN;
Datagram->Allocated = TRUE;
Datagram->QueuedOnConnection = FALSE;
@ -3350,7 +3376,7 @@ CxPlatDataPathTcpRecvComplete(
Data->Buffer = ((PUCHAR)RecvContext) + Datapath->RecvPayloadOffset;
Data->BufferLength = NumberOfBytesTransferred;
Data->Route = &RecvContext->Route;
Data->PartitionIndex = SocketProc->DatapathProc->Index;
Data->PartitionIndex = SocketProc->DatapathProc->IdealProcessor;
Data->TypeOfService = 0;
Data->Allocated = TRUE;
Data->QueuedOnConnection = FALSE;
@ -3492,7 +3518,7 @@ CxPlatSendDataAlloc(
CXPLAT_DBG_ASSERT(Socket != NULL);
CXPLAT_DATAPATH_PROC* DatapathProc =
&Socket->Datapath->Processors[GetCurrentProcessorNumber()];
CxPlatDataPathGetProc(Socket->Datapath, (uint16_t)GetCurrentProcessorNumber());
CXPLAT_SEND_DATA* SendData =
CxPlatPoolAlloc(&DatapathProc->SendDataPool);
@ -3950,8 +3976,19 @@ CxPlatSocketSend(
SendData != NULL);
CXPLAT_DATAPATH* Datapath = Socket->Datapath;
CXPLAT_SOCKET_PROC* SocketProc =
&Socket->Processors[Socket->HasFixedRemoteAddress ? 0 : IdealProcessor % Datapath->ProcCount];
CXPLAT_SOCKET_PROC* SocketProc;
if (Socket->HasFixedRemoteAddress) {
SocketProc = &Socket->Processors[0];
} else {
SocketProc = NULL;
for (uint16_t i = 0; i < Datapath->ProcCount; i++) {
if (Socket->Processors[i].DatapathProc->IdealProcessor == IdealProcessor) {
SocketProc = &Socket->Processors[i];
break;
}
}
CXPLAT_FRE_ASSERT(SocketProc != NULL);
}
CxPlatSendDataFinalizeSendBuffer(SendData);

Просмотреть файл

@ -212,7 +212,7 @@ CxPlatCryptUninitialize(
// Platform Worker APIs
//
BOOLEAN
void
CxPlatWorkersInit(
void
);
@ -222,6 +222,11 @@ CxPlatWorkersUninit(
void
);
BOOLEAN
CxPlatWorkersLazyStart(
_In_opt_ QUIC_EXECUTION_CONFIG* Config
);
CXPLAT_EVENTQ*
CxPlatWorkerGetEventQ(
_In_ uint16_t IdealProcessor

Просмотреть файл

@ -201,42 +201,26 @@ CxPlatInitialize(
void
)
{
QUIC_STATUS Status;
RandomFd = open("/dev/urandom", O_RDONLY|O_CLOEXEC);
if (RandomFd == -1) {
Status = (QUIC_STATUS)errno;
QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Status,
errno,
"open(/dev/urandom, O_RDONLY|O_CLOEXEC) failed");
goto Exit;
return (QUIC_STATUS)errno;
}
if (!CxPlatWorkersInit()) {
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Exit;
}
CxPlatWorkersInit();
CxPlatTotalMemory = CGroupGetMemoryLimit();
Status = QUIC_STATUS_SUCCESS;
QuicTraceLogInfo(
PosixInitialized,
"[ dso] Initialized (AvailMem = %llu bytes)",
CxPlatTotalMemory);
Exit:
if (QUIC_FAILED(Status)) {
if (RandomFd != -1) {
close(RandomFd);
}
}
return Status;
return QUIC_STATUS_SUCCESS;
}
void

Просмотреть файл

@ -374,10 +374,7 @@ CxPlatInitialize(
}
CryptoInitialized = TRUE;
if (!CxPlatWorkersInit()) {
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Error;
}
CxPlatWorkersInit();
#ifdef TIMERR_NOERROR
QuicTraceLogInfo(

Просмотреть файл

@ -15,25 +15,11 @@ Abstract:
#include "platform_worker.c.clog.h"
#endif
CXPLAT_RUNDOWN_REF CxPlatWorkerRundown;
const uint32_t WorkerWakeEventPayload = CXPLAT_CQE_TYPE_WORKER_WAKE;
const uint32_t WorkerUpdatePollEventPayload = CXPLAT_CQE_TYPE_WORKER_UPDATE_POLL;
typedef struct QUIC_CACHEALIGN CXPLAT_WORKER {
//
// Flags to indicate what has been initialized.
//
BOOLEAN InitializedEventQ : 1;
#ifdef CXPLAT_SQE_INIT
BOOLEAN InitializedShutdownSqe : 1;
BOOLEAN InitializedWakeSqe : 1;
BOOLEAN InitializedUpdatePollSqe : 1;
#endif
BOOLEAN InitializedThread : 1;
BOOLEAN InitializedECLock : 1;
//
// Thread used to drive the worker.
//
@ -76,41 +62,65 @@ typedef struct QUIC_CACHEALIGN CXPLAT_WORKER {
//
CXPLAT_SLIST_ENTRY* ExecutionContexts;
//
// The ideal processor for the worker thread.
//
uint16_t IdealProcessor;
//
// Flags to indicate what has been initialized.
//
BOOLEAN InitializedEventQ : 1;
#ifdef CXPLAT_SQE_INIT
BOOLEAN InitializedShutdownSqe : 1;
BOOLEAN InitializedWakeSqe : 1;
BOOLEAN InitializedUpdatePollSqe : 1;
#endif
BOOLEAN InitializedThread : 1;
BOOLEAN InitializedECLock : 1;
} CXPLAT_WORKER;
CXPLAT_LOCK CxPlatWorkerLock;
CXPLAT_RUNDOWN_REF CxPlatWorkerRundown;
uint32_t CxPlatWorkerCount;
CXPLAT_WORKER* CxPlatWorkers;
CXPLAT_THREAD_CALLBACK(CxPlatWorkerThread, Context);
void
CxPlatWorkerWake(
_In_ CXPLAT_WORKER* Worker
CxPlatWorkersInit(
void
)
{
CxPlatEventQEnqueue(&Worker->EventQ, &Worker->WakeSqe, (void*)&WorkerWakeEventPayload);
}
CXPLAT_EVENTQ*
CxPlatWorkerGetEventQ(
_In_ uint16_t IdealProcessor
)
{
return &CxPlatWorkers[IdealProcessor % CxPlatWorkerCount].EventQ;
CxPlatLockInitialize(&CxPlatWorkerLock);
}
#pragma warning(push)
#pragma warning(disable:6385)
#pragma warning(disable:6386) // SAL is confused about the worker size
BOOLEAN
CxPlatWorkersInit(
void
CxPlatWorkersLazyStart(
_In_opt_ QUIC_EXECUTION_CONFIG* Config
)
{
CxPlatWorkerCount = CxPlatProcActiveCount(); // TODO - use max instead?
CxPlatLockAcquire(&CxPlatWorkerLock);
if (CxPlatWorkers != NULL) {
CxPlatLockRelease(&CxPlatWorkerLock);
return TRUE;
}
const uint16_t* ProcessorList;
UNREFERENCED_PARAMETER(Config); // TODO - use config
/*if (Config && Config->ProcessorCount) {
CxPlatWorkerCount = Config->ProcessorCount;
ProcessorList = Config->ProcessorList;
} else {*/
CxPlatWorkerCount = CxPlatProcMaxCount();
ProcessorList = NULL;
//}
CXPLAT_DBG_ASSERT(CxPlatWorkerCount > 0 && CxPlatWorkerCount <= UINT16_MAX);
const size_t WorkersSize = sizeof(CXPLAT_WORKER) * CxPlatWorkerCount;
CxPlatWorkers = (CXPLAT_WORKER*)CXPLAT_ALLOC_PAGED(WorkersSize, QUIC_POOL_PLATFORM_WORKER);
if (CxPlatWorkers == NULL) {
QuicTraceEvent(
@ -118,7 +128,8 @@ CxPlatWorkersInit(
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_WORKER",
WorkersSize);
return FALSE;
CxPlatWorkerCount = 0;
goto Error;
}
CXPLAT_THREAD_CONFIG ThreadConfig = {
@ -133,7 +144,9 @@ CxPlatWorkersInit(
for (uint32_t i = 0; i < CxPlatWorkerCount; ++i) {
CxPlatLockInitialize(&CxPlatWorkers[i].ECLock);
CxPlatWorkers[i].InitializedECLock = TRUE;
ThreadConfig.IdealProcessor = (uint16_t)i;
CxPlatWorkers[i].IdealProcessor = ProcessorList ? ProcessorList[i] : (uint16_t)i;
CXPLAT_DBG_ASSERT(CxPlatWorkers[i].IdealProcessor < CxPlatProcMaxCount());
ThreadConfig.IdealProcessor = CxPlatWorkers[i].IdealProcessor;
ThreadConfig.Context = &CxPlatWorkers[i];
if (!CxPlatEventQInitialize(&CxPlatWorkers[i].EventQ)) {
QuicTraceEvent(
@ -181,37 +194,42 @@ CxPlatWorkersInit(
CxPlatRundownInitialize(&CxPlatWorkerRundown);
CxPlatLockRelease(&CxPlatWorkerLock);
return TRUE;
Error:
for (uint32_t i = 0; i < CxPlatWorkerCount; ++i) {
if (CxPlatWorkers[i].InitializedThread) {
CxPlatThreadWait(&CxPlatWorkers[i].Thread);
CxPlatThreadDelete(&CxPlatWorkers[i].Thread);
}
if (CxPlatWorkers) {
for (uint32_t i = 0; i < CxPlatWorkerCount; ++i) {
if (CxPlatWorkers[i].InitializedThread) {
CxPlatThreadWait(&CxPlatWorkers[i].Thread);
CxPlatThreadDelete(&CxPlatWorkers[i].Thread);
}
#ifdef CXPLAT_SQE_INIT
if (CxPlatWorkers[i].InitializedUpdatePollSqe) {
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].UpdatePollSqe);
}
if (CxPlatWorkers[i].InitializedWakeSqe) {
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].WakeSqe);
}
if (CxPlatWorkers[i].InitializedShutdownSqe) {
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].ShutdownSqe);
}
if (CxPlatWorkers[i].InitializedUpdatePollSqe) {
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].UpdatePollSqe);
}
if (CxPlatWorkers[i].InitializedWakeSqe) {
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].WakeSqe);
}
if (CxPlatWorkers[i].InitializedShutdownSqe) {
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].ShutdownSqe);
}
#endif // CXPLAT_SQE_INIT
if (CxPlatWorkers[i].InitializedEventQ) {
CxPlatEventQCleanup(&CxPlatWorkers[i].EventQ);
}
if (CxPlatWorkers[i].InitializedECLock) {
CxPlatLockUninitialize(&CxPlatWorkers[i].ECLock);
if (CxPlatWorkers[i].InitializedEventQ) {
CxPlatEventQCleanup(&CxPlatWorkers[i].EventQ);
}
if (CxPlatWorkers[i].InitializedECLock) {
CxPlatLockUninitialize(&CxPlatWorkers[i].ECLock);
}
}
CXPLAT_FREE(CxPlatWorkers, QUIC_POOL_PLATFORM_WORKER);
CxPlatWorkers = NULL;
}
CXPLAT_FREE(CxPlatWorkers, QUIC_POOL_PLATFORM_WORKER);
CxPlatWorkers = NULL;
CxPlatLockRelease(&CxPlatWorkerLock);
return FALSE;
}
#pragma warning(pop)
@ -221,28 +239,46 @@ CxPlatWorkersUninit(
void
)
{
CxPlatRundownReleaseAndWait(&CxPlatWorkerRundown);
if (CxPlatWorkers != NULL) {
CxPlatRundownReleaseAndWait(&CxPlatWorkerRundown);
for (uint32_t i = 0; i < CxPlatWorkerCount; ++i) {
CxPlatEventQEnqueue(
&CxPlatWorkers[i].EventQ,
&CxPlatWorkers[i].ShutdownSqe,
NULL);
CxPlatThreadWait(&CxPlatWorkers[i].Thread);
CxPlatThreadDelete(&CxPlatWorkers[i].Thread);
for (uint32_t i = 0; i < CxPlatWorkerCount; ++i) {
CxPlatEventQEnqueue(
&CxPlatWorkers[i].EventQ,
&CxPlatWorkers[i].ShutdownSqe,
NULL);
CxPlatThreadWait(&CxPlatWorkers[i].Thread);
CxPlatThreadDelete(&CxPlatWorkers[i].Thread);
#ifdef CXPLAT_SQE_INIT
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].UpdatePollSqe);
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].WakeSqe);
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].ShutdownSqe);
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].UpdatePollSqe);
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].WakeSqe);
CxPlatSqeCleanup(&CxPlatWorkers[i].EventQ, &CxPlatWorkers[i].ShutdownSqe);
#endif // CXPLAT_SQE_INIT
CxPlatEventQCleanup(&CxPlatWorkers[i].EventQ);
CxPlatLockUninitialize(&CxPlatWorkers[i].ECLock);
CxPlatEventQCleanup(&CxPlatWorkers[i].EventQ);
CxPlatLockUninitialize(&CxPlatWorkers[i].ECLock);
}
CXPLAT_FREE(CxPlatWorkers, QUIC_POOL_PLATFORM_WORKER);
CxPlatWorkers = NULL;
CxPlatRundownUninitialize(&CxPlatWorkerRundown);
}
CXPLAT_FREE(CxPlatWorkers, QUIC_POOL_PLATFORM_WORKER);
CxPlatWorkers = NULL;
CxPlatLockUninitialize(&CxPlatWorkerLock);
}
CxPlatRundownUninitialize(&CxPlatWorkerRundown);
CXPLAT_EVENTQ*
CxPlatWorkerGetEventQ(
_In_ uint16_t IdealProcessor
)
{
for (uint32_t i = 0; i < CxPlatWorkerCount; ++i) {
if (CxPlatWorkers[i].IdealProcessor == IdealProcessor) {
return &CxPlatWorkers[i].EventQ;
}
}
CXPLAT_FRE_ASSERT(FALSE);
return NULL;
}
void
@ -251,12 +287,21 @@ CxPlatAddExecutionContext(
_In_ uint16_t IdealProcessor
)
{
CXPLAT_WORKER* Worker = &CxPlatWorkers[IdealProcessor % CxPlatWorkerCount];
CXPLAT_WORKER* Worker = NULL;
for (uint32_t i = 0; i < CxPlatWorkerCount; ++i) {
if (CxPlatWorkers[i].IdealProcessor == IdealProcessor) {
Worker = &CxPlatWorkers[i];
break;
}
}
CXPLAT_FRE_ASSERT(Worker != NULL);
Context->CxPlatContext = Worker;
CxPlatLockAcquire(&Worker->ECLock);
Context->Entry.Next = Worker->PendingECs;
Worker->PendingECs = &Context->Entry;
CxPlatLockRelease(&Worker->ECLock);
CxPlatEventQEnqueue(
&Worker->EventQ,
&Worker->UpdatePollSqe,
@ -268,7 +313,8 @@ CxPlatWakeExecutionContext(
_In_ CXPLAT_EXECUTION_CONTEXT* Context
)
{
CxPlatWorkerWake((CXPLAT_WORKER*)Context->CxPlatContext);
CXPLAT_WORKER* Worker = (CXPLAT_WORKER*)Context->CxPlatContext;
CxPlatEventQEnqueue(&Worker->EventQ, &Worker->WakeSqe, (void*)&WorkerWakeEventPayload);
}
void

Просмотреть файл

@ -61,6 +61,8 @@ namespace QuicTrace.DataModel
RegistrationError,
RegistrationErrorStatus,
RegistrationShutdown,
RegistrationCreatedV2,
RegistrationRundownV2,
WorkerCreated = 2048,
WorkerStart,

Просмотреть файл

@ -2112,17 +2112,17 @@ void QuicTestStatefulGlobalSetParam()
}
//
// Set QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS when MsQuicLib.Datapath != NULL
// Set QUIC_PARAM_GLOBAL_EXECUTION_CONFIG when MsQuicLib.Datapath != NULL
//
{
TestScopeLogger LogScope1("Set QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS when MsQuicLib.Datapath != NULL");
GlobalSettingScope ParamScope(QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS);
uint16_t Data[4] = {};
TestScopeLogger LogScope1("Set QUIC_PARAM_GLOBAL_EXECUTION_CONFIG when MsQuicLib.Datapath != NULL");
GlobalSettingScope ParamScope(QUIC_PARAM_GLOBAL_EXECUTION_CONFIG);
uint16_t Data[QUIC_EXECUTION_CONFIG_MIN_SIZE] = {};
TEST_QUIC_STATUS(
QUIC_STATUS_INVALID_STATE,
MsQuic->SetParam(
nullptr,
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
sizeof(Data),
&Data));
}
@ -2443,42 +2443,12 @@ void QuicTestGlobalParam()
}
//
// QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS
// QUIC_PARAM_GLOBAL_EXECUTION_CONFIG
//
{
TestScopeLogger LogScope0("QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS");
TestScopeLogger LogScope0("QUIC_PARAM_GLOBAL_EXECUTION_CONFIG");
{
GlobalSettingScope ParamScope1(QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS);
//
// BufferLength is not divisible by sizeof(uint16_t)
//
{
TestScopeLogger LogScope2("BufferLength is not divisible by sizeof(uint16_t)");
uint16_t Data[4];
TEST_QUIC_STATUS(
QUIC_STATUS_INVALID_PARAMETER,
MsQuic->SetParam(
nullptr,
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
sizeof(Data) + 1,
&Data));
}
//
// one of data is bigger than the number of its platform cpus
//
{
TestScopeLogger LogScope2("one of data is bigger than the number of its platform cpus");
uint16_t Data[4] = {};
Data[0] = UINT16_MAX;
TEST_QUIC_STATUS(
QUIC_STATUS_INVALID_PARAMETER,
MsQuic->SetParam(
nullptr,
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
sizeof(Data),
&Data));
}
GlobalSettingScope ParamScope1(QUIC_PARAM_GLOBAL_EXECUTION_CONFIG);
//
// Good without data
@ -2488,12 +2458,23 @@ void QuicTestGlobalParam()
TEST_QUIC_SUCCEEDED(
MsQuic->SetParam(
nullptr,
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
0,
nullptr));
}
uint16_t Data[4] = {};
uint8_t Data[QUIC_EXECUTION_CONFIG_MIN_SIZE + sizeof(uint16_t) * 4] = {};
uint32_t DataLength = sizeof(Data);
QUIC_EXECUTION_CONFIG* Config = (QUIC_EXECUTION_CONFIG*)Data;
Config->ProcessorCount = 4;
if (CxPlatProcMaxCount() < Config->ProcessorCount) {
Config->ProcessorCount = CxPlatProcMaxCount();
DataLength = QUIC_EXECUTION_CONFIG_MIN_SIZE + sizeof(uint16_t) * Config->ProcessorCount;
}
for (uint16_t i = 0; i < (uint16_t)Config->ProcessorCount; ++i) {
Config->ProcessorList[i] = i;
}
//
// Good with data
//
@ -2502,15 +2483,15 @@ void QuicTestGlobalParam()
TEST_QUIC_SUCCEEDED(
MsQuic->SetParam(
nullptr,
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
sizeof(Data),
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
DataLength,
&Data));
}
//
// Good GetParam with data
//
SimpleGetParamTest(nullptr, QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS, sizeof(uint16_t) * 4, Data);
SimpleGetParamTest(nullptr, QUIC_PARAM_GLOBAL_EXECUTION_CONFIG, DataLength, Data);
}
//
@ -2520,7 +2501,7 @@ void QuicTestGlobalParam()
TEST_QUIC_SUCCEEDED(
MsQuic->GetParam(
nullptr,
QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS,
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
&BufferLength,
nullptr));
}

Просмотреть файл

@ -365,7 +365,7 @@ QuicTestConnectAndPing(
//
}
MsQuicRegistration Registration(true);
MsQuicRegistration Registration(NULL, QUIC_EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT, true);
TEST_TRUE(Registration.IsValid());
MsQuicAlpn Alpn("MsQuicTest");

Просмотреть файл

@ -154,11 +154,15 @@ void SimpleGetParamTest(HQUIC Handle, uint32_t Param, size_t ExpectedLength, voi
Param,
&Length,
nullptr));
TEST_EQUAL(ExpectedLength, Length);
if (ExpectedLength != Length) {
TEST_FAILURE("ExpectedLength (%u) != Length (%u)", ExpectedLength, Length);
return;
}
void* Value = CXPLAT_ALLOC_NONPAGED(Length, QUIC_POOL_TEST);
if (Value == nullptr) {
TEST_FAILURE("Out of memory for testing SetParam for global parameter");
return;
}
TEST_QUIC_SUCCEEDED(
MsQuic->GetParam(
@ -193,7 +197,7 @@ struct GlobalSettingScope {
&BufferLength,
nullptr);
TEST_TRUE(Status == QUIC_STATUS_BUFFER_TOO_SMALL ||
(Parameter == QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS && Status == QUIC_STATUS_SUCCESS));
(Parameter == QUIC_PARAM_GLOBAL_EXECUTION_CONFIG && Status == QUIC_STATUS_SUCCESS));
OriginalValue = CXPLAT_ALLOC_NONPAGED(BufferLength, QUIC_POOL_TEST);
if (OriginalValue == nullptr) {

Просмотреть файл

@ -144,6 +144,9 @@ typedef enum QUIC_EVENT_ID_REGISTRATION {
EventId_QuicRegistrationRundown,
EventId_QuicRegistrationError,
EventId_QuicRegistrationErrorStatus,
EventId_QuicRegistrationShutdown,
EventId_QuicRegistrationCreatedV2,
EventId_QuicRegistrationRundownV2,
EventId_QuicRegistrationCount
} QUIC_EVENT_ID_REGISTRATION;