зеркало из https://github.com/microsoft/msquic.git
App Controlled Execution Config (#3034)
This commit is contained in:
Родитель
2fc5c34e18
Коммит
5b921c9e18
|
@ -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
|
||||
|
|
|
@ -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.openssl.pgd
Двоичный файл не отображается.
Двоичные данные
src/bin/winuser/pgo_x64/msquic.schannel.pgd
Двоичные данные
src/bin/winuser/pgo_x64/msquic.schannel.pgd
Двоичный файл не отображается.
Двоичные данные
src/bin/winuser/pgo_x64/msquic.schannel.sharedec.pgd
Двоичные данные
src/bin/winuser/pgo_x64/msquic.schannel.sharedec.pgd
Двоичный файл не отображается.
Двоичные данные
src/bin/winuser/pgo_x64/msquic.schannel.xdp.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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче