עבודה עם Onload

בדף הזה מוסבר איך להשתמש ב-Onload עם מכונות U4 ב-Compute Engine.

מידע על Onload

Onload היא חבילת פרוטוקולים לרשת עם ביצועים גבוהים לאפליקציות שרגישות לזמן טעינה ודורשות זמן טעינה נמוך במיוחד, תנודות מינימליות בנתונים וביצועים עקביים. ‫Onload מספקת הטמעה של TCP/IP שעוקפת את ליבת מערכת ההפעלה ופועלת ישירות במרחב המשתמש, תוך מתן אפשרות לאפליקציות להשתמש ב-APIs רגילים של BSD socket.

השימוש ב-Onload עם פתרון ULL כולל תמיכה ב:

  • הפניית תנועה: אפשר לעקוף את הגיבוב (hashing) של קנה המידה של קבלת נתונים (RSS) שמוגדר כברירת מחדל על ידי הפניית תנועה ספציפית ישירות אל תור קבלה (RX) ייעודי. יש תמיכה בהכוונת זרימה של 3 טאפלים (פרוטוקול, כתובת IP של היעד, יציאת היעד).

לפני שמתחילים

לפני שמשתמשים ב-Onload במכונות U4 ב-Compute Engine, צריך לעמוד בדרישות הבאות.

יצירת מופע U4

אם עדיין לא עשיתם זאת, צריך ליצור מכונה של Compute Engine מסוג U4 באמצעות אחת מהפעולות הבאות, שכוללות את ההגדרה הנדרשת ל-Onload:

התחברות למכונה באמצעות SSH

אם עוד לא עשיתם זאת, מתחברים למכונה באמצעות SSH.

מעבר למשתמש Root

הפקודות והסקריפטים בהליכים הבאים משנים הגדרות ברמת המערכת, פרמטרים של ליבת המערכת וממשקי רשת. כדי להריץ אותן בהצלחה, צריך להריץ אותן כמשתמש root. אפשר לעבור אל מעטפת root על ידי הפעלת הפקודה sudo su, או להוסיף את הפקודה sudo לפני הפעלת פקודות לפי הצורך.

הגדרת Onload

בקטע הזה מוסבר איך מגדירים את Onload במכונת U4.

התקנת יחסי תלות

  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

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

כדי להשתמש ב-Onload כמו שמתואר במאמר אי-תאימות של מעקב אחר הסתעפות עקיפה (IBT) , צריך להשבית את IBT.

כדי להשבית את IBT, מריצים את הפקודות הבאות:

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

טעינה בטעינה

בקטע הזה מוסבר איך לטעון את Onload במכונה.

טעינת Onload במכונת U4P או U4C

כדי לטעון את Onload במכונת Bare Metal מסוג U4P או U4C, משתמשים בסקריפט הבא.

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 במכונת U4S

כדי לטעון את Onload במכונה וירטואלית מסוג U4S, משתמשים בסקריפט הבא.

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: השם של ממשק הרשת במערכת ההפעלה, למשל enp22s0f0.
  • ALLOCATED_QUEUES: מספר התורים של קבלה (RX) ושידור (TX) להקצאה ל-Onload בממשק הרשת. מגדירים את הערך הזה למחצית ממספר התורים הכולל של RX או TX שהוקצו ל-vNIC.

    במופעי U4S, מספר התורים הכולל (לתורי RX או TX בהתאמה) שווה ל-num_vcpus / num_vnics, עד למקסימום של 16 תורים לכל vNIC. לדוגמה, אם ל-vNIC יש 4 תורים כוללים של TX, צריך להגדיר את הערך הזה ל-2. אם ל-vNIC יש 16 תורים כוללים של TX, צריך להגדיר את הערך הזה ל-8.

    מידע נוסף על הקצאת תורים כברירת מחדל זמין במאמר תורים לקבלה ולשליחה.

הגדרת דיווחים על טעינה

כדי לשפר את הביצועים ולצמצם את זמן האחזור, אפשר להשתמש בקבוצת משתני הסביבה והדגלים הבאה כשמריצים את האפליקציות באמצעות 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

Unload 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

הגדרת שירות systemd שמופעל אוטומטית ב-Onload

כדי להפעיל את 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

מחליפים את מה שכתוב בשדות הבאים:

  • START_SCRIPT_PATH: הנתיב לסקריפט שמתחיל ב-Onload, כמו אחד מהסקריפטים ב-Load Onload.
  • OPTIMIZATION_SCRIPT_PATH: הנתיב לסקריפט האופציונלי שמחיל הגדרות אופטימיזציה. אם רוצים, אפשר ליצור סקריפט שכולל את האופטימיזציות של הביצועים ולהוסיף אותו כאן. אחרת, אפשר להסיר את השורה שכוללת את המשתנה הזה.
  • STOP_SCRIPT_PATH: הנתיב לסקריפט שמפסיק את Onload, כמו הסקריפט ב-Unload Onload.

