From cbdd8d9e5b017728f181188ea6ceccfe1045af4f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 17 May 2011 16:01:13 -0700 Subject: irq-affinity: add workaround to avoid some cpu's For routing and other applications it is helpful to provide some mechanism to reserve some set of CPU's and not assign interface IRQ's to them. Uses environment variable VYATTA_IRQAFFINITY_BANNED_CPUS as mechanism similar to irqbalance(8). --- scripts/system/irq-affinity.pl | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/scripts/system/irq-affinity.pl b/scripts/system/irq-affinity.pl index 2f023b7a..409eb8f6 100755 --- a/scripts/system/irq-affinity.pl +++ b/scripts/system/irq-affinity.pl @@ -131,17 +131,31 @@ sub set_rps { close $f; } +# Check if the current if this cpu is in the banned mask +# Uses environment variable VYATTA_IRQAFFINITY_BANNED_CPUS +# to mask cpus which irq affinity script should ignore +sub skip_cpu { + my $cpu = shift; + my $banned = $ENV{'VYATTA_IRQAFFINITY_BANNED_CPUS'}; + + return unless defined($banned); # false + + return ((1 << $cpu) & hex($banned)) != 0; +} + # For multi-queue NIC choose next cpu to be on next core -# FIXME assumes all cpu's online sub next_cpu { - my $cpu = shift; + my $origcpu = shift; my $threads = threads_per_core(); + my $cpu = $origcpu; - $cpu += $threads; - if ( $cpu >= $cpus ) { - # wraparound to next thread on core 0 - $cpu = ($cpu + 1) % $threads; - } + do { + $cpu += $threads; + if ( $cpu >= $cpus ) { + # wraparound to next thread on core 0 + $cpu = ($cpu + 1) % $threads; + } + } while ($cpu != $origcpu && skip_cpu($cpu)); return $cpu; } @@ -157,11 +171,15 @@ sub choose_cpu { unless defined($ifunit); my $threads = threads_per_core(); + # Give the load first to one CPU of each hyperthreaded core, then # if there are enough NICs, give the load to the other CPU of # each core. my $ht_wrap = (($ifunit * $threads) / $cpus) % $threads; - return ((($ifunit * $threads) + $ht_wrap) % $cpus); + my $cpu = ((($ifunit * $threads) + $ht_wrap) % $cpus); + + $cpu = next_cpu($cpu) if skip_cpu($cpu); + return $cpu; } # Assignment for multi-queue NICs -- cgit v1.2.3