Set rings rx/tx to maximum that supports hardware

All recent versions of the chipset have 4096, but the driver doesn't
autodetect this. Increasing the number of descriptors can improve
performance dramatically on some hosts.

This is also the case with Intel 10GE NICs - the driver defaults to 256
descriptors each for Rx and Tx, even if the hardware supports 4096.

Depends-On: Ib70ae937165ddb2968c9e4346434f18778b31714
Change-Id: I1e5029e793399ff42002f3d203c6ae3bd2608be2
Closes-Bug: #1456723
This commit is contained in:
Michael Polenchuk 2015-10-16 17:09:04 +03:00
parent 0b445e09d4
commit effc358bec
17 changed files with 396 additions and 30 deletions

View File

@ -0,0 +1,37 @@
# Fact: netrings
#
# Purpose:
# Try to get Facts about the machine's network rings
#
require 'facter/util/ip'
SETTINGS = {
'maximums' => 'Pre-set maximums',
'current' => 'Current hardware settings',
}
rings = Hash.new { |_h, _k| _h[_k] = {} }
mutex = Mutex.new
Facter::Util::IP.get_interfaces.each do |interface|
Thread.new do
rings_entries = Facter::Util::Resolution.exec("ethtool -g #{interface} 2>/dev/null")
Thread.exit unless rings_entries.include? SETTINGS['maximums']
rings_entries.scan(/(#{SETTINGS['current']}|#{SETTINGS['maximums']}):.*?(RX):\s*(\d+).*?(TX):\s*(\d+)/m).each do |settings|
header = settings.shift
mutex.synchronize do
rings[interface].merge!({SETTINGS.key(header) => Hash[*settings]})
end
end
end
end
Facter.add(:netrings) do
confine :kernel => 'Linux'
setcode do
rings
end
end

View File

@ -247,7 +247,12 @@ class Puppet::Provider::L23_stored_config_centos < Puppet::Provider::L23_stored_
k,v = feature.split(' ')
tk = Hash[L23network.ethtool_name_commands_mapping[section_name].select { |key, value| value==k }]
next if tk == ''
feature_params[tk.keys.join()] = ((v=='on' ? true : false))
# Check on/off otherwise get value as is
feature_params[tk.keys.join()] = case v
when 'on' then true
when 'off' then false
else v
end
end
rv[section_name] = feature_params
end
@ -445,7 +450,13 @@ class Puppet::Provider::L23_stored_config_centos < Puppet::Provider::L23_stored_
next if section_key.nil?
features.each do | feature, value |
next if L23network.ethtool_name_commands_mapping[section_name][feature].nil?
rv << " #{L23network.ethtool_name_commands_mapping[section_name][feature]} #{(value==true ? 'on' : 'off')} "
# Get number as is otherwise check true/false
_value = case value
when true then 'on'
when false then 'off'
else value
end
rv << " #{L23network.ethtool_name_commands_mapping[section_name][feature]} #{_value} "
end
rv = "#{section_key} #{provider.name} #{rv};"
end

View File

@ -376,7 +376,11 @@ class Puppet::Provider::L23_stored_config_ubuntu < Puppet::Provider::L23_stored_
key_fullname = key_fullname[0][0]
next if key_fullname.to_s == ''
rv[section_name] ||= {}
rv[section_name][key_fullname] = (record[3]=='on')
rv[section_name][key_fullname] = case record[3]
when 'on' then true
when 'off' then false
else record[3]
end
end
return rv
end
@ -562,7 +566,11 @@ class Puppet::Provider::L23_stored_config_ubuntu < Puppet::Provider::L23_stored_
rules.each do |k,v|
next if L23network.ethtool_name_commands_mapping[section_name][k].nil?
iface=provider.name
val = (v==true ? 'on' : 'off')
val = case v
when true then 'on'
when false then 'off'
else v
end
rv << "post-up ethtool #{section_key} #{iface} #{L23network.ethtool_name_commands_mapping[section_name][k]} #{val} | true # #{k}"
end
end

View File

@ -647,8 +647,13 @@ class Puppet::Provider::L2_base < Puppet::Provider::InterfaceToolset
ethtool_k.split(/\n+/).select{|l| !l.match(/(^\s+|\[fixed\]|^Features)/)}.map{|x| x.split(/[\s\:]+/)}.each do |p|
tmp[p[0]] = (p[1] == 'on')
end
# get current hardware settings
rings = Facter.value(:netrings)[if_name]['current'] rescue empty_return
return {
'offload' => tmp || empty_return
'offload' => tmp || empty_return,
'rings' => rings
}
end

View File

@ -157,7 +157,13 @@ Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
if optmaps
pairs.each_pair do |k,v|
if optmaps.has_key? k
_cmd = [optmaps['__section_key_set__'], @resource[:interface], optmaps[k], v ? 'on':'off']
# Get number as is otherwise check true/false
_value = case v
when true then 'on'
when false then 'off'
else v
end
_cmd = [optmaps['__section_key_set__'], @resource[:interface], optmaps[k], _value]
begin
ethtool_cmd(_cmd)
rescue Exception => e

View File

@ -186,7 +186,7 @@ Puppet::Type.newtype(:l2_port) do
# debug("\nV: #{value.to_yaml}\n")
# debug("\nS: #{should.to_yaml}\n")
# debug("\nN: #{new_should.to_yaml}\n")
new_should.keys.map{|key| new_should[key] = value[key].merge should[key] }
new_should = value.merge(should) { |key, value_v, should_v| value_v.merge should_v }
#debug("\nZ: #{new_should.to_yaml}\n")
(L23network.reccursive_sanitize_hash(value) == L23network.reccursive_sanitize_hash(new_should))
end
@ -223,4 +223,4 @@ Puppet::Type.newtype(:l2_port) do
[self[:bridge]]
end
end
# vim: set ts=2 sw=2 et :
# vim: set ts=2 sw=2 et :

View File

@ -35,8 +35,14 @@ module L23network
'tx-vlan-stag-hw-insert' => 'tx-vlan-stag-hw-insert',
'rx-vlan-stag-hw-parse' => 'rx-vlan-stag-hw-parse',
'rx-vlan-stag-filter' => 'rx-vlan-stag-filter',
},
'rings' => {
'__section_key_set__' => '-G',
'__section_key_get__' => '-g',
'RX' => 'rx',
'TX' => 'tx',
}
}
end
end
end

