Onload 작업

이 페이지에서는 U4 Compute Engine 인스턴스에서 Onload를 사용하는 방법을 설명합니다.

Onload 정보

Onload는 지연 시간에 민감한 애플리케이션을 위한 고성능 네트워크 스택으로, 매우 짧은 지연 시간, 최소한의 지터, 일관된 성능이 필요합니다. Onload는 애플리케이션이 표준 BSD 소켓 API를 사용할 수 있도록 하면서 운영체제 커널을 우회하고 사용자 공간에서 직접 실행되는 TCP/IP 구현을 제공합니다.

ULL 솔루션에서 Onload를 사용하면 다음이 지원됩니다.

  • 흐름 스티어링: 기본 수신 측면 확장 (RSS) 해싱을 우회하여 특정 트래픽 흐름을 지정된 수신 큐 (RX)로 직접 스티어링할 수 있습니다. 3-튜플 흐름 스티어링이 지원됩니다 (프로토콜, 대상 IP 주소, 대상 포트).

시작하기 전에

U4 Compute Engine 인스턴스에서 Onload를 사용하기 전에 다음 요구사항을 충족해야 합니다.

U4 인스턴스 만들기

아직 만들지 않은 경우 Onload에 필요한 구성이 포함된 다음 절차 중 하나를 사용하여 U4 Compute Engine 인스턴스를 만듭니다.

SSH를 사용하여 인스턴스에 연결

아직 연결하지 않은 경우 SSH를 사용하여 인스턴스에 연결합니다.

루트 사용자로 전환

다음 절차의 명령어와 스크립트는 시스템 수준 설정, 커널 매개변수, 네트워크 인터페이스를 수정합니다. 성공적으로 실행하려면 루트 사용자로 실행해야 합니다. `sudo su`를 실행하여 루트 셸로 전환하거나 필요에 따라 명령어를 실행하기 전에 `sudo`를 추가할 수 있습니다.sudo susudo

Onload 설정

이 섹션에서는 U4 인스턴스에서 Onload를 설정하는 데 필요한 단계를 설명합니다.

종속 항목 설치

  1. Rocky Linux를 사용하는 경우 CodeReady Builder (CRB) 저장소를 사용 설정합니다. Red Hat Enterprise Linux (RHEL)를 사용하는 경우 이 단계를 건너뜁니다.

    dnf -y config-manager --enable crb
    
  2. Onload에 필요한 종속 항목을 설치합니다.

    dnf -y install git clang \
       python3-setuptools \
       linuxptp \
       libcap-devel libbpf-devel libxdp-devel
    

Onload 소스 가져오기

필요한 변경사항이 포함된 onload 저장소 를 가져오려면 다음 명령어를 실행합니다.

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
curl -L https://github.com/Xilinx-CNS/onload/pull/282.patch | git -C /usr/src/onload am
curl -L https://github.com/Xilinx-CNS/onload/pull/325.patch | git -C /usr/src/onload am
curl -L https://github.com/Xilinx-CNS/onload/pull/327.patch | git -C /usr/src/onload am

Onload 빌드

Onload를 빌드하려면 다음 명령어를 실행합니다.

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) 사용 중지

간접 분기 추적 (IBT) 비호환성 에서 설명한 대로 Onload를 사용하려면 IBT를 사용 중지해야 합니다.

IBT를 사용 중지하려면 다음 명령어를 실행합니다.

grubby --args="ibt=off" --update-kernel=ALL
reboot

Onload 로드

이 섹션에서는 인스턴스에 Onload를 로드하는 방법을 설명합니다.

U4P 또는 U4C 인스턴스에 Onload 로드

U4P 또는 U4C 베어메탈 인스턴스에 Onload를 로드하려면 다음 스크립트를 사용합니다.

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

U4S 인스턴스에 Onload 로드

U4S VM 인스턴스에 Onload를 로드하려면 다음 스크립트를 사용합니다.

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

