Mit Onload arbeiten
Auf dieser Seite wird beschrieben, wie Sie Onload mit U4 Compute Engine-Instanzen verwenden.
Über Onload
Onload ist ein leistungsstarker Netzwerk stack für latenzempfindliche Anwendungen, die eine extrem niedrige Latenz, minimalen Jitter und eine konsistente Leistung erfordern. Onload bietet eine TCP/IP-Implementierung, die den Betriebssystemkernel umgeht und direkt im Userspace ausgeführt wird, während Anwendungen Standard-BSD-Socket-APIs verwenden können.
Die Verwendung von Onload mit der ULL-Lösung umfasst die Unterstützung für Folgendes:
- Flow Steering: Sie können das standardmäßige Receive Side Scaling (RSS)-Hashing umgehen, indem Sie bestimmte Traffic-Flows direkt an eine bestimmte Empfangswarteschlange (Receive Queue, RX) weiterleiten. Es wird 3-Tupel-Flow Steering unterstützt (Protokoll, Ziel-IP-Adresse, Zielport).
Hinweis
Bevor Sie Onload auf U4 Compute Engine-Instanzen verwenden, müssen die folgenden Voraussetzungen erfüllt sein.
U4-Instanz erstellen
Wenn Sie noch keine U4 Compute Engine-Instanz erstellt haben, verwenden Sie eine der folgenden Methoden, die die erforderliche Konfiguration für Onload enthalten:
- Informationen zum Erstellen einer U4P- oder U4C-Bare-Metal-Instanz finden Sie unter ULL Compute Engine-Instanzen erstellen.
- Informationen zum Erstellen einer U4S-VM-Instanz (Virtual Machine) finden Sie unter Nicht-ULL Compute Engine-Instanzen für Hilfsarbeitslasten erstellen.
Mit SSH eine Verbindung zur Instanz herstellen
Wenn Sie noch keine Verbindung zu Ihrer Instanz hergestellt haben, stellen Sie jetzt eine Verbindung her mit SSH.
Zum Root-Nutzer wechseln
Die Befehle und Skripts in den folgenden Schritten ändern Einstellungen auf Systemebene, Kernelparameter und Netzwerkschnittstellen. Damit sie erfolgreich ausgeführt werden können, müssen Sie sie als Root-Nutzer ausführen. Sie können zu einer Root-Shell wechseln, indem Sie
sudo suausführen, oder bei Bedarf sudovor Befehle setzen.
Onload einrichten
In diesem Abschnitt werden die Schritte beschrieben, die zum Einrichten von Onload auf einer U4-Instanz erforderlich sind.
Abhängigkeiten installieren
Wenn Sie Rocky Linux verwenden, aktivieren Sie das CodeReady Builder-Repository (CRB). Wenn Sie Red Hat Enterprise Linux (RHEL) verwenden, überspringen Sie diesen Schritt.
dnf -y config-manager --enable crb
Installieren Sie die erforderlichen Abhängigkeiten für Onload:
dnf -y install git clang \ python3-setuptools \ linuxptp \ libcap-devel libbpf-devel libxdp-devel
Onload-Quelle abrufen
Führen Sie die folgenden Befehle aus, um das onload-Repository
mit den erforderlichen Änderungen abzurufen:
umask 0022 mkdir -p /usr/src/ git clone https://github.com/Xilinx-CNS/onload /usr/src/onload # 9.2.0.43 / 9.2.1, origin/v9_2 as of May 18, 2026 git -C /usr/src/onload checkout origin/v9_2 # Pull Google-specific Onload changes not yet merged as of v9_2 curl -L https://github.com/Xilinx-CNS/onload/pull/279.patch | git -C /usr/src/onload am -3 curl -L https://github.com/Xilinx-CNS/onload/pull/282.patch | git -C /usr/src/onload am -3 curl -L https://github.com/Xilinx-CNS/onload/pull/325.patch | git -C /usr/src/onload am -3 curl -L https://github.com/Xilinx-CNS/onload/pull/327.patch | git -C /usr/src/onload am -3
Onload erstellen
Führen Sie die folgenden Befehle aus, um Onload zu erstellen:
cd /usr/src/onload USEONLOADEXT=1 ./scripts/onload_install --no-sfc pushd ./src/tools/bpf_link_helper clang xdp_onload_prepare.c -lbpf -o xdp_onload_prepare clang -target bpf -O2 -g -c xdp_tstamp.c -o ./xdp_tstamp.o popd
IBT (Indirect Branch Tracking) deaktivieren
IBT muss deaktiviert sein, um Onload wie unter Inkompatibilität mit IBT (Indirect Branch Tracking) beschrieben zu verwenden.
Führen Sie die folgenden Befehle aus, um IBT zu deaktivieren:
grubby --args="ibt=off" --update-kernel=ALL reboot
Onload laden
In diesem Abschnitt wird beschrieben, wie Sie Onload auf Ihre Instanz laden.
Onload auf eine U4P- oder U4C-Instanz laden
Verwenden Sie das folgende Skript, um Onload auf eine U4P- oder U4C-Bare-Metal-Instanz zu laden.
IFNAMES=($( find /sys/class/net -type l -not -lname '*virtual*' -printf '%l %f\n' | sort | awk '{print $2}')) for IFNAME in "${IFNAMES[@]}"; do ethtool -L "${IFNAME}" rx 16 tx 16 ethtool -G "${IFNAME}" rx 1024 rx-buf-len 2048 ethtool -K "${IFNAME}" ntuple on echo 0 > "/sys/class/net/${IFNAME}/threaded" /usr/src/onload/src/tools/bpf_link_helper/xdp_onload_prepare \ "${IFNAME}" /usr/src/onload/src/tools/bpf_link_helper/xdp_tstamp.o done setenforce 0 numactl --cpunodebind=0,2 onload_tool reload --onload-only for IFNAME in "${IFNAMES[@]}"; do echo "${IFNAME}" 16 > /sys/module/sfc_resource/afxdp/register until [[ $(cat "/sys/class/net/${IFNAME}/carrier") == 1 ]]; do sleep 1 done hwstamp_ctl -i "${IFNAME}" -r 1 done echo 1 > /sys/module/sfc_resource/parameters/enable_af_xdp_flow_filters echo 256 > /sys/module/onload/parameters/xdp_headroom echo -1 > /sys/module/onload/parameters/inject_kernel_gid
Onload auf eine U4S-Instanz laden
Verwenden Sie das folgende Skript, um Onload auf eine U4S-VM-Instanz zu laden.
IFNAME=NIC_NAME ALLOCATED_QUEUES=ALLOCATED_QUEUES ethtool -L "$IFNAME" rx "${ALLOCATED_QUEUES}" tx "${ALLOCATED_QUEUES}" ethtool -G "$IFNAME" rx 1024 rx-buf-len 2048 ethtool -K "$IFNAME" ntuple on echo 0 > "/sys/class/net/${IFNAME}/threaded" /usr/src/onload/src/tools/bpf_link_helper/xdp_onload_prepare "$IFNAME" \ /usr/src/onload/src/tools/bpf_link_helper/xdp_tstamp.o setenforce 0 numactl --cpunodebind=0 onload_tool reload --onload-only echo "${IFNAME} ${ALLOCATED_QUEUES}" | tee /sys/module/sfc_resource/afxdp/register until [[ $(cat "/sys/class/net/${IFNAME}/carrier") == 1 ]]; do sleep 1 done hwstamp_ctl -i "$IFNAME" -r 1 echo 1 > /sys/module/sfc_resource/parameters/enable_af_xdp_flow_filters echo 256 > /sys/module/onload/parameters/xdp_headroom echo -1 > /sys/module/onload/parameters/inject_kernel_gid
Ersetzen Sie Folgendes:
NIC_NAME: der Name der Netzwerkschnittstelle im Betriebssystem, z. B.enp22s0f0.ALLOCATED_QUEUES: die Anzahl der Empfangs- (RX) und Sende- (TX) Warteschlangen, die für Onload auf der Netzwerkschnittstelle zugewiesen werden sollen. Legen Sie diesen Wert auf die Hälfte der Gesamtzahl der RX- oder TX-Warteschlangen fest, die der vNIC zugewiesen sind.Bei U4S-Instanzen entspricht die Gesamtzahl der Warteschlangen (für RX- bzw. TX-Warteschlangen)
num_vcpus / num_vnics, maximal jedoch16Warteschlangen pro vNIC. Wenn die vNIC beispielsweise4TX-Warteschlangen hat, legen Sie diesen Wert auf2fest. Wenn die vNIC16TX-Warteschlangen hat, legen Sie diesen Wert auf8fest.Weitere Informationen zur Standardzuweisung von Warteschlangen finden Sie unter Empfangs- und Sendewarteschlangen.
Onload-Flags konfigurieren
Um die Leistung zu optimieren und die Latenz zu verringern, können Sie die folgenden Umgebungsvariablen und Flags verwenden, wenn Sie Ihre Anwendungen mit Onload ausführen. Dieser Abschnitt enthält empfohlene Einstellungen, die Sie bei Bedarf für Ihre Anwendungen anpassen können.
Sie müssen diese Parameter vor den Befehlen Ihrer Anwendung angeben. Wenn Sie beispielsweise eine Anwendung mit diesen Einstellungen ausführen möchten, verwenden Sie das folgende Format:
env EF_NO_FAIL=0 \ EF_POLL_USEC=100000 \ EF_RX_TIMESTAMPING=3 \ EF_MAX_ENDPOINTS=1048576 \ EF_WODA_SINGLE_INTERFACE=1 \ EF_UL_EPOLL=3 \ EF_USE_HUGE_PAGES=0 \ EF_EPOLL_CTL_HANDOFF=0 \ EF_FDS_MT_SAFE=0 \ EF_NONAGLE_INFLIGHT_MAX=-1 \ EF_RXQ_SIZE=4096 \ EF_TCP_RCVBUF_ESTABLISHED_DEFAULT=65536 \ EF_MAX_PACKETS=65536 \ EF_PREFAULT_PACKETS=65536 \ EF_EVS_PER_POLL=256 \ onload -v --profile=latency APPLICATION_COMMAND
Onload entfernen
Verwenden Sie das folgende Skript, um Onload zu entfernen.
IFNAMES=($( find /sys/class/net -type l -not -lname '*virtual*' -printf '%l %f\n' | sort | awk '{print $2}')) for IFNAME in "${IFNAMES[@]}"; do rm -f "/sys/fs/bpf/onload_xdp_xsk_${IFNAME}" done onload_tool unload --onload-only for IFNAME in "${IFNAMES[@]}"; do # (optional) Disable threaded busypolling in case it's up. See busypolling # section echo 0 > "/sys/class/net/${IFNAME}/threaded" ip link set dev "${IFNAME}" xdp off done
Einen systemd-Dienst konfigurieren, der Onload automatisch startet
Wenn Onload automatisch gestartet werden soll, wenn Ihre Instanz hochgefahren wird, können Sie es als
systemd Dienst registrieren. Erstellen Sie eine Dienstdatei mit folgender Vorlage:
[Unit] Description=ULL Solution -- Loading & instance tuning for Onload After=network-online.target After=google-guest-agent-manager.service google-guest-agent.service Before=multi-user.target Before=sshd.service [Service] Type=oneshot RemainAfterExit=yes ExecStart=START_SCRIPT_PATH ExecStartPost=OPTIMIZATION_SCRIPT_PATH ExecStop=STOP_SCRIPT_PATH [Install] WantedBy=multi-user.target
Ersetzen Sie Folgendes:
START_SCRIPT_PATH: der Pfad zum Skript, das Onload startet, z. B. eines der Skripts unter Onload laden.OPTIMIZATION_SCRIPT_PATH: der Pfad zum optionalen Skript, das Optimierungskonfigurationen anwendet. Bei Bedarf können Sie ein Skript erstellen, das Ihre Leistungsoptimierungen enthält und es hier einfügen. Andernfalls können Sie die Zeile entfernen, die diese Variable enthält.STOP_SCRIPT_PATH: der Pfad zum Skript, das Onload beendet, z. B. das Skript unter Onload entfernen.
Busy Polling konfigurieren
In diesem Abschnitt finden Sie Beispiele für die Konfiguration von Busy Polling auf Ihrer Instanz.
Beim Busy Polling wird kontinuierlich nach neuen Netzwerkpaketen gesucht, anstatt auf Geräteinterrupts zu warten. Dadurch werden Latenz und Jitter reduziert. Weitere Informationen zum Busy Polling finden Sie in der Linux-Kernel-Dokumentation unter Busy Polling.
Die RX-Warteschlange abrufen, die von einem Onload-Stack verwendet wird
So rufen Sie die RX-Warteschlange ab, die von einem Onload-Stack verwendet wird:
Rufen Sie die Onload-Stack-ID mit
onload_stackdumpab:onload_stackdump
Da die Onload-Stack-ID und die NAPI-Warteschlangen-ID nicht immer übereinstimmen, verwenden Sie das folgende Skript, um den entsprechenden Schnittstellennamen, Index und die Warteschlangen-ID aus einer Stack-ID abzurufen.
ONLOAD_STACK=ONLOAD_STACK_ID INTF_HWPORT_MAP=($(onload_stackdump "${ONLOAD_STACK}" netif_extra | grep -oP "intf_i_to_hwport=\K.*$" | tr ',' '\n')) HWPORT_IFINDEX_MAP=($(onload_stackdump "${ONLOAD_STACK}" hwport_to_base_ifindex | grep -oP "\d+$")) while read -r INTF_ID QUEUE_ID; do HW_PORT="${INTF_HWPORT_MAP[INTF_ID]}" IFINDEX="${HWPORT_IFINDEX_MAP[HW_PORT]}" IFNAME=$(ip -j link | jq -r ".[] | select(.ifindex == ${IFINDEX}) | .ifname") echo "ifname=${IFNAME} ifindex=${IFINDEX} queue_id=${QUEUE_ID}" done < <(onload_stackdump "${ONLOAD_STACK}" netif | grep -oP "((intf|vi)=)\K\d+" | xargs -n 2)
Ersetzen Sie
ONLOAD_STACK_IDdurch die ID des Stacks, für den Sie Busy Polling aktivieren oder deaktivieren möchten.Notieren Sie sich die Werte, die Sie verwenden, wenn Sie Busy Polling in den folgenden Abschnitten aktivieren oder deaktivieren.
Busy Polling für eine RX-Warteschlange aktivieren
In diesem Abschnitt finden Sie ein Beispiel dafür, wie Sie Busy Polling für eine bestimmte RX-Warteschlange aktivieren können, die von einem Onload-Stack verwendet wird.
Führen Sie das folgende Bash-Skript in Ihrem Terminal aus. Die Funktion
enable_single_queueführt folgende Schritte aus:- Ruft die
napi_idab, die einer RX-Warteschlange entspricht, indem sie Netlink (ynl) verwendet. - Legt die Eigenschaft
threaded: busy-pollfür dienapi_idfest. - Ruft die
kthread_piddes Threads ab, der dienapi_idabfragt. - Verwendet
taskset, um diekthread_pidan eine bestimmte CPU zu binden.
readonly NETDEV_YAML=${NETDEV_YAML:-"/usr/share/ynl/specs/netdev.yaml"} call_ynl() { ynl --spec "${NETDEV_YAML}" "$@" } enable_single_queue() { local -r interface="$1" local -r ifindex=$(cat "/sys/class/net/${interface}/ifindex") local -r q_id="$2" local -r cpu="$3" local napi_id napi_id=$(call_ynl --output-json --do queue-get \ --json "{\"ifindex\": ${ifindex}, \"id\": ${q_id}, \"type\": \"rx\"}" | \ jq -r '."napi-id"') if [[ -z "${napi_id}" || "${napi_id}" == "null" ]]; then echo "Error: No napi_id found for queue ${q_id} on interface ${interface}" >&2 exit 1 fi echo "Enabling busypolling for queue ${q_id} (NAPI ${napi_id}) on CPU ${cpu}" call_ynl --do napi-set --json "{\"id\": \"${napi_id}\", \"threaded\": \"busy-poll\"}" >/dev/null local napi_kthread_pid napi_kthread_pid=$(call_ynl --do napi-get --output-json \ --json "{\"id\": \"${napi_id}\"}" | jq -r '."pid" // empty') if [[ -z "${napi_kthread_pid}" ]]; then echo "Error: Could not get PID for NAPI ${napi_id}" >&2 exit 1 fi taskset -pc "${cpu}" "${napi_kthread_pid}" >/dev/null }
- Ruft die
Führen Sie den folgenden Befehl aus, um die Funktion
enable_single_queueaufzurufen:enable_single_queue NIC_NAME QUEUE_ID CPU_ID
Ersetzen Sie Folgendes:
NIC_NAME: der Name der Netzwerkschnittstelle im Betriebssystem, z. B.ens8f0.QUEUE_ID: die zuvor abgerufene Warteschlangen-ID.CPU_ID: die ID der CPU, auf der der Busy Polling-Thread ausgeführt werden soll, z. B.5.
Stellen Sie sicher, dass Sie Ereignisse zur Neuerstellung von Threads einplanen , die sich auf Ihre Busy Polling-Konfiguration auswirken können.
Ereignisse zur Neuerstellung von Threads einplanen
Wenn der Kernel einen Thread neu erstellt, bleiben die zugehörigen Threadkonfigurationen nicht erhalten, z. B. die CPU-Affinitätsmaske und die Planungsrichtlinie. Ereignisse wie die folgenden führen dazu, dass der Kernel einen Thread neu erstellt, der NAPI abfragt:
- Link-Flaps/-Resets
- XDP-Programmanhänge (z. B. beim Ausführen der Skripts zum Laden von Onload oder beim Anhängen benutzerdefinierter XDP-Programme)
- Änderungen der Ringparameter (
ethtool -G) - Änderungen der Warteschlangenzahl (
ethtool -L)
Um Probleme zu vermeiden, sollten Sie Aufgaben vermeiden, die während des normalen Betriebs Ereignisse zur Neuerstellung von Threads verursachen.
Damit Ihre Busy Polling-Konfiguration nach der Neuerstellung eines Threads erhalten bleibt, müssen Sie die neue Prozess-ID (PID) des Threads abrufen und ihn wieder an die CPU binden. Dazu können Sie die enable_single_queue
Funktion noch einmal ausführen.
Busy Polling für eine RX-Warteschlange deaktivieren
In diesem Abschnitt finden Sie ein Beispiel dafür, wie Sie Busy Polling für eine bestimmte RX-Warteschlange deaktivieren können, die von einem Onload-Stack verwendet wird.
Rufen Sie die RX-Warteschlange ab, die von einem Onload-Stack verwendet wird, indem Sie
onload_stackdumpausführen:onload_stackdump
Führen Sie das folgende Bash-Skript in Ihrem Terminal aus. Die Funktion
disable_single_queueführt folgende Schritte aus:- Ruft die
napi_idab, die einer RX-Warteschlange entspricht, indem sie Netlink (ynl) verwendet. - Setzt die Thread-Eigenschaft der
napi_idaufdisabled.
disable_single_queue() { local -r interface="$1" local -r ifindex=$(cat "/sys/class/net/${interface}/ifindex") local -r q_id="$2" local napi_id napi_id=$(call_ynl --output-json --do queue-get \ --json "{\"ifindex\": ${ifindex}, \"id\": ${q_id}, \"type\": \"rx\"}" | \ jq -r '."napi-id"') if [[ -z "${napi_id}" || "${napi_id}" == "null" ]]; then echo "Error: No napi_id found for queue ${q_id} on interface ${interface}" >&2 exit 1 fi echo "Disabling busypolling for queue ${q_id} (NAPI ${napi_id})" call_ynl --do napi-set --json "{\"id\": \"${napi_id}\", \"threaded\": \"disabled\"}" >/dev/null }
- Ruft die
Führen Sie den folgenden Befehl aus, um die Funktion
disable_single_queueaufzurufen:disable_single_queue NIC_NAME QUEUE_ID
Ersetzen Sie Folgendes:
NIC_NAME: der Name der Netzwerkschnittstelle im Betriebssystem, z. B.ens8f0.QUEUE_ID: die zuvor abgerufene Warteschlangen-ID.
Busy Polling-Status einer Warteschlange abrufen
Mit den folgenden Befehlen können Sie den NAPI-Status einer Warteschlange prüfen, um festzustellen, ob Busy Polling verwendet wird:
IFNAME=NIC_NAME QUEUE_ID=QUEUE_ID QUEUE_TYPE=QUEUE_TYPE IFINDEX=$(cat "/sys/class/net/${IFNAME}/ifindex") NAPI_ID=$(ynl --spec /usr/share/ynl/specs/netdev.yaml \ --output-json --do queue-get \ --json '{"ifindex": '${IFINDEX}', "id": '${QUEUE_ID}', "type": "'${QUEUE_TYPE}'"}' | \ jq '."napi-id"') ynl --spec /usr/share/ynl/specs/netdev.yaml \ --output-json --do napi-get \ --json '{"id": '${NAPI_ID}'}' | jq -r '"status: \(.threaded)"'
Ersetzen Sie Folgendes:
NIC_NAME: der Name der Netzwerkschnittstelle im Betriebssystem, z. B.ens8f0.QUEUE_ID: die ID der Warteschlange, die Sie prüfen möchten.QUEUE_TYPE:rxodertx.
Leistung optimieren
In diesem Abschnitt finden Sie allgemeine Anleitungen zur Optimierung der Leistung Ihrer U4-Bare-Metal-Instanzen (U4P und U4C). Passen Sie die Beispiele in dieser Anleitung nach Bedarf an Ihre Arbeitslasten an.
NUMA-Topologie für U4-Bare-Metal-Instanzen prüfen
In der folgenden Tabelle wird beschrieben, welche Netzwerkschnittstellen welche NUMA-Knoten für U4-Bare-Metal-Instanzen verwenden:
| NIC (Google Cloud Name) | NIC (Name im Betriebssystem) | NUMA-Knoten | PCIE BDF |
|---|---|---|---|
nic0 |
enp22s0f0 |
0 | 0000:16:00.0 |
nic1 |
ens8f0 |
0 | 0000:27:00.0 |
nic2 |
ens48f0 |
2 | 0000:b8:00.0 |
Die obige Tabelle enthält typische vom Betriebssystem zugewiesene Namen für Netzwerkschnittstellen für RHEL. Die tatsächlichen Namen können abweichen.
CPU-Isolierungsschema bestimmen
Für eine optimale Leistung empfehlen wir, Folgendes zu isolieren:
- Die CPUs, die von Ihrer Anwendung verwendet werden
- Die CPUs, die zum Abfragen der Onload-RX-Warteschlangen verwendet werden
- Die CPUs, die für Kernel- und Treiberinterrupts verwendet werden
Die folgende Tabelle enthält ein Beispiel dafür, wie Sie CPUs auf U4-Bare-Metal-Instanzen isolieren können. Passen Sie die Zuordnung nach Bedarf an Ihre Arbeitslasten an. Möglicherweise benötigen Sie beispielsweise mehr Anwendungs-CPUs.
| Zweck | CPUs |
|---|---|
| Allgemeine Kernelinterrupts | 0,1,30,31,60,61,90,91 |
nic0-Treiberinterrupts für Warteschlangen 0–11 |
2 |
nic1-Treiberinterrupts für Warteschlangen 0–11 |
3 |
nic0- und nic1-Treiberinterrupts für Warteschlangen 12–15 |
4 |
nic1-Busy Polling |
5-16 |
nic1-Anwendungsthreads (Onload) |
17-29 |
nic0-Busy Polling |
32-43 |
nic0-Anwendungsthreads (Onload) |
44-59 |
nic2-Treiberinterrupts für Warteschlangen 0–11 |
62 |
nic2-Treiberinterrupts für Warteschlangen 12–15 |
63 |
nic2-Busy Polling |
64-75 |
nic2-Anwendungsthreads (Onload) |
76-89 |
Abhängigkeiten für die Leistungsoptimierung installieren
Führen Sie den folgenden Befehl aus, um die erforderlichen Abhängigkeiten für die Leistungsoptimierung zu installieren:
dnf -y install numactl tuna jq
Kernel-Bootparameter konfigurieren
Führen Sie den folgenden Befehl aus, um CPUs von der Kernelplanung zu isolieren. Dadurch wird auch die Intel QuickAssist Technology (QAT) deaktiviert, damit sie nicht mit Ihren isolierten Kernen in Konflikt gerät.
Der folgende Beispielbefehl isoliert die CPUs 2-29, 32-59 und 62-89 und weist 0,1,30,31,60,61,90,91 für allgemeine Kernelinterrupts zu. Diese Werte
entsprechen dem Beispiel-CPU-Isolierungsschema. Ersetzen Sie die Werte nach Bedarf entsprechend Ihrem CPU-Isolierungsschema.
grubby --args="isolcpus=domain,managed_irq,2-29,32-59,62-89 nohz=on nohz_full=2-29,32-59,62-89 rcu_nocbs=2-29,32-59,62-89 irqaffinity=0,1,30,31,60,61,90,91 rcu_nocb_poll modprobe.blacklist=intel_qat,qat_4xxx" --update-kernel=ALL reboot
CPU-Isolierung nach dem Booten konfigurieren
Führen Sie den folgenden Befehl aus, um CPUs nach dem Booten zu isolieren. Die Werte entsprechen dem Beispiel-CPU-Isolierungsschema. Ersetzen Sie die Werte nach Bedarf entsprechend Ihrem CPU-Isolierungsschema.
tuna isolate -c 2-29,32-59,62-89
Warteschlangeninterrupts bestimmten CPUs zuweisen
In diesem Abschnitt wird beschrieben, wie Sie gve-Warteschlangeninterruptanfragen (Interrupt Requests, IRQs) an bestimmte CPUs verschieben. Der gve-Treiber wird vom Netzwerkschnittstellentyp GVNIC in Google Cloudverwendet.
Bestimmen Sie die IRQs für eine bestimmte Netzwerkschnittstelle und einen bestimmten Warteschlangenbereich. Sehen Sie sich das folgende Bash-Beispiel an, in dem eine Funktion
irq_listdefiniert wird.irq_list() { local ifname=$1 local queue_begin=$2 local queue_end=$3 pci_name=$(basename $(readlink /sys/class/net/${ifname}/device)) rx_ntfy_blk_start=$(ethtool -l "${ifname}" | awk ' /Pre-set maximums:/ { in_preset = 1 } /Current hardware settings:/ { in_preset = 0 } in_preset && $1 == "RX:" { rx = $2 } in_preset && $1 == "TX:" { tx = $2 } END { print int((rx + tx) / 2) } ') for i in $(seq "${queue_begin}" "${queue_end}"); do irq_tx="gve-ntfy-blk${i}@pci:${pci_name}" irq_rx="gve-ntfy-blk$(($i + rx_ntfy_blk_start))@pci:${pci_name}" # gve IRQ names are stored in a char[IFNAMSIZ + 16] so capped to 31 characters. echo "${irq_tx:0:31}" echo "${irq_rx:0:31}" done | paste -sd ',' }
Weisen Sie IRQs entsprechend Ihrem CPU-Isolierungsschema der entsprechenden CPU zu. Das folgende Beispielskript verwendet
tunaund die Funktionirq_listaus dem vorherigen Schritt:tuna move -c 2 -q "$(irq_list enp22s0f0 0 11)" tuna move -c 4 -q "$(irq_list enp22s0f0 12 15)" tuna move -c 3 -q "$(irq_list ens8f0 0 11)" tuna move -c 4 -q "$(irq_list ens8f0 12 15)" tuna move -c 62 -q "$(irq_list ens48f0 0 11)" tuna move -c 63 -q "$(irq_list ens48f0 12 15)"
Betriebssystem- und Geräteeinstellungen konfigurieren
Führen Sie das folgende Skript aus, um Einstellungen zu konfigurieren, die die Latenz minimieren und verhindern, dass Standardverhalten des Betriebssystems Ihre Onload-Konfigurationen beeinträchtigen.
echo 0 > /proc/sys/net/core/busy_poll echo 0 > /proc/sys/net/core/busy_read echo 0 > /proc/sys/kernel/timer_migration echo 0 > /proc/sys/net/core/rps_sock_flow_entries echo -1 > /proc/sys/kernel/sched_rt_runtime_us for IFNAME in "${IFNAMES[@]}"; do ethtool -C "${IFNAME}" rx-usecs 0 tx-usecs 0 echo 0 > "/sys/class/net/${IFNAME}/napi_defer_hard_irqs" echo 15000 > "/sys/class/net/${IFNAME}/gro_flush_timeout" done
Um Traffic von Warteschlangen wegzuleiten, die für Onload-Arbeitslasten vorgesehen sind, verwenden Sie RSS (
ethtool -X). Das folgende Beispielskript basiert auf den Werten im Beispiel-CPU-Isolierungsschema. Da Onload die Warteschlangen0-11verwendet, leitet das Skript den gesamten anderen Traffic an die Warteschlangen12-15weiter.for IFNAME in "${IFNAMES[@]}"; do ethtool -X "${IFNAME}" weight 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 done
Bekannte Probleme
Die folgenden bekannten Probleme können auftreten, wenn Sie Onload auf U4-Instanzen verwenden:
- Das Öffnen und Schließen eines Sockets kann mehrere Millisekunden dauern.
Diese Verzögerung tritt auf, weil die für AF_XDP
erforderliche Flow Steering-Konfiguration ein langsamer Prozess im Steuerpfad ist:
- Börsenbetreiber, die Listener-Sockets verwalten, können dieses Problem umgehen indem sie Patches verwenden, die Google an das Upstream-Onload-Repository gesendet hat (#335, #336). Achten Sie darauf , dass Sie diese Patches einfügen, wenn Sie die Onload-Quelle abrufen.
- Börsenteilnehmer, die ausgehende Verbindungen herstellen, benötigen die oben genannten Patches nicht. Stattdessen können sie die vorhandene
EF_TCP_SHARED_LOCAL_PORTSFunktion von Onload verwenden, um die Latenz zu verringern.
Nächste Schritte
- Informationen zum Synchronisieren der Systemuhr Ihrer Instanz mit der Uhr der physischen NIC ihres Hostservers finden Sie unter Genaue Zeit konfigurieren.