Enable secnetperf with xdp on azure VM (#4262)

* enable secnetperf with xdp on azure VM

* remove redundant settings

* move sudo inside script

* cleanup

* add 'sudo' in Invoke-Secnetperf

* cleanup

* Few minor fixes

* Change back

* touch ethtool only when ubuntu-22.04

* cleanup xdpgeneric and remote

* cleanup if xdp is there

* add XDP flag for execution config

* fix for DataPathTest

* remove MSQUIC_ENABLE_XDP flag

* remove Status

* remove local variable

* make FLAG_XDP visible from DataPathTest.cpp

* define preview feature

* fix RebindAddrPadded bug

* make RebindDatapathAddr to duonic dependent

* Use appropriate default values

* rollback

* fix memory leak

---------

Co-authored-by: Ubuntu <daiki@f4-ubuntu22-02.lcaeom4kylsuvmegib5mitghvd.bx.internal.cloudapp.net>
Co-authored-by: Nick Banks <nibanks@microsoft.com>
This commit is contained in:
Daiki AMINAKA 2024-05-01 16:42:02 -07:00 коммит произвёл GitHub
Родитель 596326e117
Коммит 4b08a11c99
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
15 изменённых файлов: 88 добавлений и 31 удалений

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

@ -187,7 +187,6 @@ Commands below automatically install dependencies and setup runtime environment.
```sh
pwsh ./scripts/prepare-machine.ps1 -UseXdp
pwsh ./scripts/build.ps1
export MSQUIC_ENABLE_XDP=1
```
`./scripts/prepare-machine.ps1` internally does the below commands:
@ -208,11 +207,11 @@ sudo ./scripts/duonic.sh install
Test
```sh
# "sudo" and MSQUIC_ENABLE_XDP=1 required
# "sudo" and --duoNic required
# You can explicitly specify directory of datapath_raw_xdp_kern.o by MSQUIC_XDP_OBJECT_PATH
# By default, libmsquic.so searchs for same directory as its executable
# If something failed, fallback to normal socket
sudo MSQUIC_ENABLE_XDP=1 ./artifacts/bin/linux/x64_Debug_openssl3/msquictest --duoNic
sudo ./artifacts/bin/linux/x64_Debug_openssl3/msquictest --duoNic
```
**Q&A**

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

@ -228,6 +228,26 @@ function Cleanup-State {
try { & "$Using:RemoteDir/scripts/log.ps1" -Cancel }
catch { Write-Host "Failed to stop logging on server!" }
}
} else {
# iterate all interface and "ip link set ${iface} xdp off"
if ((ip link show) -match "xdp") {
$ifaces = ip link show | grep -oP '^\d+: \K[\w@]+' | cut -d'@' -f1
foreach ($xdp in @('xdp', 'xdpgeneric')) {
foreach ($iface in $ifaces) {
sudo ip link set $iface $xdp off
}
}
}
Invoke-Command -Session $Session -ScriptBlock {
if ((ip link show) -match "xdp") {
$ifaces = ip link show | grep -oP '^\d+: \K[\w@]+' | cut -d'@' -f1
foreach ($xdp in @('xdp', 'xdpgeneric')) {
foreach ($iface in $ifaces) {
sudo ip link set $iface $xdp off
}
}
}
}
}
}
@ -428,7 +448,7 @@ function Get-LatencyOutput {
# Invokes secnetperf with the given arguments for both TCP and QUIC.
function Invoke-Secnetperf {
param ($Session, $RemoteName, $RemoteDir, $SecNetPerfPath, $LogProfile, $TestId, $ExeArgs, $io, $Filter)
param ($Session, $RemoteName, $RemoteDir, $UserName, $SecNetPerfPath, $LogProfile, $TestId, $ExeArgs, $io, $Filter)
$values = @(@(), @())
$latency = $null
@ -483,6 +503,9 @@ function Invoke-Secnetperf {
continue
}
# Linux XDP requires sudo for now
$sudo = (!$IsWindows -and $io -eq "xdp") ? "sudo -E " : ""
$artifactName = $tcp -eq 0 ? "$TestId-quic" : "$TestId-tcp"
New-Item -ItemType Directory "artifacts/logs/$artifactName" -ErrorAction Ignore | Out-Null
$artifactDir = Repo-Path "artifacts/logs/$artifactName"
@ -511,7 +534,7 @@ function Invoke-Secnetperf {
# Start the server running.
"> secnetperf $serverArgs" | Add-Content $serverOut
$job = Start-RemoteServer $Session "$RemoteDir/$SecNetPerfPath $serverArgs"
$job = Start-RemoteServer $Session "$sudo$RemoteDir/$SecNetPerfPath $serverArgs"
# Run the test multiple times, failing (for now) only if all tries fail.
# TODO: Once all failures have been fixed, consider all errors fatal.
@ -521,11 +544,14 @@ function Invoke-Secnetperf {
Write-Host "==============================`nRUN $($try+1):"
"> secnetperf $clientArgs" | Add-Content $clientOut
try {
$process = Start-LocalTest $clientPath $clientArgs $artifactDir
$process = Start-LocalTest "$sudo$clientPath" $clientArgs $artifactDir
$rawOutput = Wait-LocalTest $process $artifactDir ($io -eq "wsk") 30000
Write-Host $rawOutput
$values[$tcp] += Get-TestOutput $rawOutput $metric
if ($extraOutput) {
if ($sudo -ne "") {
sudo chown $UserName $extraOutput
}
$latency[$tcp] += Get-LatencyOutput $extraOutput
}
$rawOutput | Add-Content $clientOut

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

@ -68,7 +68,10 @@ param (
[string]$filter = "",
[Parameter(Mandatory = $false)]
[string]$RemoteName = "netperf-peer"
[string]$RemoteName = "netperf-peer",
[Parameter(Mandatory = $false)]
[string]$UserName = "secnetperf"
)
Set-StrictMode -Version "Latest"
@ -77,7 +80,11 @@ $PSDefaultParameterValues["*:ErrorAction"] = "Stop"
# Set up some important paths.
$RemoteDir = "C:/_work/quic"
if (!$isWindows) {
$RemoteDir = "/home/secnetperf/_work/quic"
if ($UserName -eq "root") {
$RemoteDir = "/$UserName/_work/quic"
} else {
$RemoteDir = "/home/$UserName/_work/quic"
}
}
$SecNetPerfDir = "artifacts/bin/$plat/$($arch)_Release_$tls"
$SecNetPerfPath = "$SecNetPerfDir/secnetperf"
@ -106,7 +113,7 @@ while ($Attempts -lt 5) {
$cred = New-Object System.Management.Automation.PSCredential ($username, $password)
$Session = New-PSSession -ComputerName $RemoteName -Credential $cred -ConfigurationName PowerShell.7
} else {
$Session = New-PSSession -HostName $RemoteName -UserName secnetperf -SSHTransport
$Session = New-PSSession -HostName $RemoteName -UserName $UserName -SSHTransport
}
break
} catch {
@ -235,19 +242,29 @@ if ($isWindows) {
Configure-DumpCollection $Session
# Install any dependent drivers.
if ($useXDP) { Install-XDP $Session $RemoteDir }
if ($useXDP -and $isWindows) { Install-XDP $Session $RemoteDir }
if ($io -eq "wsk") { Install-Kernel $Session $RemoteDir $SecNetPerfDir }
if (!$isWindows) {
# Make sure the secnetperf binary is executable.
Write-Host "Updating secnetperf permissions"
$GRO = "on"
if ($io -eq "xdp") {
$GRO = "off"
}
Invoke-Command -Session $Session -ScriptBlock {
$env:LD_LIBRARY_PATH = "${env:LD_LIBRARY_PATH}:$Using:RemoteDir/$Using:SecNetPerfDir"
chmod +x "$Using:RemoteDir/$Using:SecNetPerfPath"
if ($Using:os -eq "ubuntu-22.04") {
sudo sh -c "ethtool -K eth0 generic-receive-offload $Using:GRO"
}
}
$fullPath = Repo-Path $SecNetPerfDir
$env:LD_LIBRARY_PATH = "${env:LD_LIBRARY_PATH}:$fullPath"
chmod +x "./$SecNetPerfPath"
if ($os -eq "ubuntu-22.04") {
sudo sh -c "ethtool -K eth0 generic-receive-offload $GRO"
}
if ((Get-Content "/etc/security/limits.conf") -notcontains "root soft core unlimited") {
# Enable core dumps for the system.
@ -270,7 +287,7 @@ $regressionJson = Get-Content -Raw -Path "watermark_regression.json" | ConvertFr
Write-Host "Setup complete! Running all tests"
foreach ($testId in $allTests.Keys) {
$ExeArgs = $allTests[$testId] + " -io:$io"
$Output = Invoke-Secnetperf $Session $RemoteName $RemoteDir $SecNetPerfPath $LogProfile $testId $ExeArgs $io $filter
$Output = Invoke-Secnetperf $Session $RemoteName $RemoteDir $UserName $SecNetPerfPath $LogProfile $testId $ExeArgs $io $filter
$Test = $Output[-1]
if ($Test.HasFailures) { $hasFailures = $true }

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

@ -188,7 +188,7 @@ if (![string]::IsNullOrWhiteSpace($ExtraArtifactDir)) {
# Run the script.
if ($IsLinux -and $UseXdp) {
Invoke-Expression ('sudo MSQUIC_ENABLE_XDP=1 pwsh -c "$RunExecutable $Arguments"')
Invoke-Expression ('sudo pwsh -c "$RunExecutable $Arguments"')
} else {
Invoke-Expression ($RunExecutable + " " + $Arguments)
}

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

@ -366,7 +366,7 @@ for ($iteration = 1; $iteration -le $NumIterations; $iteration++) {
# Run the script.
foreach ($TestPath in $TestPaths) {
if ($IsLinux -and $UseXdp) {
Invoke-Expression ("sudo MSQUIC_ENABLE_XDP=1 pwsh -c " + $RunTest + " -Path $TestPath " + $TestArguments)
Invoke-Expression ("sudo pwsh -c " + $RunTest + " -Path $TestPath " + $TestArguments)
} else {
Invoke-Expression ($RunTest + " -Path $TestPath " + $TestArguments)
}

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

@ -213,6 +213,7 @@ namespace Microsoft.Quic
NONE = 0x0000,
QTIP = 0x0001,
RIO = 0x0002,
XDP = 0x0004,
}
internal unsafe partial struct QUIC_EXECUTION_CONFIG

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

@ -267,6 +267,7 @@ typedef enum QUIC_EXECUTION_CONFIG_FLAGS {
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
QUIC_EXECUTION_CONFIG_FLAG_QTIP = 0x0001,
QUIC_EXECUTION_CONFIG_FLAG_RIO = 0x0002,
QUIC_EXECUTION_CONFIG_FLAG_XDP = 0x0004,
#endif
} QUIC_EXECUTION_CONFIG_FLAGS;

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

@ -151,6 +151,11 @@ QuicMainStart(
SetConfig = true;
}
if (IoMode && IsValue(IoMode, "xdp")) {
Config->Flags |= QUIC_EXECUTION_CONFIG_FLAG_XDP;
SetConfig = true;
}
const char* CpuStr;
if ((CpuStr = GetValue(argc, argv, "cpu")) != nullptr) {
SetConfig = true;

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

@ -357,7 +357,7 @@ AttachXdpProgram(struct xdp_program *Prog, XDP_INTERFACE *Interface, struct xsk_
unsigned int xdp_flag;
} AttachTypePairs[] = {
// { XDP_MODE_HW, XDP_FLAGS_HW_MODE },
{ XDP_MODE_NATIVE, XDP_FLAGS_DRV_MODE },
// { XDP_MODE_NATIVE, XDP_FLAGS_DRV_MODE },
{ XDP_MODE_SKB, XDP_FLAGS_SKB_MODE },
};
for (uint32_t i = 0; i < ARRAYSIZE(AttachTypePairs); i++) {
@ -479,19 +479,17 @@ CxPlatDpRawInterfaceInitialize(
DetachXdpProgram(Interface, true);
struct xdp_program *Prog = NULL;
Status = OpenXdpProgram(&Prog);
Status = OpenXdpProgram(&Interface->XdpProg);
if (QUIC_FAILED(Status)) {
goto Error;
}
Status = AttachXdpProgram(Prog, Interface, XskCfg);
Status = AttachXdpProgram(Interface->XdpProg, Interface, XskCfg);
if (QUIC_FAILED(Status)) {
goto Error;
}
Interface->XdpProg = Prog;
int XskBypassMapFd = bpf_map__fd(bpf_object__find_map_by_name(xdp_program__bpf_obj(Prog), "xsks_map"));
int XskBypassMapFd = bpf_map__fd(bpf_object__find_map_by_name(xdp_program__bpf_obj(Interface->XdpProg), "xsks_map"));
if (XskBypassMapFd < 0) {
QuicTraceLogVerbose(
XdpNoXsksMap,

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

@ -45,10 +45,7 @@ CxPlatDataPathInitialize(
goto Error;
}
#if defined(CX_PLATFORM_LINUX)
char* EnableXdp = getenv("MSQUIC_ENABLE_XDP");
if (EnableXdp != NULL && EnableXdp[0] == '1') {
#endif
if (Config && Config->Flags & QUIC_EXECUTION_CONFIG_FLAG_XDP) {
Status =
RawDataPathInitialize(
ClientRecvContextLength,
@ -62,9 +59,7 @@ CxPlatDataPathInitialize(
Status = QUIC_STATUS_SUCCESS;
(*NewDataPath)->RawDataPath = NULL;
}
#if defined(CX_PLATFORM_LINUX)
}
#endif
Error:

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

@ -9,6 +9,8 @@ Abstract:
--*/
#define QUIC_API_ENABLE_PREVIEW_FEATURES 1
#include "main.h"
#include "quic_datapath.h"
@ -425,6 +427,7 @@ QuicAddr DataPathTest::UnspecIPv4;
QuicAddr DataPathTest::UnspecIPv6;
struct CxPlatDataPath {
QUIC_EXECUTION_CONFIG DefaultExecutionConfig { QUIC_EXECUTION_CONFIG_FLAG_XDP, 0, 0, {0} };
CXPLAT_DATAPATH* Datapath {nullptr};
QUIC_STATUS InitStatus;
CxPlatDataPath(
@ -439,7 +442,7 @@ struct CxPlatDataPath {
ClientRecvContextLength,
UdpCallbacks,
TcpCallbacks,
Config,
Config ? Config : &DefaultExecutionConfig,
&Datapath);
}
~CxPlatDataPath() noexcept {

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

@ -96,8 +96,13 @@ public:
MsQuic = new(std::nothrow) MsQuicApi();
ASSERT_TRUE(QUIC_SUCCEEDED(MsQuic->GetInitStatus()));
#if defined(QUIC_API_ENABLE_PREVIEW_FEATURES)
QUIC_EXECUTION_CONFIG Config = {QUIC_EXECUTION_CONFIG_FLAG_NONE, 0, 0, {0}};
if (UseQTIP) {
QUIC_EXECUTION_CONFIG Config = {QUIC_EXECUTION_CONFIG_FLAG_QTIP, 10000, 0, {0}};
Config.PollingIdleTimeoutUs = 10000;
Config.Flags |= QUIC_EXECUTION_CONFIG_FLAG_QTIP;
}
Config.Flags |= UseDuoNic ? QUIC_EXECUTION_CONFIG_FLAG_XDP : QUIC_EXECUTION_CONFIG_FLAG_NONE;
if (Config.Flags != QUIC_EXECUTION_CONFIG_FLAG_NONE) {
ASSERT_TRUE(QUIC_SUCCEEDED(
MsQuic->SetParam(
nullptr,
@ -1586,7 +1591,7 @@ TEST_P(WithFamilyArgs, RebindAddr) {
TEST_P(WithFamilyArgs, RebindDatapathAddr) {
#if defined(QUIC_API_ENABLE_PREVIEW_FEATURES)
if (UseQTIP) {
if (UseQTIP || !UseDuoNic) {
//
// NAT rebind doesn't make sense for TCP and QTIP.
//

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

@ -2582,7 +2582,7 @@ void QuicTestGlobalParam()
}
#if defined(QUIC_API_ENABLE_PREVIEW_FEATURES)
if (!UseQTIP)
if (!UseQTIP && !UseDuoNic)
#endif
{
//

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

@ -455,8 +455,11 @@ main(
UdpRecvCallback,
UdpUnreachCallback,
};
// flag
QUIC_EXECUTION_CONFIG_FLAGS Flags = QUIC_EXECUTION_CONFIG_FLAG_XDP;
Flags |= AttackType == 0 ? QUIC_EXECUTION_CONFIG_FLAG_QTIP : QUIC_EXECUTION_CONFIG_FLAG_NONE;
QUIC_EXECUTION_CONFIG DatapathFlags = {
((AttackType == 0) ? QUIC_EXECUTION_CONFIG_FLAG_QTIP : QUIC_EXECUTION_CONFIG_FLAG_NONE),
Flags,
};
CxPlatSystemLoad();
CxPlatInitialize();

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

@ -1556,7 +1556,11 @@ void start() {
printf("Using %u partitions...\n", ProcCount);
ExecConfigSize = QUIC_EXECUTION_CONFIG_MIN_SIZE + sizeof(uint16_t)*ProcCount;
ExecConfig = (QUIC_EXECUTION_CONFIG*)malloc(ExecConfigSize);
ExecConfig->Flags = QUIC_EXECUTION_CONFIG_FLAG_NONE;
if (strncmp(SpinSettings.ServerName, "192.168.1.11", 12) == 0) {
ExecConfig->Flags = QUIC_EXECUTION_CONFIG_FLAG_XDP;
} else {
ExecConfig->Flags = QUIC_EXECUTION_CONFIG_FLAG_NONE;
}
ExecConfig->PollingIdleTimeoutUs = 0; // TODO - Randomize?
ExecConfig->ProcessorCount = ProcCount;
for (uint32_t i = 0; i < ProcCount; ++i) {