View File

@ -129,6 +129,14 @@ define l23network::l2::port (
$real_if_type = $if_type
}
# Merge offloading data with rings rx/tx
$netrings_maximums = try_get_value($::netrings, "${port_name}/maximums", undef)
if $netrings_maximums {
$ethtool_opts = deep_merge({ 'rings' => $netrings_maximums }, $ethtool)
} else {
$ethtool_opts = $ethtool
}
L23_stored_config <| title == $port_name |> {
ensure => $ensure,
if_type => $real_if_type,
@ -139,7 +147,7 @@ define l23network::l2::port (
bond_master => $master,
mtu => $mtu,
onboot => $onboot,
ethtool => $ethtool,
ethtool => $ethtool_opts,
delay_while_up => $delay_while_up,
vendor_specific => $vendor_specific,
provider => $config_provider,
@ -158,7 +166,7 @@ define l23network::l2::port (
onboot => $onboot,
#type => $type,
#trunks => $trunks,
ethtool => $ethtool,
ethtool => $ethtool_opts,
vendor_specific => $vendor_specific,
provider => $provider
}

View File

@ -37,6 +37,20 @@ end
:kernel => 'Linux',
:l23_os => 'ubuntu',
:l3_fqdn_hostname => 'stupid_hostname',
:netrings => {
'eth1' => {
'maximums' => {'RX'=>'4096', 'TX'=>'4096'},
'current' => {'RX'=>'256', 'TX'=>'256'}
},
'eth2' => {
'maximums' => {'RX'=>'4096', 'TX'=>'4096'},
'current' => {'RX'=>'256', 'TX'=>'256'}
},
'eth3' => {
'maximums' => {'RX'=>'4096', 'TX'=>'4096'},
'current' => {'RX'=>'2048', 'TX'=>'2048'}
}
}
}
}
@ -71,7 +85,7 @@ end
'generic-receive-offload' => false,
'generic-segmentation-offload' => false
}
}
}.merge({'rings' => facts[:netrings][iface]['maximums']})
})
should contain_l23_stored_config(iface).with({
'ensure' => 'present',
@ -82,7 +96,7 @@ end
'generic-receive-offload' => false,
'generic-segmentation-offload' => false
}
}
}.merge({'rings' => facts[:netrings][iface]['maximums']})
})
end
end
@ -130,6 +144,7 @@ end
:kernel => 'Linux',
:l23_os => 'ubuntu',
:l3_fqdn_hostname => 'stupid_hostname',
:netrings => {}
}
}

