#!/bin/bash # # Copyright (c) 2015, Intel Corporation # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of Intel Corporation nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Affinitize interrupts to cores # # typical usage is (as root): # set_irq_affinity -x local eth1 <eth2> <eth3> # # to get help: # set_irq_affinity
usage() { echo echo"Usage: $0 [-x|-X] {all|local|remote|one|custom} [ethX] <[ethY]>" echo" options: -x Configure XPS as well as smp_affinity" echo" options: -X Disable XPS but set smp_affinity" echo" options: {remote|one} can be followed by a specific node number" echo" Ex: $0 local eth0" echo" Ex: $0 remote 1 eth0" echo" Ex: $0 custom eth0 eth1" echo" Ex: $0 0-7,16-23 eth0" echo exit 1 }
usageX() { echo"options -x and -X cannot both be specified, pick one" exit 1 }
if [ "$1" == "-x" ]; then XPS_ENA=1 shift fi
if [ "$1" == "-X" ]; then if [ -n "$XPS_ENA" ]; then usageX fi XPS_DIS=2 shift fi
if [ "$1" == -x ]; then usageX fi
if [ -n "$XPS_ENA" ] && [ -n "$XPS_DIS" ]; then usageX fi
# Allow usage of , or - # parse_range () { RANGE=${@//,/ } RANGE=${RANGE//-/..} LIST="" for r in$RANGE; do # eval lets us use vars in {#..#} range [[ $r =~ '..' ]] && r="$(eval echo {$r})" LIST+=" $r" done echo$LIST }
# this script only supports interrupt vectors in pairs, # modification would be required to support a single Tx or Rx queue # per interrupt vector
queues="${IFACE}-.*TxRx"
irqs=$(grep "$queues" /proc/interrupts | cut -f1 -d:) [ -z "$irqs" ] && irqs=$(grep $IFACE /proc/interrupts | cut -f1 -d:) [ -z "$irqs" ] && irqs=$(for i in `ls -Ux /sys/class/net/$IFACE/device/msi_irqs` ;\ do grep "$i:.*TxRx" /proc/interrupts | grep -v fdir | cut -f 1 -d : ;\ done) [ -z "$irqs" ] && echo"Error: Could not find interrupts for $IFACE"
echo"IFACE CORE MASK -> FILE" echo"=======================" for IRQ in$irqs; do [ "$n" -gt "$ncores" ] && n=1 j=1 # much faster than calling cut for each for i in$CORES; do [ $((j++)) -ge $n ] && break done core=$i set_affinity ((n++)) done }
# now the actual useful bits of code
# these next 2 lines would allow script to auto-determine interfaces #[ -z "$IFACES" ] && IFACES=$(ls /sys/class/net) #[ -z "$IFACES" ] && echo "Error: No interfaces up" && exit 1
# Core list for each node from sysfs node_dir=/sys/devices/system/node for i in $(ls -d $node_dir/node*); do i=${i/*node/} corelist[$i]=$(<$node_dir/node${i}/cpulist) done
for IFACE in$IFACES; do # echo $IFACE being modified
[root@]# ps -eo user,stat,pid,psr,%cpu,%mem,comm |grep nginx root Ss 1793180.00.0 nginx nginx S 2774030.00.0 nginx nginx S 27741230.00.0 nginx nginx S 2774240.00.0 nginx nginx S 27743220.00.0 nginx nginx S 2774450.00.0 nginx nginx S 27745210.00.0 nginx nginx S 2774610.00.0 nginx nginx S 2774720.00.0 nginx nginx S 2774880.00.0 nginx nginx S 2774900.00.0 nginx nginx S 27750150.00.0 nginx nginx S 27751100.00.0 nginx nginx S 27752160.00.0 nginx nginx S 27753170.00.0 nginx nginx S 2775470.00.0 nginx nginx S 2775520.00.0 nginx nginx S 2775640.00.0 nginx nginx S 2775760.00.0 nginx nginx S 2775850.00.0 nginx nginx S 2775930.00.0 nginx nginx S 27760110.00.0 nginx nginx S 27761140.00.0 nginx nginx S 27762130.00.0 nginx nginx S 2776390.00.0 nginx [root@]# ps -eo user,stat,pid,psr,%cpu,%mem,comm |grep nginx root Ss 1793180.00.0 nginx nginx S 2774000.00.0 nginx nginx S 2774190.00.0 nginx nginx S 2774220.00.0 nginx nginx S 27743120.00.0 nginx nginx S 2774450.00.0 nginx nginx S 27745140.00.0 nginx nginx S 27746120.00.0 nginx nginx S 27747130.00.0 nginx nginx S 2774850.00.0 nginx nginx S 2774990.00.0 nginx nginx S 27750120.00.0 nginx nginx S 2775180.00.0 nginx nginx S 27752160.00.0 nginx nginx S 2775350.00.0 nginx nginx S 2775460.00.0 nginx nginx S 27755120.00.0 nginx nginx S 27756120.00.0 nginx nginx S 27757160.00.0 nginx nginx S 2775810.00.0 nginx nginx S 2775900.00.0 nginx nginx S 27760170.00.0 nginx nginx S 2776130.00.0 nginx nginx S 2776230.00.0 nginx nginx S 2776330.00.0 nginx
[root@]# ps -eo user,stat,pid,psr,%cpu,%mem,comm |grep nginx nginx S 356700.00.0 nginx nginx S 356800.00.0 nginx nginx S 356900.00.0 nginx nginx S 357000.00.0 nginx nginx S 357100.00.0 nginx nginx S 357200.00.0 nginx nginx S 357300.00.0 nginx nginx S 357400.00.0 nginx nginx S 357500.00.0 nginx nginx S 357600.00.0 nginx nginx S 357700.00.0 nginx nginx S 357800.00.0 nginx nginx S 357900.00.0 nginx nginx S 358000.00.0 nginx nginx S 358100.00.0 nginx nginx S 358200.00.0 nginx nginx S 358300.00.0 nginx nginx S 358400.00.0 nginx nginx S 358500.00.0 nginx nginx S 358600.00.0 nginx nginx S 358700.00.0 nginx nginx S 358800.00.0 nginx nginx S 358900.00.0 nginx nginx S 359000.00.0 nginx root Ss 17931200.00.0 nginx