]> git.openfabrics.org - ~emulex/for-vlad/old/compat-rdma.git/commitdiff
truescale.cmds: fix many issues with irqbalance banning
authorMike Marciniszyn <mike.marciniszyn@intel.com>
Tue, 14 Jan 2014 14:51:50 +0000 (09:51 -0500)
committerMike Marciniszyn <mike.marciniszyn@intel.com>
Tue, 14 Jan 2014 14:51:50 +0000 (09:51 -0500)
The following issues are addressed:
- Detect --banirq vs. IRQ_BALANCE_BANNED_INTERRUPTS
- Configure --banirq vs. IRQ_BALANCE_BANNED_INTERRUPTS
- Detect unconfigurable banning (SLES11SP2/3)
- Determine service name correctly
- Use grep to cut out qib interrupts from banned configuration

This patch also adds the shell comment line to better
support invokation from udev.

Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
ofed_scripts/truescale.cmds

index 31ff9ddd6f69c9407b8bda6c6c61d94e30753796..42f541071de2ade10867816bb78459652c0b46fc 100644 (file)
@@ -1,3 +1,4 @@
+#!/bin/sh
 # Copyright (c) 2013 Intel Corporation. All rights reserved.
 # Copyright (c) 2010 QLogic Corporation.
 # All rights reserved.
 qb=/sys/class/infiniband/qib
 ir=/proc/irq
 serdes_parm=txselect
-service="/etc/init.d/irqbalance"
 irqbalance_conf=/etc/sysconfig/irqbalance
+irqbalance_bin=/usr/sbin/irqbalance
+if [ -f $irqbalance_bin ]; then
+    # Deal with different names for the irqbalance service on
+    # different distros
+    service=$(rpm -ql $(rpm -qf $irqbalance_bin) 2>/dev/null | grep init.d)
+    service=$(basename $service)
+fi
 OPENIBD_CONFIG=${OPENIBD_CONFIG:-"/etc/infiniband/openib.conf"}
 CONFIG=$OPENIBD_CONFIG
 
@@ -240,6 +247,92 @@ get_localcpus()
     fi
 }
 
+irq_ban_configurable()
+{
+    if [ ! -x $irqbalance_bin ]; then
+       return 1
+    fi
+    if strings $irqbalance_bin | grep -q IRQBALANCE_BANNED_INTERRUPTS; then
+       return 0
+    fi
+    # new style irqbalance banning
+    if grep -q IRQBALANCE_ARGS $irqbalance_conf; then
+       return 0
+    fi
+    return 1
+}
+
+new_irq_ban_syntax()
+{
+    if strings $irqbalance_bin | grep -q IRQBALANCE_BANNED_INTERRUPTS; then
+       return 1
+    fi
+    return 0
+}
+
+get_irqs_banned()
+{
+    local banned=
+    if new_irq_ban_syntax; then
+       local -a arr
+       local irq= arg= args=
+       args=$(grep '^IRQBALANCE_ARGS' ${irqbalance_conf} | sed s/IRQBALANCE_ARGS=// | sed s/\"//g)
+       arr=($(echo ${args}))
+       for arg in "${arr[@]}"; do
+           case $arg in 
+               --banirq*)
+                   irq=${arg#--banirq=}
+                   if [ -n "$irq" ]; then
+                       banned="$banned $irq"
+                   fi
+                   ;;
+           esac
+       done
+    else
+       banned="$(grep '^IRQBALANCE_BANNED_INTERRUPTS' ${irqbalance_conf} | sed s/IRQBALANCE_BANNED_INTERRUPTS=// | sed s/\"//g)"
+    fi
+    echo $banned
+}
+
+set_irqs_banned()
+# $1 - list of irqs
+{
+    local banned="$1" irq=
+    local newformat
+   
+    new_irq_ban_syntax
+    newformat=$?
+    sed -ie '/^IRQBALANCE_BANNED_INTERRUPTS=/d' ${irqbalance_conf}
+    sed -ie '/^export IRQBALANCE_BANNED_INTERRUPTS/d' ${irqbalance_conf}
+    if [ $newformat -eq 0 ]; then
+       local args= old=
+       # delete old format
+       for irq in $banned; do
+           if [ -z "$args" ]; then
+               args="--banirq=$irq"
+           else
+               args="$args --banirq=$irq"
+           fi
+       done
+       old=$(grep '^IRQBALANCE_ARGS' ${irqbalance_conf} | sed -e s/^IRQBALANCE_ARGS=// | sed s/--banirq=[0-9][0-9]*//g | sed s/\"//g)
+       old=$(echo $old)
+       sed -ie '/^IRQBALANCE_ARGS=/d' ${irqbalance_conf}
+       if [ -z "$old" -a -z "$args" ]; then
+           return
+       fi
+       if [ -n "$old" ]; then
+           echo "IRQBALANCE_ARGS=\"${old} ${args}\"" >> ${irqbalance_conf}
+        else
+           echo "IRQBALANCE_ARGS=\"${args}\"" >> ${irqbalance_conf}
+       fi
+    else
+       if [ -n "$banned" ]; then
+           echo "IRQBALANCE_BANNED_INTERRUPTS=\"${banned}\"" >> ${irqbalance_conf}
+           echo "export IRQBALANCE_BANNED_INTERRUPTS" >> ${irqbalance_conf}
+       fi
+    fi
+}
+
 set_irq_affinity()
 {
     local -a irqs cpulist
@@ -255,17 +348,8 @@ set_irq_affinity()
     
     if [ ${balance} -eq 1 ]; then
        # stop irqbalance
-       if [ ! -f ${service} ]; then
-           if [ -f /usr/sbin/irqbalance ]; then
-               # Deal with different names for the irqbalance service on
-               # different distros
-               service=$(rpm -ql $(rpm -qf /usr/sbin/irqbalance) 2>/dev/null | \
-                   grep /etc/init.d)
-           fi
-       fi
-       
        if [ -n "${service}" ]; then
-           ${service} stop 2>/dev/null
+           service ${service} stop 2>/dev/null
            [ ${?} -ne 0 ] && balance=0
        else
            balance=0
@@ -323,24 +407,18 @@ set_irq_affinity()
                    done; echo ${b}))
        done
     fi
-
     
-    if [ ${balance} -eq 1 ]; then
+    if test ${balance} -eq 1 && irq_ban_configurable; then
        if [ -f ${irqbalance_conf} ]; then
-           prevbanned="$(grep IRQBALANCE_BANNED_INTERRUPTS ${irqbalance_conf})"
-           prevbanned=$( (eval "${prevbanned}"; echo $IRQBALANCE_BANNED_INTERRUPTS) )
+           prevbanned=`get_irqs_banned`
            [ -n "${prevbanned}" ] && banned="${prevbanned} ${banned}"
        fi
-       
-       sed -ie '/^IRQBALANCE_BANNED_INTERRUPTS=/d' ${irqbalance_conf}
        tbanned=$(for i in $banned; do
            echo $i
        done | sort | uniq)
        banned=$(echo $tbanned)
-       echo "IRQBALANCE_BANNED_INTERRUPTS=\"${banned}\"" >> \
-           ${irqbalance_conf}
-
-       ${service} start
+       set_irqs_banned "$banned"
+       service ${service} start
     fi
     return
 }
