summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Gilligan <gilligan@vyatta.com>2011-05-17 12:08:39 -0700
committerBob Gilligan <gilligan@vyatta.com>2011-05-17 12:08:39 -0700
commit76c76e8edeb9d71c8afdbb824fbb71c93905daea (patch)
tree642d886f1d1716f719718c08353042ceccf35030
parent4fad1606dfce2b2cd180fe6afcf6eeb9826a8fc7 (diff)
downloadvyatta-cfg-quagga-76c76e8edeb9d71c8afdbb824fbb71c93905daea.tar.gz
vyatta-cfg-quagga-76c76e8edeb9d71c8afdbb824fbb71c93905daea.zip
Bugfix: 6773 (again). Fix handling of single-queue NICs on MPs.
Some single-queue NICs use the multiqueue IRQ naming format (e.g. eth0-rx-0). We need to select the CPU assignements for these IRQs using the same algorithm that we use for single-queue NICs using the standard naming format (e.g. eth0).
-rwxr-xr-xscripts/system/irq-affinity.pl41
1 files changed, 28 insertions, 13 deletions
diff --git a/scripts/system/irq-affinity.pl b/scripts/system/irq-affinity.pl
index ae0ba298..943dace3 100755
--- a/scripts/system/irq-affinity.pl
+++ b/scripts/system/irq-affinity.pl
@@ -29,9 +29,10 @@ die "Error: Interface $ifname does not exist\n"
openlog("irq-affinity","",LOG_LOCAL0);
-my ( $cpus, $cores ) = cpuinfo();
+my ( $cpus, $cores, $processors ) = cpuinfo();
-printf("cpus = $cpus, cores = $cores.\n") if (defined($debug));
+printf("cpus = $cpus, cores = $cores, processors = $processors.\n")
+ if (defined($debug));
if ($mask eq 'auto') {
affinity_auto($ifname);
@@ -104,7 +105,7 @@ sub cpuinfo {
$packages++;
$core *= $packages;
- return ( $cpu + 1, $core );
+ return ( $cpu + 1, $core, $packages );
}
# Determine hyperthreading factor
@@ -201,14 +202,26 @@ sub choose_cpu {
sub assign_multiqueue {
my $ifname = shift;
my $irqmap = shift;
- my $numq = $#_;
-
- # For multi-queue nic's always starts with 0
- # This is less than ideal when there are more core's available
- # than number of queues (probably should barber pole);
- # but the Intel IXGBE needs CPU 0 <-> queue 0
- # because of flow director bug.
- my $cpu = 0;
+ my $numq = scalar(@_);
+ my $cpu;
+
+ if ($numq == 1) {
+ # This is a single-queue NIC using the multi-queue naming
+ # format. In this case, we use the same algorithm to select
+ # the CPU as we use for standard single-queue NICs. This
+ # algorithm spreads the work of different NICs accross
+ # different CPUs.
+
+ $cpu = choose_cpu($ifname);
+ } else {
+ # For multi-queue nic's always starts with CPU 0
+ # This is less than ideal when there are more core's available
+ # than number of queues (probably should barber pole);
+ # but the Intel IXGBE needs CPU 0 <-> queue 0
+ # because of flow director bug.
+
+ $cpu = 0;
+ }
foreach my $name (sort @_) {
my $irq = $irqmap->{$name};
@@ -312,7 +325,8 @@ sub affinity_auto {
} elsif ($numirq > 1) {
# Special case for paired Rx and Tx
my @mirq = grep { /^$ifname-rx-/ } @irqnames;
- if ( $#mirq > 0 ) {
+ my $num_mirq = scalar(@mirq);
+ if ( $num_mirq > 0 ) {
assign_multiqueue( $ifname, $irqmap, @mirq );
@mirq = grep { /^$ifname-tx-/ } @irqnames;
@@ -322,7 +336,8 @@ sub affinity_auto {
# Normal case for single irq per queue
@mirq = grep { /^$ifname-/ } @irqnames;
- if ( $#mirq > 0 ) {
+ $num_mirq = scalar(@mirq);
+ if ( $num_mirq > 0 ) {
assign_multiqueue( $ifname, $irqmap, @mirq );
return;
}