다음을 바꿉니다.

  • NIC_NAME: 네트워크 인터페이스의 OS 이름입니다(예: enp22s0f0).
  • ALLOCATED_QUEUES: 네트워크 인터페이스에서 Onload에 할당할 수신 (RX) 및 전송 (TX) 큐의 수입니다. 이 값을 vNIC에 할당된 총 RX 또는 TX 큐 수의 절반으로 설정합니다.

    U4S 인스턴스의 경우 총 큐 수 (각각 RX 또는 TX 큐)는 vNIC당 최대 16개의 큐까지 num_vcpus / num_vnics와 같습니다. 예를 들어 vNIC에 총 4개의 TX 큐가 있는 경우 이 값을 2로 설정합니다. vNIC에 총 16개의 TX 큐가 있는 경우 이 값을 8로 설정합니다.

    기본 큐 할당에 대한 자세한 내용은 수신 및 전송 큐를 참조하세요.

Onload 플래그 구성

성능을 최적화하고 지연 시간을 줄이려면 Onload로 애플리케이션을 실행할 때 다음 환경 변수 및 플래그 집합을 사용하면 됩니다. 이 섹션에는 애플리케이션에 맞게 필요에 따라 조정할 수 있는 권장 설정이 포함되어 있습니다.

애플리케이션 명령어 전에 이러한 매개변수를 지정해야 합니다. 예를 들어 이러한 설정으로 애플리케이션을 실행하려면 다음 형식을 사용합니다.

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 로드 취소

Onload를 로드 취소하려면 다음 스크립트를 사용합니다.

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

Onload를 자동으로 시작하는 systemd 서비스 구성

인스턴스가 부팅될 때 Onload를 자동으로 시작하려면 systemd 서비스로 등록하면 됩니다. 다음 템플릿을 사용하여 서비스 파일을 만듭니다.

[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

다음을 바꿉니다.

바쁜 폴링 구성

이 섹션에서는 인스턴스에서 바쁜 폴링을 구성하는 방법의 예를 제공합니다.

바쁜 폴링은 기기 인터럽트를 기다리는 대신 새 네트워크 패킷을 지속적으로 확인하여 지연 시간과 지터를 줄이는 데 도움이 됩니다. 바쁜 폴링에 대한 자세한 내용은 Linux 커널 문서의 바쁜 폴링 을 참조하세요.

Onload 스택에서 사용하는 RX 큐 가져오기

Onload 스택에서 사용하는 RX 큐를 가져오려면 다음 단계를 따르세요.

  1. `onload_stackdump`를 실행하여 Onload 스택 ID를 가져옵니다. onload_stackdump

    onload_stackdump
    
  2. Onload 스택 ID와 NAPI 큐 ID가 항상 일치하지 않을 수 있으므로 다음 스크립트를 사용하여 스택 ID에서 해당하는 인터페이스 이름, 색인, 큐 ID를 가져옵니다.

    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)

    ONLOAD_STACK_ID를 바쁜 폴링을 사용 설정하거나 사용 중지하려는 스택의 ID로 바꿉니다.

  3. 다음 섹션에서 바쁜 폴링을 사용 설정하거나 사용 중지할 때 사용할 값을 기록합니다.

RX 큐에서 바쁜 폴링 사용 설정

이 섹션에서는 Onload 스택에서 사용하는 특정 RX 큐에서 바쁜 폴링을 사용 설정하는 방법의 예를 제공합니다.

  1. 터미널에서 다음 bash 스크립트를 실행합니다. enable_single_queue 함수는 다음을 실행합니다.

    • netlink (ynl)를 사용하여 RX 큐에 해당하는 napi_id를 가져옵니다.
    • napi_id에서 threaded: busy-poll 속성을 설정합니다.
    • napi_id를 바쁜 폴링하는 스레드의 kthread_pid를 가져옵니다.
    • taskset을 사용하여 kthread_pid를 특정 CPU에 바인딩합니다.
    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
    }
  2. 다음 명령어를 실행하여 enable_single_queue 함수를 호출합니다.

    enable_single_queue NIC_NAME QUEUE_ID CPU_ID
    

    다음을 바꿉니다.

    • NIC_NAME: 네트워크 인터페이스의 OS 이름입니다(예: ens8f0).
    • QUEUE_ID: 이전에 가져온 큐 ID입니다.
    • CPU_ID: 바쁜 폴링 스레드를 실행할 CPU의 ID입니다(예: 5).
  3. 바쁜 폴링 구성에 영향을 줄 수 있는 스레드 재작성 이벤트를 계획해야 합니다.