View File

@ -10,17 +10,20 @@ network_scheme:
interfaces:
eth0:
ethtool:
offload:
generic-receive-offload: true
generic-segmentation-offload: true
rx-all: true
rx-checksumming: true
rx-fcs: true
rx-vlan-offload: true
scatter-gather: true
tcp-segmentation-offload: true
tx-checksumming: true
tx-nocache-copy: true
offload:
generic-receive-offload: true
generic-segmentation-offload: true
rx-all: true
rx-checksumming: true
rx-fcs: true
rx-vlan-offload: true
scatter-gather: true
tcp-segmentation-offload: true
tx-checksumming: true
tx-nocache-copy: true
rings:
RX: 2048
TX: 2048
eth1:
vendor_specific:
disable_offloading: true
@ -63,6 +66,20 @@ end
:kernel => 'Linux',
:l23_os => 'ubuntu',
:l3_fqdn_hostname => 'stupid_hostname',
:netrings => {
'eth1' => {
'maximums' => {'RX'=>'4096', 'TX'=>'4096'},
'current' => {'RX'=>'256', 'TX'=>'256'}
},
'eth2' => {
'maximums' => {'RX'=>'4096', 'TX'=>'4096'},
'current' => {'RX'=>'256', 'TX'=>'256'}
},
'eth3' => {
'maximums' => {'RX'=>'4096', 'TX'=>'4096'},
'current' => {'RX'=>'2048', 'TX'=>'2048'}
}
}
}
}
@ -70,6 +87,15 @@ end
:settings_yaml => network_scheme,
} end
let(:rings) do
{
'rings' => {
'RX' => '4096',
'TX' => '4096'
}
}
end
before(:each) do
puppet_debug_override()
end
@ -88,6 +114,10 @@ end
'ensure' => 'present',
'bridge' => 'br-eth0',
'ethtool' => {
'rings' => {
'RX' => '2048',
'TX' => '2048'
},
'offload' => {
'generic-receive-offload' => true,
'generic-segmentation-offload' => true,
@ -107,6 +137,10 @@ end
should contain_l2_port('eth0').with({
'bridge' => 'br-eth0',
'ethtool' => {
'rings' => {
'RX' => '2048',
'TX' => '2048'
},
'offload' => {
'generic-receive-offload' => true,
'generic-segmentation-offload' => true,
@ -135,7 +169,7 @@ end
'offload' => {
'generic-receive-offload' => false,
'generic-segmentation-offload' => false
}}
}}.merge(rings)
})
end
@ -147,7 +181,7 @@ end
'generic-receive-offload' => false,
'generic-segmentation-offload' => false
}
}})
}.merge(rings)})
end
it do
@ -169,7 +203,7 @@ end
'generic-receive-offload' => false,
'generic-segmentation-offload' => false
}
}
}.merge(rings)
})
should contain_l23_stored_config(iface).with({
'ensure' => 'present',
@ -180,7 +214,7 @@ end
'generic-receive-offload' => false,
'generic-segmentation-offload' => false
}
}
}.merge(rings)
})
end
end