הגדרת בדיקה של סטטוס העומס

בקטע הזה תמצאו דוגמאות להגדרת סקרים בזמן שהמופע עסוק.

בשיטת הסקר העסוק, המערכת בודקת באופן רציף אם יש חבילות רשת חדשות במקום לחכות להפרעות במכשיר, וכך היא עוזרת להפחית את זמן האחזור ואת התנודות. מידע נוסף על busy polling זמין במאמר בנושא Busy polling במסמכי העזרה של ליבת Linux.

קבלת תור RX שמשמש מחסנית Onload

כדי לקבל את תור ה-RX שבו משתמשת חבילת Onload:

  1. מריצים את הפקודה onload_stackdump כדי לקבל את מזהה מחסנית Onload:

    onload_stackdump
    
  2. יכול להיות שמזהה הערימה של Onload ומזהה התור של NAPI לא תמיד יהיו זהים, ולכן צריך להשתמש בסקריפט הבא כדי לקבל את שם הממשק, האינדקס ומזהה התור התואמים ממזהה הערימה.

    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 במזהה של מחסנית התגים שרוצים להפעיל או להשבית עבורה את בדיקת הזמינות.

  3. בקטעים הבאים מוסבר איך להפעיל או להשבית את בדיקת הזמינות של הערוץ, ואיך להקליט את הערכים שבהם צריך להשתמש.

הפעלת סקרים בזמן שהמכשיר עסוק בתור RX

בקטע הזה מופיעה דוגמה להפעלה של סקר פעיל בתור RX ספציפי שמשמש מחסנית Onload.

  1. מריצים את סקריפט ה-Bash הבא בטרמינל. הפונקציה enable_single_queue מבצעת את הפעולות הבאות:

    • מקבל את napi_id שמתאים לתור RX באמצעות netlink ‏ (ynl)
    • הגדרת המאפיין threaded: busy-poll ב-napi_id
    • הפונקציה מקבלת את kthread_pid של השרשור שבודק כל הזמן את napi_id
    • משתמש ב-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: השם של ממשק הרשת במערכת ההפעלה, למשל ens8f0.
    • QUEUE_ID: מזהה התור שקיבלתם קודם.
    • CPU_ID: מזהה המעבד שבו יפעל השרשור של סקר התפוסה, למשל 5.
  3. חשוב לתכנן אירועים של יצירה מחדש של שרשור שעשויים להשפיע על ההגדרה של סקרים בזמן שהמערכת עסוקה.

תכנון אירועים של יצירה מחדש של שרשורים

כשליבת המערכת יוצרת מחדש את ה-thread, הגדרות ה-thread המשויכות לא נשמרות, כמו מסכת השיוך למעבד ומדיניות התזמון. אירועים כמו אלה שמופיעים בהמשך גורמים לליבת המערכת ליצור מחדש שרשור שנמצא בשימוש ב-NAPI:

  • שינויים מהירים בקישור או איפוסים
  • קבצים מצורפים לתוכנית XDP (לדוגמה, כשמריצים את הסקריפטים לטעינת Onload או כשמצרפים תוכניות XDP מותאמות אישית)
  • שינויים בפרמטרים של הצלצול (ethtool -G)
  • שינויים במספר הפריטים בתור (ethtool -L)

כדי למנוע בעיות, מומלץ להימנע ממשימות שגורמות לאירועים של יצירה מחדש של שרשור במהלך פעולות רגילות.

כדי לשמור על הגדרת הסקרים העמוסים אחרי שיוצרים מחדש את השרשור, צריך לקבל את מזהה התהליך (PID) החדש של השרשור ולקשר אותו מחדש למעבד. כדי לעשות את זה, מריצים שוב את הפונקציה enable_single_queue.

השבתה של בדיקת זמינות בתור RX

בקטע הזה מופיעה דוגמה להשבתת סקרים בזמן שהמערכת עסוקה בתור RX ספציפי שמשמש מחסנית Onload.

  1. כדי לקבל את תור ה-RX שבו משתמשת חבילת Onload, מריצים את הפקודה onload_stackdump:

    onload_stackdump
    
  2. מריצים את סקריפט ה-Bash הבא בטרמינל. הפונקציה disable_single_queue מבצעת את הפעולות הבאות:

    • מקבל את napi_id שמתאים לתור RX באמצעות netlink ‏ (ynl)
    • הגדרת המאפיין threaded של 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: השם של ממשק הרשת במערכת ההפעלה, למשל ens8f0.
    • QUEUE_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: השם של ממשק הרשת במערכת ההפעלה, למשל ens8f0.
  • QUEUE_ID: המזהה של התור שרוצים לבדוק.
  • QUEUE_TYPE: rx או tx.

