#!/bin/bash version=0.1 get_highest_mask() { cpu_nums=$1 if [ $cpu_nums -gt 32 ]; then mask_tail="" mask_low32="00000000" idx=$((cpu_nums/32)) cpu_reset=$((cpu_nums-idx*32)) if [ $cpu_reset -eq 0 ]; then mask="80000000" for((i=2;i<=idx;i++)) do mask="$mask,$mask_low32" done else for ((i=1;i<=idx;i++)) do mask_tail="$mask_tail,$mask_low32" done mask_head_num=$((1<<(cpu_reset-1))) mask=`printf "%x%s" $mask_head_num $mask_tail` fi else mask_num=$((1<<(cpu_nums-1))) mask=`printf "%x" $mask_num` fi echo $mask } set_irq_affinity() { local ethd=$1 eth=`basename $ethd` dev=$(basename $(readlink /sys/class/net/$eth/device)) echo "eth $eth dev $dev" irqs=$(cat /proc/interrupts | grep ${dev}-input | awk -F":" '{print $1}') i=0 for irq in $irqs do cpunum=$((i%cpuCount+1)) mask=`get_highest_mask $cpunum` echo $mask > /proc/irq/$irq/smp_affinity echo "bind irq [$irq] with mask 0x$mask affinity" ((i++)) done } ethtool_eth() { local ethd=$1 eth=`basename $ethd` pre_ch_max=`ethtool -l $eth 2>/dev/null | grep -i "combined" | head -n 1 | awk '{print $2}'` cur_ch_max=`ethtool -l $eth 2>/dev/null | grep -i "combined" | tail -n 1 | awk '{print $2}'` [ $? -eq 0 ] || continue #ethtool error if [ $pre_ch_max -gt $eth_pre_max ]; then eth_pre_max=$pre_ch_max fi target_value=$([ $cpuCount -le $pre_ch_max ] && echo "$cpuCount" || echo "$pre_ch_max") if [ $target_value -ne $cur_ch_max ]; then ethtool -L $eth combined $target_value echo "Set [$eth] Current Combined to <$target_value>" fi } date cpuCount=$(grep "^processor" /proc/cpuinfo | wc -l) echo "cpu count is $cpuCount" if [ $cpuCount -le 1 ] ;then echo "needn't set nic mq" exit 0 fi eth_pre_max=1 dir=`find /sys/devices/ -type d | grep virtio | grep "/net$"` devs=`ls ${dir} | grep -v devices` if [ -n "$devs" ]; then for dev in ${devs}; do ethtool_eth ${dev}; done else ethtool_eth eth0 fi echo "eth pre max: $eth_pre_max" if [ $eth_pre_max -gt 1 ]; then ps ax | grep -v grep | grep -q irqbalance && pkill irqbalance if [ -n "$devs" ]; then for dev in ${devs}; do set_irq_affinity ${dev}; done else set_irq_affinity eth0 fi fi
但谈何容易。