diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-11-12 13:51:24 -0800 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-11-12 13:51:24 -0800 |
commit | 985778af972d1ec074802604c819663af54e499e (patch) | |
tree | ca059f5adaf624ea695b41156b27d494ea9e28c3 /scripts | |
parent | ac9042acae2579b03d39fa6d5b7a8dbef1a8a048 (diff) | |
download | vyatta-cfg-quagga-985778af972d1ec074802604c819663af54e499e.tar.gz vyatta-cfg-quagga-985778af972d1ec074802604c819663af54e499e.zip |
Fix irq-affinity for special cases
Need to handle virtual devices with no IRQ, and older processors
without concept of multi-core.
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/system/irq-affinity.pl | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/scripts/system/irq-affinity.pl b/scripts/system/irq-affinity.pl index eaad95cc..27eae4a8 100755 --- a/scripts/system/irq-affinity.pl +++ b/scripts/system/irq-affinity.pl @@ -86,6 +86,14 @@ sub cpuinfo { return ( $cpu + 1, $core ); } +# Determine hyperthreading factor +# most CPU's have either 1 or 2 threads per core +sub threads_per_core { + return 1 unless defined($cores); + + return $cpus / $cores; +} + # Set affinity value for a irq sub set_affinity { my ( $ifname, $irq, $mask ) = @_; @@ -121,12 +129,14 @@ sub set_rps { # FIXME assumes all cpu's online sub next_cpu { my $cpu = shift; - my $threads = $cpus / $cores; # threads per core + my $threads = threads_per_core(); $cpu += $threads; if ( $cpu >= $cpus ) { - $cpu = ($cpu + 1) % $threads; # next thread on core 0 + # wraparound to next thread on core 0 + $cpu = ($cpu + 1) % $threads; } + return $cpu; } @@ -146,7 +156,8 @@ sub first_cpu { die "can't find number for $ifname\n" unless defined($ifunit); - return ( $ifunit * ($cpus / $cores) ) % $cpus; + my $threads = threads_per_core(); + return ( $ifunit * $threads ) % $cpus; } # Assignment for multi-queue NICs @@ -186,7 +197,7 @@ sub assign_single { set_affinity( $ifname, $irq, 1 << $cpu ); - my $threads = $cpus / $cores; + my $threads = threads_per_core(); if ($threads > 1) { # Use both threads on this cpu if hyperthreading my $mask = ((1 << $threads) - 1) << $cpu; @@ -199,8 +210,9 @@ sub assign_single { sub get_irq { my $ifname = shift; - open( my $irqf, '<', "/sys/class/net/$ifname/device/irq" ) - or warn "$ifname: can't find irq : $!\n"; + # return (undefined) unless device has irq + return unless open( my $irqf, '<', "/sys/class/net/$ifname/device/irq" ); + my $irq = <$irqf>; chomp $irq; close $irqf; @@ -230,14 +242,18 @@ sub affinity_mask { die "$ifname: irq mask $mask is not a valid affinity mask\n" } - my $irq = $1; - my $rps = $3; + my $irqmsk = $1; + my $rpsmsk = $3; + + check_mask($ifname, "irq", $irqmsk); + check_mask($ifname, "rps", $rpsmsk) if $rpsmsk; - check_mask($ifname, "irq", $irq); - check_mask($ifname, "rps", $rps) if $rps; + my $irq = get_irq($ifname); + die "$ifname: attempt to assign affinity to device without irq\n" + unless (defined($irq)); - set_affinity($ifname, get_irq($ifname), hex($irq)); - set_rps($ifname, 0, hex($rps)) if $rps; + set_affinity($ifname, $irq, hex($irqmsk)); + set_rps($ifname, 0, hex($rpsmsk)) if $rpsmsk; } # The auto strategy involves trying to achieve the following goals: @@ -260,7 +276,10 @@ sub affinity_auto { # Figure out what style of irq naming is being used my $numirq = grep { /$ifname/ } @irqnames; - if ( $numirq > 1 ) { + if ( $numirq <= 1 ) { + my $irq = get_irq($ifname); + assign_single( $ifname, $irq) if $irq; + } else { my $nq = grep { /$ifname-rx-/ } @irqnames; if ( $nq > 0 ) { @@ -284,6 +303,4 @@ sub affinity_auto { die "Unknown multiqueue device naming for $ifname\n"; } - - assign_single( $ifname, get_irq($ifname) ); } |