DPDK on VF feature

Change-Id: I9a48da04ff0b64ec66d27afdc412ac2f168ba1fc
This commit is contained in:
Vitalii Kovalchuk 2016-06-06 09:38:46 +00:00 committed by Illia Polliul
parent 22d8946328
commit 0943990630
14 changed files with 311 additions and 40 deletions

View File

@ -0,0 +1,18 @@
# Copyright 2016 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
notice('MODULAR: contrail/contrail-compute-dpdk-on-vf.pp')
include contrail
class { 'contrail::compute::dpdk_on_vf': }

View File

@ -0,0 +1,40 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
require 'yaml'
module Puppet::Parser::Functions
newfunction(:add_data_to_yaml, :type => :rvalue, :doc => <<-EOS
Append yaml file with additional data
example:
add_data_to_yaml(file, key, value)
EOS
) do |args|
file_path = args[0]
key = args[1]
value = args[2]
yaml_string = File.read file_path
current_data = YAML.load yaml_string
current_data[key] = value
yaml_string = YAML.dump current_data
File.write(file_path, yaml_string)
return current_data
end
end

View File

@ -21,14 +21,34 @@ module Puppet::Parser::Functions
) do |args|
physnet = args[0]
dpdk_on_vf = args[1]
sriov_hash = function_get_sriov_devices([])
list = sriov_hash.map { |dev, _|
#pci_address = `ethtool -i #{dev} | awk '/bus-info/ {print $2}'`.strip
pci_address = function_get_dev_pci_addr([dev])
Hash["address" => pci_address, "physical_network" => physnet]
}.to_json
}
return list
if dpdk_on_vf
hiera_data_key = "priv_int_vfn_wl"
priv_int = args[2]
dpdk_vf_number = args[3]
if (File.exists?("/sys/class/net/#{priv_int}"))
vfn = Dir.glob "/sys/class/net/#{priv_int}/device/virtfn*"
vfn_wl = vfn.map { |f|
if not f.end_with? "virtfn#{dpdk_vf_number}"
pci_address = File.readlink(f).split("/")[1]
Hash["address" => pci_address, "physical_network" => physnet]
end
}
list += vfn_wl
function_add_data_to_yaml(["/etc/hiera/plugins/contrail.yaml", hiera_data_key, vfn_wl])
elsif not function_hiera_array([hiera_data_key, []]).empty?
vfn_wl = function_hiera_array([hiera_data_key, []])
list += vfn_wl
end
end
return list.to_json
end
end

View File

@ -1,4 +1,4 @@
# Copyright 2015 Mirantis, Inc.
# Copyright 2016 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
@ -12,9 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
require 'yaml'
module Puppet::Parser::Functions
newfunction(:get_sriov_devices, :type => :rvalue, :doc => <<-EOS
Returns sriov capable devices
@ -23,6 +20,7 @@ module Puppet::Parser::Functions
EOS
) do |args|
dpdk_on_vf = args[0]
bridge_interfaces = Array.new()
bond_interfaces = Array.new()
@ -50,6 +48,23 @@ module Puppet::Parser::Functions
end
end
if dpdk_on_vf
hiera_data_key = "priv_int_sriov_data"
private_interface = args[1]
private_interface_path = "/sys/class/net/" + private_interface
if (File.exists?(private_interface_path + "/device/sriov_totalvfs"))
sriov_hash[private_interface] = Hash.new
sriov_hash[private_interface]["totalvfs"] = IO.read(private_interface_path + "/device/sriov_totalvfs").to_i
sriov_hash[private_interface]["numvfs"] = IO.read(private_interface_path + "/device/sriov_numvfs").to_i
function_add_data_to_yaml(["/etc/hiera/plugins/contrail.yaml", hiera_data_key, sriov_hash[private_interface]])
elsif not function_hiera_hash([hiera_data_key, {}]).empty?
sriov_hiera = function_hiera_hash([hiera_data_key, {}])
sriov_hash[private_interface] = Hash.new
sriov_hash[private_interface]["totalvfs"] = sriov_hiera["totalvfs"]
sriov_hash[private_interface]["numvfs"] = sriov_hiera["numvfs"]
end
end
return sriov_hash
end
end

