summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach Marano <zmarano@google.com>2017-02-24 15:43:01 -0800
committerGitHub <noreply@github.com>2017-02-24 15:43:01 -0800
commitf611604a5404f2a742c05722e96aab86dd9844f3 (patch)
tree7ab4a5509430dfa12c742e971259cf4b8c147ce7
parentb896567ee2979ecb35a66523209f9a4a8d8db3c8 (diff)
downloadgoogle-compute-image-packages-f611604a5404f2a742c05722e96aab86dd9844f3.tar.gz
Support >32 vCPU's in set_multiqueue. (#375)
-rwxr-xr-xbuild_packages.sh1
-rwxr-xr-xscripts/set_multiqueue78
2 files changed, 41 insertions, 38 deletions
diff --git a/build_packages.sh b/build_packages.sh
index a2c5cef..6205077 100755
--- a/build_packages.sh
+++ b/build_packages.sh
@@ -42,6 +42,7 @@ function build_distro() {
fpm \
-s python \
-t "${pkg_type}" \
+ --conflicts 'irqbalance' \
--depends "${depends}" \
--depends 'python-boto' \
--depends 'python-setuptools' \
diff --git a/scripts/set_multiqueue b/scripts/set_multiqueue
index 636ee90..9dfe45f 100755
--- a/scripts/set_multiqueue
+++ b/scripts/set_multiqueue
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 2016 Google Inc. All Rights Reserved.
+# Copyright 2017 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ function set_channels() {
ethtool -L "${1}" combined "${2}" > /dev/null 2>&1
}
-echo "Running $(basename "$0")."
+echo "Running $(basename $0)."
NET_DEVS=/sys/bus/virtio/drivers/virtio_net/virtio*
# Loop through all the virtionet devices and enable multi-queue
@@ -68,7 +68,7 @@ do
irq_dir=/proc/irq/*
for irq in $irq_dir
do
- smp_affinity="${irq}/smp_affinity"
+ smp_affinity="${irq}/smp_affinity_list"
[ ! -f "${smp_affinity}" ] && continue
# Classify this IRQ as virtionet intx, virtionet MSI-X, or non-virtionet
# If the IRQ type is virtionet intx, a subdirectory with the same name as
@@ -78,7 +78,7 @@ do
# a decimal integer ranging from 0 to K - 1 where K is the number of
# input (output) queues in the virtionet device.
virtionet_intx_dir="${irq}/${dev}"
- virtionet_msix_dir_regex=".*/${dev}-(input|output)\.[0-9]+$"
+ virtionet_msix_dir_regex=".*/${dev}-(input|output)\.([0-9]+)$"
if [ -d "${virtionet_intx_dir}" ]; then
# All virtionet intx IRQs are delivered to CPU 0
echo "Setting ${smp_affinity} to 01 for device ${dev}."
@@ -90,44 +90,46 @@ do
for entry in ${irq}/${dev}*; do
if [[ "$entry" =~ ${virtionet_msix_dir_regex} ]]; then
virtionet_msix_found=1
+ queue_num=${BASH_REMATCH[2]}
fi
done
affinity_hint="${irq}/affinity_hint"
[ "$virtionet_msix_found" -eq 0 -o ! -f "${affinity_hint}" ] && continue
- # The affinity hint file contains a CPU mask, consisting of
- # groups of up to 8 hexadecimal digits, separated by a comma. Each bit
- # position in the CPU mask hex value specifies whether this interrupt
- # should be delivered to the corresponding CPU. For example, if bits 0
- # and 3 are set in the affinity hint CPU mask hex value, then the
- # interrupt should be delivered to CPUs 0 and 3. The virtionet device
- # driver should set only a single bit in the affinity hint per MSI-X
- # interrupt, ensuring each TX (RX) queue is used only by a single CPU.
- # The virtionet driver will only specify an affinity hint if the number of
- # TX (RX) queues equals the number of online CPUs. If no affinity hint is
- # specified for an IRQ, the affinity hint file will contain all zeros.
- affinity_cpumask=$(cat "${affinity_hint}")
- affinity_hint_enabled=0
- # Parse the affinity hint, skip if mask is invalid or is empty (all-zeros)
- OIFS=${IFS}
- IFS=","
- for cpu_bitmap in ${affinity_cpumask}; do
- bitmap_val=$(printf "%d" "0x${cpu_bitmap}" 2>/dev/null)
- if [ "$?" -ne 0 ]; then
- echo "Invalid affinity hint ${affinity_hint}: ${affinity_cpumask}."
- affinity_hint_enabled=0
- break
- elif [ "${bitmap_val}" -ne 0 ]; then
- affinity_hint_enabled=1
- fi
- done
- IFS=${OIFS}
- if [ "${affinity_hint_enabled}" -eq 0 ]; then
- echo "Cannot set IRQ affinity ${smp_affinity}, affinity hint disabled."
- else
- # Set the IRQ CPU affinity to the virtionet-initialized affinity hint
- echo "Setting ${smp_affinity} to ${affinity_cpumask} for device ${dev}."
- echo "${affinity_cpumask}" > "${smp_affinity}"
- fi
+ # Set the IRQ CPU affinity to the virtionet-initialized affinity hint
+ echo "Setting ${smp_affinity} to ${queue_num} for device ${dev}."
+ echo "${queue_num}" > "${smp_affinity}"
+ real_affinity=`cat ${smp_affinity}`
+ echo "${smp_affinity}: real affinity ${real_affinity}"
done
done
+
+XPS=/sys/class/net/e*/queues/tx*/xps_cpus
+num_cpus=$(nproc)
+
+num_queues=0
+for q in $XPS; do
+ num_queues=$((num_queues + 1))
+done
+
+# If we have more CPUs than queues, then stripe CPUs across tx affinity
+# as CPUNumber % queue_count.
+for q in $XPS; do
+ queue_re=".*tx-([0-9]+).*$"
+ if [[ "$q" =~ ${queue_re} ]]; then
+ queue_num=${BASH_REMATCH[1]}
+ fi
+
+ xps=0
+ for cpu in `seq $queue_num $num_queues $((num_cpus - 1))`; do
+ xps=$((xps | (1 << cpu)))
+ done
+
+ # Linux xps_cpus requires a hex number with commas every 32 bits.
+ # It ignores all bits above # cpus, so unconditionally write a
+ # 64 bit hex value, with a comma between dwords.
+ xps_string=`printf "%08x,%08x" $((xps >> 32 & 0xffffffff)) $((xps & 0xffffffff))`
+
+ echo ${xps_string} > $q
+ printf "Queue %d XPS=%s for %s\n" $queue_num `cat $q` $q
+done | sort -n -k2