View File

@ -7,7 +7,13 @@ describe 'l23network::l3::ifconfig', :type => :define do
:osfamily => 'Debian',
:operatingsystem => 'Ubuntu',
:l23_os => 'ubuntu',
:kernel => 'Linux'
:kernel => 'Linux',
:netrings => {
'eth4' => {
'maximums' => {'RX'=>'4096', 'TX'=>'4096'},
'current' => {'RX'=>'256', 'TX'=>'256'}
},
}
} }
let(:params) { {
@ -19,6 +25,12 @@ describe 'l23network::l3::ifconfig', :type => :define do
"class {'l23network': }"
] }
let(:rings) do
{
'rings' => facts[:netrings][params[:interface]]['maximums']
}
end
before(:each) do
puppet_debug_override()
end
@ -35,6 +47,7 @@ describe 'l23network::l3::ifconfig', :type => :define do
'ipaddr' => 'dhcp',
'gateway' => nil,
'vendor_specific' => {},
'ethtool' => rings,
})
end

View File

@ -7,7 +7,13 @@ describe 'l23network::l3::ifconfig', :type => :define do
:osfamily => 'Debian',
:operatingsystem => 'Ubuntu',
:l23_os => 'ubuntu',
:kernel => 'Linux'
:kernel => 'Linux',
:netrings => {
'eth4' => {
'maximums' => {'RX'=>'4096', 'TX'=>'4096'},
'current' => {'RX'=>'256', 'TX'=>'256'}
},
}
} }
let(:params) { {
@ -19,6 +25,12 @@ describe 'l23network::l3::ifconfig', :type => :define do
"class {'l23network': }"
] }
let(:rings) do
{
'rings' => facts[:netrings][params[:interface]]['maximums']
}
end
before(:each) do
puppet_debug_override()
end
@ -35,6 +47,7 @@ describe 'l23network::l3::ifconfig', :type => :define do
'ipaddr' => 'none',
'ipaddr_aliases' => nil,
'vendor_specific' => {},
'ethtool' => rings,
})
end

View File

@ -9,3 +9,4 @@ DEVICE=eth0
BOOTPROTO=dhcp
HWADDR=00:50:56:B2:00:1B
ONBOOT=yes
ETHTOOL_OPTS="-G eth0 rx 2048 tx 2048 ;"

View File

@ -8,3 +8,5 @@ auto eth1
iface eth1 inet static
address 169.254.0.1/24
post-up sleep 25
post-up ethtool -G eth1 rx 2048 | true # RX
post-up ethtool -G eth1 tx 2048 | true # TX

View File

@ -0,0 +1,51 @@
require 'spec_helper'
require 'facter/util/ip'
describe 'netrings', :type => :fact do
before { Facter.clear }
let(:e1000g0_output) do
%q(Ring parameters for e1000g0:
Pre-set maximums:
RX: 4096
RX Mini: 0
RX Jumbo: 0
TX: 4096
Current hardware settings:
RX: 256
RX Mini: 0
RX Jumbo: 0
TX: 256)
end
let(:nge0_output) do
%q(Ring parameters for nge0:
)
end
context 'with two interfaces' do
before :each do
Facter::Util::Resolution.stubs(:exec).with('uname -s').returns('Linux')
Facter::Util::IP.stubs(:get_interfaces).returns(%w(e1000g0 nge0))
Facter::Util::Resolution.stubs(:exec).with("ethtool -g e1000g0 2>/dev/null").returns(e1000g0_output)
Facter::Util::Resolution.stubs(:exec).with("ethtool -g nge0 2>/dev/null").returns(nge0_output)
end
it 'should return info only for one' do
expect(Facter.fact(:netrings).value).to eq({
'e1000g0' => {
'maximums' => {
'RX' => '4096',
'TX' => '4096'
},
'current' => {
'RX' => '256',
'TX' => '256'
}
}
})
end
end
end