View File

@ -0,0 +1,41 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
module Puppet::Parser::Functions
newfunction(:get_fv_data, :type => :rvalue, :doc => <<-EOS
Returns interface name, pci address, mac address related to specific virtual function
example:
get_vf_data(dev_name, vf_number)
EOS
) do |args|
dev_name = args[0]
vf_number = args[1]
vf_sys = "/sys/class/net/#{dev_name}/device/virtfn#{vf_number}"
vf_data = Hash.new
hiera_data_key = "dpdk_vf_int_data"
if (File.exists?("/sys/class/net/#{dev_name}/device/virtfn#{vf_number}/net"))
vf_dev_name = Dir.entries("#{vf_sys}/net/")[2]
vf_pci_addr = File.readlink(vf_sys).split("/")[1]
vf_mac_addr = File.open("#{vf_sys}/net/#{vf_dev_name}/address", "rb") { |f| f.read.strip }
vf_data = {"vf_dev_name" => vf_dev_name, "vf_pci_addr" => vf_pci_addr, "vf_mac_addr" => vf_mac_addr}
function_add_data_to_yaml(["/etc/hiera/plugins/contrail.yaml", hiera_data_key, vf_data])
elsif not function_hiera_hash([hiera_data_key, {}]).empty?
vf_data = function_hiera_hash([hiera_data_key, {}])
end
return vf_data
end
end

View File

@ -0,0 +1,31 @@
# Copyright 2016 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
module Puppet::Parser::Functions
newfunction(:sriov_in_kernel, :type => :rvalue, :doc => <<-EOS
Returns true if sriov enable in kernel
example:
sriov_in_kernel()
EOS
) do |args|
params = File.read("/proc/cmdline")
if params.include? "intel_iommu=on" and params.include? "iommu=pt"
return true
else
return false
end
end
end

View File

@ -0,0 +1,63 @@
# Copyright 2016 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
class contrail::compute::dpdk_on_vf {
if $contrail::compute_dpkd_on_vf {
$vf_data = get_fv_data($contrail::phys_dev, $contrail::dpdk_vf_number)
$dpdk_dev_name = "dpdk-vf${contrail::dpdk_vf_number}"
$dpdk_vf_origin_name = $vf_data['vf_dev_name']
$dpdk_dev_pci = $vf_data['vf_pci_addr']
$dpdk_dev_mac = $vf_data['vf_mac_addr']
$phys_dev = $dpdk_dev_name
$pci_wl = generate_passthrough_whitelist(
$contrail::sriov_physnet,
$contrail::compute_dpkd_on_vf,
$contrail::phys_dev,
$contrail::dpdk_vf_number
)
exec { 'rename-dpdk-vf':
path => '/bin:/usr/bin:/usr/sbin',
command => "ip link set ${dpdk_vf_origin_name} name ${dpdk_dev_name}",
unless => 'ip link | grep vhost0',
}
file {'/etc/udev/rules.d/72-contrail-dpdk-on-vf.rules':
ensure => present,
content => template('contrail/72-contrail-dpdk-on-vf.rules.erb'),
}
file {'/etc/contrail/contrail-vrouter-agent.conf':
ensure => present,
content => template('contrail/contrail-vrouter-agent.conf.erb'),
}
nova_config {
'DEFAULT/pci_passthrough_whitelist': value => $pci_wl;
} ~>
service { 'nova-compute':
ensure => running,
enable => true,
}
service {'supervisor-vrouter':
ensure => running,
enable => true,
subscribe => [Exec['rename-dpdk-vf'],
File['/etc/contrail/contrail-vrouter-agent.conf']],
}
}
}

View File

@ -58,4 +58,3 @@ class contrail::compute::network {
default: {}
}
}

View File