@@ -350,22 +428,16 @@ clean_irq_affinity()
     local irqs= banned= prevbanned=
     local -i balance=0
     
+    if ! irq_ban_configurable; then
+       return
+    fi
     [ -n "$(ps aux | grep irqbalance | grep -v grep | awk '{print $2}')" ] && \
        balance=1
     
     if [ ${balance} -eq 1 ]; then
        # stop irqbalance
-       if [ ! -f ${service} ]; then
-           if [ -f /usr/sbin/irqbalance ]; then
-               # Deal with different names for the irqbalance service on
-               # different distros
-               service=$(rpm -ql $(rpm -qf /usr/sbin/irqbalance) 2>/dev/null | \
-                   grep /etc/init.d)
-           fi
-       fi
-       
        if [ -n "${service}" ]; then
-           ${service} stop 2>/dev/null
+           service ${service} stop 2>/dev/null
            [ ${?} -ne 0 ] && balance=0
        else
            balance=0
@@ -375,17 +447,20 @@ clean_irq_affinity()
     irqs=$(grep 'ib_qib' /proc/interrupts | sed -re 's/([0-9]*):.*/\1/g')
     
     if [ -f ${irqbalance_conf} ]; then
-       banned="$(grep IRQBALANCE_BANNED_INTERRUPTS ${irqbalance_conf})"
-       banned=$( (eval "${banned}"; echo $IRQBALANCE_BANNED_INTERRUPTS) )
-       for irq in ${irqs}; do
-           banned="$(echo "${banned}" | sed -e 's/'$irq'//g')"
-       done
-       banned="$(echo ${banned} | sed -e 's/\ */\ /g')"
-       sed -ie '/^IRQBALANCE_BANNED_INTERRUPTS=/d' ${irqbalance_conf}
-       if [ -n "${banned}" -a "X${banned}" != "X " ]; then
-           echo "IRQBALANCE_BANNED_INTERRUPTS=${banned}" >> \
-               ${irqbalance_conf}
-       fi
+       local i
+       banned=`get_irqs_banned`
+       for i in ${irqs}; do
+           echo $irq
+       done | sort | uniq > /tmp/qib_interrupts$$
+       if [ -s /tmp/qib_interrupts$$ ]; then
+           for i in $banned; do
+               echo $i
+           done | sort | uniq > /tmp/banned_interrupts$$
+           banned=$(grep -v -f /tmp/qib_interrupts$$ /tmp/banned_interrupts$$)
+           banned=$(echo ${banned})
+           set_irqs_banned "$banned"
+       fi
+       rm -f /tmp/qib_interrupts$$ /tmp/banned_interrupts$$
     fi
 
     if [ ${balance} -eq 1 ]; then