# cat bind_vf_irqs.sh #!/bin/bash # Script to bind Mellanox VF MSI-X interrupts to a given CPU range # Usage: ./bind_vf_irqs.sh <PCI_ADDR> <CPU_LIST> # Example: ./bind_vf_irqs.sh 0000:c1:00.1 0-39
PCI_ADDR=$1 CPU_LIST=$2
if [[ -z "$PCI_ADDR" || -z "$CPU_LIST" ]]; then echo"Usage: $0 <PCI_ADDR> <CPU_LIST>" exit 1 fi
# Get all IRQs for this VF IRQS=($(grep -i "$PCI_ADDR" /proc/interrupts | awk -F: '{gsub(" ","",$1); print $1}'))
# Convert CPU_LIST to array CPUS=() for cpu in $(echo$CPU_LIST | tr','' ' | sed 's/-/ /'); do CPUS+=($cpu) done
# Handle ranges like 0-39 if [[ ${#CPUS[@]} -eq 2 ]]; then START=${CPUS[0]} END=${CPUS[1]} CPUS=() for ((i=START;i<=END;i++)); do CPUS+=($i) done fi
CPU_COUNT=${#CPUS[@]} INDEX=0
echo"Binding VF $PCI_ADDR IRQs to CPUs: ${CPUS[*]}"
for irq in"${IRQS[@]}"; do cpu=${CPUS[$INDEX]} echo$cpu > /proc/irq/$irq/smp_affinity_list echo"IRQ $irq -> CPU $cpu" INDEX=$(( (INDEX + 1) % CPU_COUNT )) done
echo"Done."
运行脚本来绑定 VF 的 IRQ 到 CPU core 0-11 上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# chmod +x bind_vf_irqs.sh # ./bind_vf_irqs.sh 0000:c1:00.1 0-39 Binding VF 0000:c1:00.1 IRQs to CPUs: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 IRQ 560 -> CPU 0 IRQ 561 -> CPU 1 IRQ 562 -> CPU 2 IRQ 563 -> CPU 3 IRQ 564 -> CPU 4 IRQ 565 -> CPU 5 IRQ 566 -> CPU 6 IRQ 567 -> CPU 7 IRQ 568 -> CPU 8 IRQ 569 -> CPU 9 IRQ 570 -> CPU 10 IRQ 571 -> CPU 11 Done.
通过上述步骤,成功将 VF 的 IRQ 绑定到 CPU core 0-11 上,以提高虚拟机的网络性能。
在虚拟机内部,优化网络性能的一个重要步骤是配置 RPS (Receive Packet Steering),将网络接收处理分散到多个 CPU core 上,以提高网络吞吐量。
通过以下命令将 enp0s9 网卡的 RPS CPU mask 设置为 ffffffff,表示允许32 CPU core 处理网络接收任务。
1 2 3
for i in /sys/class/net/enp0s9/queues/rx-*/rps_cpus; do echo ffffffff > $i done
通过上述命令,成功配置了 RPS,使得 enp0s9 网卡的网络接收处理可以分散到多个 CPU core 上,从而提高了虚拟机的网络性能。
3. 测试脚本
Server 端:
1 2 3 4 5 6 7 8 9 10
#!/usr/bin/bash core=32 for((i=0;i<$core;i++)) do let port=3000+$i let cpu=$i%$core echo"$port is listening on $cpu" numactl --physcpubind=$cpu iperf3 -s -D -p $port done echo"please use pkill iperf3 to stop server"
Client 端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#!/bin/sh #core=`cat /proc/cpuinfo|grep "processor"|wc -l` core=32 ip=$1 for((i=0;i<$core;i++)) do let port=3000+$i let cpu=$i%$core lettime=3600 echo"$port is connected on cpu $cpu" numactl --physcpubind=$cpu iperf3 -c $ip -p $port -t $time -P 3 > iperf-tcp-$i.log & sleep 0.3 done echo"after running $time sec iperf3 client will stop"