스레드 재작성 이벤트 계획

커널이 스레드를 다시 만들면 연결된 스레드 구성(예: CPU 어피니티 마스크 및 예약 정책)이 유지되지 않습니다. 다음과 같은 이벤트로 인해 커널이 NAPI를 바쁜 폴링하는 스레드를 다시 만듭니다.

  • 링크 플랩/재설정
  • XDP 프로그램 첨부파일 (예: Onload를 로드하거나 커스텀 XDP 프로그램을 연결하는 스크립트를 실행할 때)
  • 링 매개변수 변경 (ethtool -G)
  • 큐 수 변경 (ethtool -L)

문제를 방지하려면 정상 작동 중에 스레드 재작성 이벤트를 일으키는 작업을 피하는 것이 좋습니다.

스레드가 다시 생성된 후 바쁜 폴링 구성을 유지하려면 스레드의 새 프로세스 ID (PID)를 가져와서 CPU에 다시 바인딩해야 합니다. enable_single_queue 함수를 다시 실행하여 이 작업을 수행할 수 있습니다.

RX 큐에서 바쁜 폴링 사용 중지

이 섹션에서는 Onload 스택에서 사용하는 특정 RX 큐에서 바쁜 폴링을 사용 중지하는 방법의 예를 제공합니다.

  1. ` onload_stackdump`를 실행하여 Onload 스택에서 사용하는 RX 큐를 가져옵니다.

    onload_stackdump
    
  2. 터미널에서 다음 bash 스크립트를 실행합니다. disable_single_queue 함수는 다음을 실행합니다.

    • netlink (ynl)를 사용하여 RX 큐에 해당하는 napi_id를 가져옵니다.
    • napi_id의 스레드 속성을 disabled로 설정합니다.
    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
    }
  3. 다음 명령어를 실행하여 disable_single_queue 함수를 호출합니다.

    disable_single_queue NIC_NAME QUEUE_ID
    

    다음을 바꿉니다.

    • NIC_NAME: 네트워크 인터페이스의 OS 이름입니다(예: ens8f0).
    • QUEUE_ID: 이전에 가져온 큐 ID입니다.

큐의 바쁜 폴링 상태 가져오기

큐의 NAPI 상태를 확인하여 바쁜 폴링 중인지 확인하려면 다음 명령어를 사용하면 됩니다.

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)"'

다음을 바꿉니다.

  • NIC_NAME: 네트워크 인터페이스의 OS 이름입니다(예: ens8f0).
  • QUEUE_ID: 확인하려는 큐의 ID입니다.
  • QUEUE_TYPE: rx 또는 tx입니다.

성능 최적화

이 섹션에서는 U4 베어메탈 인스턴스 (U4P 및 U4C)의 성능을 최적화하기 위한 일반적인 안내를 제공합니다. 워크로드에 맞게 필요에 따라 이 안내의 예시를 조정하세요.

U4 베어메탈 인스턴스의 NUMA 토폴로지 검토

다음 표에서는 U4 베어메탈 인스턴스에 어떤 네트워크 인터페이스가 어떤 NUMA 노드를 사용하는지 설명합니다.

NIC (Google Cloud 이름) NIC (OS 이름) NUMA 노드 PCIE BDF
nic0 enp22s0f0 0 0000:16:00.0
nic1 ens8f0 0 0000:27:00.0
nic2 ens48f0 2 0000:b8:00.0