@ -34,10 +34,11 @@ class contrail::compute::nova {
'DEFAULT/security_group_api': value => 'neutron';
'DEFAULT/heal_instance_info_cache_interval': value => '0';
}
if $contrail::compute_dpdk_enabled {
nova_config {
'libvirt/virt_type': value => 'kvm';
'CONTRAIL/use_userspace_vhost': value => true;
'libvirt/virt_type': value => 'kvm';
'CONTRAIL/use_userspace_vhost': value => true;
}
file { '/etc/nova/nova-compute.conf':
@ -46,7 +47,13 @@ class contrail::compute::nova {
}
}
if $contrail::compute_sriov_enabled {
$pci_wl = generate_passthrough_whitelist($contrail::sriov_physnet)
$pci_wl = generate_passthrough_whitelist(
$contrail::sriov_physnet,
$contrail::compute_dpkd_on_vf,
$contrail::phys_dev,
$contrail::dpdk_vf_number
)
nova_config {
'DEFAULT/pci_passthrough_whitelist': value => $pci_wl;
}

View File

@ -14,19 +14,20 @@
class contrail::compute::override {
$common_pkg = ['iproute2', 'haproxy', 'libatm1', 'libxen-4.4']
$libvirt_pkg = ['libvirt-bin', 'libvirt0']
$qemu_pkg = ['qemu','qemu-*']
$nova_pkg = ['nova-compute', 'nova-common', 'python-nova', 'python-urllib3']
$keep_config_files = '-o Dpkg::Options::="--force-confold"'
$force_overwrite = '-o Dpkg::Options::="--force-overwrite"'
$patch_path = '/usr/lib/python2.7/dist-packages'
Exec {
path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'],
}
apt::pin { 'contrail-override-common':
explanation => 'Set priority for packages that need to override from contrail repository',
priority => 1200,
@ -131,4 +132,3 @@ class contrail::compute::override {
}
}
}

View File

@ -14,11 +14,14 @@
class contrail::compute::vrouter {
# facter uses underscore instead of dot as a separator for interface name with vlan
$phys_dev_facter = regsubst($::contrail::phys_dev, '\.' , '_')
$dev_mac = getvar("::macaddress_${phys_dev_facter}")
# facter uses underscore instead of dot as a separator for interface name with vlan
$phys_dev_facter = regsubst($::contrail::phys_dev, '\.' , '_')
$dev_mac = getvar("::macaddress_${phys_dev_facter}")
$phys_dev = $contrail::phys_dev
$dpdk_dev_pci = $contrail::phys_dev_pci
if $contrail::compute_dpdk_enabled {
if empty($dev_mac) {
$dpdk_dev_mac = get_mac_from_vrouter()
} else {
@ -66,10 +69,6 @@ $dev_mac = getvar("::macaddress_${phys_dev_facter}")
content => template('contrail/agent_param.erb'),
require => Class[Contrail::Package],
} ->
file {'/etc/contrail/contrail-vrouter-agent.conf':
ensure => present,
content => template('contrail/contrail-vrouter-agent.conf.erb'),
} ->
file {'/etc/contrail/contrail-vrouter-nodemgr.conf':
ensure => present,
content => template('contrail/contrail-vrouter-nodemgr.conf.erb'),
@ -78,13 +77,47 @@ $dev_mac = getvar("::macaddress_${phys_dev_facter}")
command => 'rm -rf /etc/init/supervisor-vrouter.override',
provider => shell,
require => Class[Contrail::Package],
} ->
service {'supervisor-vrouter':
ensure => running,
enable => true,
subscribe => [Class[Contrail::Package],Exec['remove-ovs-modules'],
File['/etc/contrail/agent_param','/etc/contrail/contrail-vrouter-agent.conf',
'/etc/contrail/contrail-vrouter-nodemgr.conf']
],
}
if $contrail::compute_dpkd_on_vf {
$sriov_in_kernel = sriov_in_kernel()
$cmd_arr = ['puppet apply -v -d --logdest /var/log/puppet.log',
'--modulepath=/etc/puppet/modules/:/etc/fuel/plugins/contrail-4.0/puppet/modules/',
'/etc/fuel/plugins/contrail-4.0/puppet/manifests/contrail-compute-dpdk-on-vf.pp',
'&& sed -i "/contrail-compute-dpdk-on-vf/d" /etc/rc.local']
if $sriov_in_kernel {
class { 'contrail::compute::dpdk_on_vf':
require => [Class[Contrail::Package],Exec['remove-ovs-modules'],
File['/etc/contrail/agent_param',
'/etc/contrail/contrail-vrouter-nodemgr.conf']],
}
} else {
file_line {'apply_dpdk_on_vf_after_reboot':
line => join($cmd_arr, ' '),
path => '/etc/rc.local',
}
service {'supervisor-vrouter':
ensure => stopped,
enable => false,
require => Class[Contrail::Package],
}
}
} else {
file {'/etc/contrail/contrail-vrouter-agent.conf':
ensure => present,
content => template('contrail/contrail-vrouter-agent.conf.erb'),
} ->
service {'supervisor-vrouter':
ensure => running,
enable => true,
subscribe => [Class[Contrail::Package],Exec['remove-ovs-modules'],
File['/etc/contrail/agent_param','/etc/contrail/contrail-vrouter-agent.conf',
'/etc/contrail/contrail-vrouter-nodemgr.conf']
],
}
}
}

View File

@ -99,7 +99,16 @@ class contrail {
$global_sriov_enabled = $settings['contrail_global_sriov']
$compute_sriov_enabled = $global_sriov_enabled and 'sriov' in hiera_array('roles')
$sriov_physnet = $settings['sriov_physnet']
$sriov_hash = get_sriov_devices()
# DPDK settings
$global_dpdk_enabled = $settings['contrail_global_dpdk']
$dpdk_on_vf = $settings['dpdk_on_vf']
$compute_dpdk_enabled = $global_dpdk_enabled and 'dpdk' in hiera_array('roles')
# DPDK on VF settings
$compute_dpkd_on_vf = $compute_dpdk_enabled and $compute_sriov_enabled and $settings['dpdk_on_vf']
$dpdk_vf_number = 0
$sriov_hash = get_sriov_devices($compute_dpkd_on_vf, $phys_dev)
# Custom mount point for contrail-db
$cassandra_path = '/var/lib/contrail_db'
@ -110,11 +119,6 @@ class contrail {
default => 'running',
}
# DPDK settings
$global_dpdk_enabled = $settings['contrail_global_dpdk']
$dpdk_on_vf = $settings['dpdk_on_vf']
$compute_dpdk_enabled = $global_dpdk_enabled and 'dpdk' in hiera_array('roles')
# Package override
$patch_nova = pick($settings['patch_nova'], false)
$install_contrail_qemu_lv = pick($settings['install_contrail_qemu_lv'], false )

View File

@ -0,0 +1 @@
SUBSYSTEM=="net", ACTION=="add", KERNELS=="<%= @dpdk_dev_pci %>", NAME="<%= @dpdk_dev_name %>", RUN+="/bin/ip link set dev %k address <%= @dpdk_dev_mac %>"

View File

@ -6,8 +6,7 @@ log_local=1
headless_mode=true
<%- if scope.lookupvar('contrail::compute_dpdk_enabled') == true then -%>
platform=dpdk
physical_interface_address=<%= scope.lookupvar('contrail::phys_dev_pci') %>
<% phys_dev_fact = scope.lookupvar('contrail::phys_dev').gsub(/[^a-z0-9_]/i,"_") -%>
physical_interface_address=<%= @dpdk_dev_pci %>
physical_interface_mac=<%= @dpdk_dev_mac %>
<%- end -%>
[DISCOVERY]
@ -24,7 +23,7 @@ control_network_ip=<%= scope.lookupvar('contrail::address') %>
[VIRTUAL-HOST-INTERFACE]
name=vhost0
ip=<%= scope.lookupvar('contrail::address') %>/<%= scope.lookupvar('contrail::netmask_short') %>
physical_interface=<%= scope.lookupvar('contrail::phys_dev') %>
physical_interface=<%= @phys_dev %>
<% if scope.lookupvar('contrail::gateway') != :undef -%>
gateway=<%= scope.lookupvar('contrail::gateway') %>
<% end -%>