אופטימיזציה של הביצועים

בקטע הזה מפורטות הנחיות כלליות לאופטימיזציה של הביצועים של מופעי Bare Metal מסוג U4 ‏ (U4P ו-U4C). כדאי להתאים את הדוגמאות בהנחיות האלה לעומסי העבודה שלכם.

בדיקת טופולוגיית ה-NUMA במכונות Bare Metal מסוג U4

בטבלה הבאה מפורט אילו ממשקי רשת משתמשים באילו צמתי NUMA עבור מופעי U4 bare metal:

NIC (Google Cloud name) NIC (שם מערכת ההפעלה) צומת 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. יכול להיות שהשמות בפועל יהיו שונים.

קביעת תוכנית לבידוד מעבד

כדי להשיג את הביצועים הטובים ביותר, מומלץ לבצע את הפעולות הבאות:

  • המעבדים שבהם האפליקציה משתמשת
  • מעבדי ה-CPU שמשמשים לביצוע busy poll בתורי ה-RX של Onload
  • מעבדי ה-CPU שמשמשים להפסקות של ליבת מערכת ההפעלה והמנהל

בטבלה הבאה מופיעה דוגמה לאופן שבו אפשר לבודד מעבדים במכונות Bare Metal מסוג U4. משנים את המיפוי לפי הצורך של עומסי העבודה. לדוגמה, יכול להיות שתרצו יותר מעבדי CPU לאפליקציה.

מטרה מעבדים (CPU)
הפסקות כלליות של ליבת המערכת 0,1,30,31,60,61,90,91
nic0 driver interrupts for queues 0-11 2
nic1 driver interrupts for queues 0-11 3
הפרעות לנהגים nic0 ו-nic1 לתורים 12-15 4
nic1 סקרים פעילים 5-16
nic1 שרשורים של אפליקציות (Onload) 17-29
nic0 סקרים פעילים 32-43
nic0 שרשורים של אפליקציות (Onload) 44-59
nic2 driver interrupts for queues 0-11 62
nic2 נהג קוטע תורות להמתנה 12-15 63
nic2 סקרים פעילים 64-75
nic2 שרשורים של אפליקציות (Onload) 76-89

התקנת יחסי תלות לאופטימיזציה של הביצועים

כדי להתקין את התלויות הנדרשות לאופטימיזציה של הביצועים, מריצים את הפקודה הבאה:

dnf -y install numactl tuna jq

הגדרת פרמטרים להפעלה של ליבת המערכת

כדי לבודד את המעבדים מתזמון הליבה, מריצים את הפקודה הבאה. הפעולה הזו גם משביתה את Intel QuickAssist Technology (QAT) כדי שלא תהיה הפרעה לליבות המבודדות.

בדוגמה הבאה, הפקודה מבודדת את יחידות העיבוד המרכזיות 2-29, 32-59 ו-62-89 ומקצה את 0,1,30,31,60,61,90,91 להפרעות כלליות בקרנל. הערכים האלה תואמים לדוגמה לתוכנית לבידוד 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. מחליפים את הערכים לפי הצורך בהתאם לתוכנית הבידוד של המעבד שלנו.

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

הקצאת הפרעות בתור למעבדים ספציפיים

בקטע הזה מוסבר איך להעביר gveבקשות להפסקת תור (IRQs) למעבדים ספציפיים. מנהל ההתקן gve משמש את סוג ממשק הרשת GVNIC ב- Google Cloud.

  1. קובעים את ה-IRQ עבור ממשק רשת וטווח תורים נתונים. בדוגמה הבאה של bash מוגדרת פונקציה irq_list.

    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. מקצים IRQ למעבד המתאים על סמך תוכנית הבידוד של המעבד. בדוגמה הבאה של סקריפט נעשה שימוש בפונקציה tuna ובפונקציה irq_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)"

הגדרת מערכת ההפעלה והגדרות המכשיר

  1. מריצים את הסקריפט הבא כדי להגדיר הגדרות שיעזרו לצמצם את זמן האחזור ולמנוע מהתנהגויות ברירת המחדל של מערכת ההפעלה להפריע להגדרות של 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). סקריפט הדוגמה הבא מבוסס על הערכים בסכימת הבידוד של המעבד. מכיוון ש-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 הפיזי של שרת המארח, אפשר לעיין במאמר בנושא הגדרת זמן מדויק.