위의 표에는 RHEL의 일반적인 OS 할당 네트워크 인터페이스 이름이 포함되어 있습니다. 실제 이름은 다를 수 있습니다.

CPU 격리 체계 결정

최상의 성능을 위해서는 다음을 격리하는 것이 좋습니다.

  • 애플리케이션에서 사용하는 CPU
  • Onload RX 큐를 바쁜 폴링하는 데 사용되는 CPU
  • 커널 및 드라이버 인터럽트에 사용되는 CPU

다음 표에서는 U4 베어메탈 인스턴스에서 CPU를 격리하는 방법의 예를 제공합니다. 워크로드에 맞게 매핑을 조정합니다. 예를 들어 애플리케이션 CPU가 더 필요할 수 있습니다.

목적 CPU
일반 커널 인터럽트 0,1,30,31,60,61,90,91
큐 0~11의 nic0 드라이버 인터럽트 2
큐 0~11의 nic1 드라이버 인터럽트 3
큐 12~15의 nic0nic1 드라이버 인터럽트 4
nic1 바쁜 폴링 5-16
nic1 애플리케이션 스레드 (Onload) 17-29
nic0 바쁜 폴링 32-43
nic0 애플리케이션 스레드 (Onload) 44-59
큐 0~11의 nic2 드라이버 인터럽트 62
큐 12~15의 nic2 드라이버 인터럽트 63
nic2 바쁜 폴링 64-75
nic2 애플리케이션 스레드 (Onload) 76-89

성능 최적화를 위한 종속 항목 설치

성능 최적화를 위해 필요한 종속 항목을 설치하려면 다음 명령어를 실행합니다.

dnf -y install numactl tuna jq

커널 부팅 매개변수 구성

커널 예약에서 CPU를 격리하려면 다음 명령어를 실행합니다. 이렇게 하면 Intel QuickAssist Technology (QAT)도 사용 중지되므로 격리된 코어와 충돌하지 않습니다.

다음 예시 명령어는 CPU 2-29, 32-59, 62-89를 격리하고 일반 커널 인터럽트에 0,1,30,31,60,61,90,91을 지정합니다. 이러한 값은 예시 CPU 격리 체계에 해당합니다. CPU 격리 체계에 따라 필요에 따라 값을 바꿉니다.

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 격리 구성

부팅 후 CPU를 격리하려면 다음 명령어를 실행합니다. 이러한 값 은 예시 CPU 격리 체계에 해당합니다. CPU 격리 체계에 따라 필요에 따라 값을 바꿉니다.

tuna isolate -c 2-29,32-59,62-89

특정 CPU에 큐 인터럽트 할당

이 섹션에서는 gve 큐 인터럽트 요청 (IRQ)을 특정 CPU로 이동하는 방법을 설명합니다. gve 드라이버는 GVNIC 네트워크 인터페이스 유형에서 사용됩니다 Google Cloud.

  1. 지정된 네트워크 인터페이스 및 큐 범위의 IRQ를 결정합니다. irq_list 함수를 정의하는 다음 bash 예시를 참조하세요.

    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 ','
    }
  2. CPU 격리 체계에 따라 IRQ를 적절한 CPU에 할당합니다. 다음 예시 스크립트는 이전 단계의 tunairq_list 함수를 사용합니다.

    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)"

OS 및 기기 설정 구성

  1. 다음 스크립트를 실행하여 지연 시간을 최소화하고 기본 OS 동작이 Onload 구성을 방해하지 않도록 하는 설정을 구성합니다.

    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
  2. Onload 워크로드 전용 큐에서 트래픽을 스티어링하려면, RSS (ethtool -X)를 사용합니다. 다음 예시 스크립트는 예시 CPU 격리 체계의 값을 기반으로 합니다. Onload는 큐 0-11을 사용하므로 스크립트는 다른 모든 트래픽을 큐 12-15로 보냅니다.

    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

다음 단계

  • 인스턴스 시스템 시계를 호스트 서버의 실제 NIC 시계와 동기화하려면 정확한 시간 구성을 참조하세요.