config/worker-utils/worker-utils/affine-platform.sh

164 lines
5.2 KiB
Bash
Executable File

#!/bin/bash
################################################################################
# Copyright (c) 2013 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
################################################################################
# Define minimal path
PATH=/bin:/usr/bin:/usr/local/bin
LOG_FUNCTIONS=${LOG_FUNCTIONS:-"/etc/init.d/log_functions.sh"}
CPUMAP_FUNCTIONS=${CPUMAP_FUNCTIONS:-"/etc/init.d/cpumap_functions.sh"}
TASK_AFFINITY_FUNCTIONS=${TASK_AFFINITY_FUNCTIONS:-"/etc/init.d/task_affinity_functions.sh"}
source /etc/init.d/functions
[[ -e ${LOG_FUNCTIONS} ]] && source ${LOG_FUNCTIONS}
[[ -e ${CPUMAP_FUNCTIONS} ]] && source ${CPUMAP_FUNCTIONS}
[[ -e ${TASK_AFFINITY_FUNCTIONS} ]] && source ${TASK_AFFINITY_FUNCTIONS}
linkname=$(readlink -n -f $0)
scriptname=$(basename $linkname)
# Enable debug logs
LOG_DEBUG=1
. /etc/platform/platform.conf
################################################################################
# Affine all running tasks to the CPULIST provided in the first parameter.
################################################################################
function affine_tasks {
local CPULIST=$1
local PIDLIST
local RET=0
# Affine non-kernel-thread tasks (excluded [kthreadd] and its children) to all available
# cores. They will be reaffined to platform cores later on as part of nova-compute
# launch.
log_debug "Affining all tasks to all available CPUs..."
affine_tasks_to_all_cores
RET=$?
if [ $RET -ne 0 ]; then
log_error "Some tasks failed to be affined to all cores."
fi
# Get number of logical cpus
N_CPUS=$(cat /proc/cpuinfo 2>/dev/null | \
awk '/^[pP]rocessor/ { n +=1 } END { print (n>0) ? n : 1}')
# Calculate platform cores cpumap
PLATFORM_COREMASK=$(cpulist_to_cpumap ${CPULIST} ${N_CPUS})
# Set default IRQ affinity
echo ${PLATFORM_COREMASK} > /proc/irq/default_smp_affinity
# Affine all PCI/MSI interrupts to platform cores; this overrides
# irqaffinity boot arg, since that does not handle IRQs for PCI devices
# on numa nodes that do not intersect with platform cores.
PCIDEVS=/sys/bus/pci/devices
declare -a irqs=()
irqs+=($(cat ${PCIDEVS}/*/irq 2>/dev/null | xargs))
irqs+=($(ls ${PCIDEVS}/*/msi_irqs 2>/dev/null | grep -E '^[0-9]+$' | xargs))
# flatten list of irqs, removing duplicates
irqs=($(echo ${irqs[@]} | tr ' ' '\n' | sort -nu))
log_debug "Affining all PCI/MSI irqs(${irqs[@]}) with cpus (${CPULIST})"
for i in ${irqs[@]}; do
/bin/bash -c "[[ -e /proc/irq/${i} ]] && echo ${CPULIST} > /proc/irq/${i}/smp_affinity_list" 2>/dev/null
done
if [[ "$subfunction" == *"worker,lowlatency" ]]; then
# Affine work queues to platform cores
echo ${PLATFORM_COREMASK} > /sys/devices/virtual/workqueue/cpumask
echo ${PLATFORM_COREMASK} > /sys/bus/workqueue/devices/writeback/cpumask
# On low latency compute reassign the per cpu threads rcuc, ksoftirq,
# ktimersoftd to FIFO along with the specified priority
PIDLIST=$( ps -e -p 2 |grep rcuc | awk '{ print $1; }')
for PID in ${PIDLIST[@]}; do
chrt -p -f 4 ${PID} 2>/dev/null
done
PIDLIST=$( ps -e -p 2 |grep ksoftirq | awk '{ print $1; }')
for PID in ${PIDLIST[@]}; do
chrt -p -f 2 ${PID} 2>/dev/null
done
PIDLIST=$( ps -e -p 2 |grep ktimersoftd | awk '{ print $1; }')
for PID in ${PIDLIST[@]}; do
chrt -p -f 3 ${PID} 2>/dev/null
done
fi
return 0
}
################################################################################
# Start Action
################################################################################
function start {
local RET=0
echo -n "Starting ${scriptname}: "
## Check whether we are root (need root for taskset)
if [ $UID -ne 0 ]; then
log_error "require root or sudo"
RET=1
return ${RET}
fi
## Define platform cpulist to be thread siblings of core 0
PLATFORM_CPULIST=$(get_platform_cpu_list)
# Affine all tasks to platform cpulist
affine_tasks ${PLATFORM_CPULIST}
RET=$?
if [ ${RET} -ne 0 ]; then
log_error "Failed to affine tasks ${PLATFORM_CPULIST}, rc=${RET}"
return ${RET}
fi
print_status ${RET}
return ${RET}
}
################################################################################
# Stop Action - don't do anything
################################################################################
function stop {
local RET=0
echo -n "Stopping ${scriptname}: "
print_status ${RET}
return ${RET}
}
################################################################################
# Restart Action
################################################################################
function restart {
stop
start
}
################################################################################
# Main Entry
#
################################################################################
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
restart
;;
status)
echo -n "OK"
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|status}"
exit 1
esac
exit $?