diff options
author | Bob Gilligan <gilligan@vyatta.com> | 2011-05-17 12:08:39 -0700 |
---|---|---|
committer | Bob Gilligan <gilligan@vyatta.com> | 2011-05-17 12:08:39 -0700 |
commit | 76c76e8edeb9d71c8afdbb824fbb71c93905daea (patch) | |
tree | 642d886f1d1716f719718c08353042ceccf35030 | |
parent | 4fad1606dfce2b2cd180fe6afcf6eeb9826a8fc7 (diff) | |
download | vyatta-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-x | scripts/system/irq-affinity.pl | 41 |
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; } |