View File

@ -0,0 +1,77 @@
require 'spec_helper'
describe Puppet::Type.type(:l23_stored_config).provider(:lnx_centos7) do
let(:input_data) do
{
:eth0 => {
:name => "eth0",
:method => "dhcp",
:provider => "lnx_centos7",
:ethtool => {"rings" => {"RX" => "2048", "TX" => "2048"}},
},
}
end
let(:resources) do
resources = {}
input_data.each do |name, res|
resources.store name, Puppet::Type.type(:l23_stored_config).new(res)
end
resources
end
let(:providers) do
providers = {}
resources.each do |name, resource|
provider = resource.provider
if ENV['SPEC_PUPPET_DEBUG']
class << provider
def debug(msg)
puts msg
end
end
end
provider.create
providers.store name, provider
end
providers
end
before(:each) do
puppet_debug_override()
end
def fixture_path
File.join(PROJECT_ROOT, 'spec', 'fixtures', 'provider', 'l23_stored_config', 'lnx_centos7_spec')
end
def fixture_file(file)
File.join(fixture_path, file)
end
def fixture_data(file)
File.read(fixture_file(file))
end
context "Ethtool options" do
context 'format file' do
subject { providers[:eth0] }
let(:data) { subject.class.format_file('filepath', [subject]) }
it { expect(data).to match %r(DEVICE=eth0) }
it { expect(data).to match %r(ONBOOT=yes) }
it { expect(data).to match %r(ETHTOOL_OPTS="-G eth0 rx 2048 tx 2048 ;") }
end
context 'parse data from fixture' do
let(:data) { subject.class.parse_file('eth0', fixture_data('ifcfg-eth0'))[0] }
it { expect(data[:method]).to eq 'dhcp' }
it { expect(data[:ethtool]).to eq 'rings' => {'RX' => '2048', 'TX' => '2048'} }
end
end
end

View File

@ -0,0 +1,79 @@
require 'spec_helper'
describe Puppet::Type.type(:l23_stored_config).provider(:lnx_ubuntu) do
let(:input_data) do
{
:eth1 => {
:name => "eth1",
:provider => "lnx_ubuntu",
:if_type => "ethernet",
:ethtool => { 'rings' => {'RX' => '2048', 'TX' => '2048'} },
},
}
end
let(:resources) do
resources = {}
input_data.each do |name, res|
resources.store name, Puppet::Type.type(:l23_stored_config).new(res)
end
resources
end
let(:providers) do
providers = {}
resources.each do |name, resource|
provider = resource.provider
if ENV['SPEC_PUPPET_DEBUG']
class << provider
def debug(msg)
puts msg
end
end
end
provider.create
providers.store name, provider
end
providers
end
before(:each) do
puppet_debug_override()
end
def fixture_path
File.join(PROJECT_ROOT, 'spec', 'fixtures', 'provider', 'l23_stored_config', 'lnx_ubuntu__spec')
end
def fixture_file(file)
File.join(fixture_path, file)
end
def fixture_data(file)
File.read(fixture_file(file))
end
context "Ethtool options" do
context 'format file' do
subject { providers[:eth1] }
let(:data) { subject.class.format_file('filepath', [subject]) }
it { expect(data).to match %r(auto eth1) }
it { expect(data).to match %r(iface eth1 inet manual) }
it { expect(data).not_to match %r(.*ethernet.*) }
it { expect(data).to match %r(post-up ethtool -G eth1 rx 2048.*) }
it { expect(data).to match %r(post-up ethtool -G eth1 tx 2048.*) }
end
context "parse data from fixture" do
let(:data) { subject.class.parse_file('eth1', fixture_data('ifcfg-eth1'))[0] }
it { expect(data[:method]).to eq :static }
it { expect(data[:ethtool]).to eq 'rings'=>{'RX' => '2048', 'TX' => '2048'} }
end
end
end