2b82117b33
By default, libvirt and openstack-helm expect the hugepage mountpoints to be under /dev, while we currently use mountpoints under /mnt. To get containerized libvirt working, add a set of mountpoints under /dev. Later on we can switch our existing code over to use the new mountpoints and remove the mounts under /mnt. Just to make things interesting, the libvirt helm chart also expects the default hugepage size (2M in our case) to be mounted at /dev/hugepages, so we add another mountpoint for that pagesize. Ideally we'd upstream a helm chart change to auto-detect the mountpoint, at which time we could remove this hack. Change-Id: I88baa169dd357e73295aa32f4044da35e3a7fd6a Story: 2003909 Task: 27081 Signed-off-by: Chris Friesen <chris.friesen@windriver.com>
312 lines
8.6 KiB
Puppet
312 lines
8.6 KiB
Puppet
class platform::compute::params (
|
|
$compute_cpu_list = '',
|
|
$platform_cpu_list = '',
|
|
$reserved_vswitch_cores = '',
|
|
$reserved_platform_cores = '',
|
|
$compute_base_reserved = '',
|
|
$compute_vswitch_reserved = '',
|
|
) { }
|
|
|
|
class platform::compute::config
|
|
inherits ::platform::compute::params {
|
|
|
|
file { "/etc/nova/compute_reserved.conf":
|
|
ensure => 'present',
|
|
replace => true,
|
|
content => template('platform/compute_reserved.conf.erb')
|
|
}
|
|
}
|
|
|
|
class platform::compute::grub::params (
|
|
$n_cpus = '',
|
|
$cpu_options = '',
|
|
$m_hugepages = 'hugepagesz=2M hugepages=0',
|
|
$default_pgsz = 'default_hugepagesz=2M',
|
|
$keys = ['kvm-intel.eptad', 'default_hugepagesz', 'hugepagesz', 'hugepages', 'isolcpus', 'nohz_full', 'rcu_nocbs', 'kthread_cpus', 'irqaffinity'],
|
|
) {
|
|
|
|
if $::is_broadwell_processor {
|
|
$eptad = 'kvm-intel.eptad=0'
|
|
} else {
|
|
$eptad = ''
|
|
}
|
|
|
|
if $::is_gb_page_supported {
|
|
$gb_hugepages = "hugepagesz=1G hugepages=$::number_of_numa_nodes"
|
|
} else {
|
|
$gb_hugepages = ''
|
|
}
|
|
|
|
$grub_updates = strip("${eptad} ${$gb_hugepages} ${m_hugepages} ${default_pgsz} ${cpu_options}")
|
|
}
|
|
|
|
class platform::compute::grub::update
|
|
inherits ::platform::compute::grub::params {
|
|
|
|
notice("Updating grub configuration")
|
|
|
|
$to_be_removed = join($keys, " ")
|
|
exec { "Remove the cpu arguments":
|
|
command => "grubby --update-kernel=ALL --remove-args='$to_be_removed'",
|
|
} ->
|
|
exec { "Add the cpu arguments":
|
|
command => "grubby --update-kernel=ALL --args='$grub_updates'",
|
|
}
|
|
}
|
|
|
|
class platform::compute::grub::recovery {
|
|
|
|
notice("Update Grub and Reboot")
|
|
|
|
class {'platform::compute::grub::update': } -> Exec['reboot-recovery']
|
|
|
|
exec { "reboot-recovery":
|
|
command => "reboot",
|
|
}
|
|
}
|
|
|
|
class platform::compute::grub::audit
|
|
inherits ::platform::compute::grub::params {
|
|
|
|
if ! str2bool($::is_initial_config_primary) {
|
|
|
|
notice("Audit CPU and Grub Configuration")
|
|
|
|
$expected_n_cpus = $::number_of_logical_cpus
|
|
$n_cpus_ok = ("$n_cpus" == "$expected_n_cpus")
|
|
|
|
$cmd_ok = check_grub_config($grub_updates)
|
|
|
|
if $cmd_ok and $n_cpus_ok {
|
|
$ensure = present
|
|
notice("CPU and Boot Argument audit passed.")
|
|
} else {
|
|
$ensure = absent
|
|
if !$cmd_ok {
|
|
notice("Kernel Boot Argument Mismatch")
|
|
include ::platform::compute::grub::recovery
|
|
}
|
|
}
|
|
|
|
file { "/var/run/compute_huge_goenabled":
|
|
ensure => $ensure,
|
|
owner => 'root',
|
|
group => 'root',
|
|
mode => '0644',
|
|
}
|
|
}
|
|
}
|
|
|
|
class platform::compute::grub::runtime {
|
|
include ::platform::compute::grub::update
|
|
}
|
|
|
|
# Mounts virtual hugetlbfs filesystems for each supported page size
|
|
class platform::compute::hugetlbf {
|
|
|
|
if str2bool($::is_hugetlbfs_enabled) {
|
|
|
|
$fs_list = generate("/bin/bash", "-c", "ls -1d /sys/kernel/mm/hugepages/hugepages-*")
|
|
$array = split($fs_list, '\n')
|
|
$array.each | String $val | {
|
|
$page_name = generate("/bin/bash", "-c", "basename $val")
|
|
$page_size = strip(regsubst($page_name, 'hugepages-', ''))
|
|
$hugemnt ="/mnt/huge-$page_size"
|
|
$options = "pagesize=${page_size}"
|
|
|
|
# TODO: Once all the code is switched over to use the /dev
|
|
# mount point we can get rid of this mount point.
|
|
notice("Mounting hugetlbfs at: $hugemnt")
|
|
exec { "create $hugemnt":
|
|
command => "mkdir -p ${hugemnt}",
|
|
onlyif => "test ! -d ${hugemnt}",
|
|
} ->
|
|
mount { "${hugemnt}":
|
|
name => "${hugemnt}",
|
|
device => 'none',
|
|
fstype => 'hugetlbfs',
|
|
ensure => 'mounted',
|
|
options => "${options}",
|
|
atboot => 'yes',
|
|
remounts => true,
|
|
}
|
|
|
|
# The libvirt helm chart expects hugepages to be mounted
|
|
# under /dev so let's do that.
|
|
$hugemnt2 ="/dev/huge-$page_size"
|
|
notice("Mounting hugetlbfs at: $hugemnt2")
|
|
file { "${hugemnt2}":
|
|
ensure => 'directory',
|
|
owner => 'root',
|
|
group => 'root',
|
|
mode => '0755',
|
|
}->
|
|
mount { "${hugemnt2}":
|
|
name => "${hugemnt2}",
|
|
device => 'none',
|
|
fstype => 'hugetlbfs',
|
|
ensure => 'mounted',
|
|
options => "${options}",
|
|
atboot => 'yes',
|
|
remounts => true,
|
|
}
|
|
}
|
|
|
|
# The libvirt helm chart also assumes that the default hugepage size
|
|
# will be mounted at /dev/hugepages so let's make that happen too.
|
|
# Once we upstream a fix to the helm chart to automatically determine
|
|
# the mountpoint then we can remove this.
|
|
$page_size = '2M'
|
|
$hugemnt ="/dev/hugepages"
|
|
$options = "pagesize=${page_size}"
|
|
|
|
notice("Mounting hugetlbfs at: $hugemnt")
|
|
exec { "create $hugemnt":
|
|
command => "mkdir -p ${hugemnt}",
|
|
onlyif => "test ! -d ${hugemnt}",
|
|
} ->
|
|
mount { "${hugemnt}":
|
|
name => "${hugemnt}",
|
|
device => 'none',
|
|
fstype => 'hugetlbfs',
|
|
ensure => 'mounted',
|
|
options => "${options}",
|
|
atboot => 'yes',
|
|
remounts => true,
|
|
}
|
|
}
|
|
}
|
|
|
|
class platform::compute::hugepage::params (
|
|
$nr_hugepages_2M = undef,
|
|
$nr_hugepages_1G = undef,
|
|
$vswitch_2M_pages = '',
|
|
$vswitch_1G_pages = '',
|
|
$vm_4K_pages = '',
|
|
$vm_2M_pages = '',
|
|
$vm_1G_pages = '',
|
|
) {}
|
|
|
|
|
|
define allocate_pages (
|
|
$path,
|
|
$page_count,
|
|
) {
|
|
exec { "Allocate ${page_count} ${path}":
|
|
command => "echo $page_count > $path",
|
|
onlyif => "test -f $path",
|
|
}
|
|
}
|
|
|
|
# Allocates HugeTLB memory according to the attributes specified in the
|
|
# nr_hugepages_2M and nr_hugepages_1G
|
|
class platform::compute::allocate
|
|
inherits ::platform::compute::hugepage::params {
|
|
|
|
# determine the node file system
|
|
if str2bool($::is_per_numa_supported) {
|
|
$nodefs = '/sys/devices/system/node'
|
|
} else {
|
|
$nodefs = '/sys/kernel/mm'
|
|
}
|
|
|
|
if $nr_hugepages_2M != undef {
|
|
$nr_hugepages_2M_array = regsubst($nr_hugepages_2M, '[\(\)\"]', '', 'G').split(' ')
|
|
$nr_hugepages_2M_array.each | String $val | {
|
|
$per_node_2M = $val.split(':')
|
|
if size($per_node_2M)== 3 {
|
|
$node = $per_node_2M[0]
|
|
$page_size = $per_node_2M[1]
|
|
allocate_pages { "Start ${node} ${page_size}":
|
|
path => "${nodefs}/${node}/hugepages/hugepages-${page_size}/nr_hugepages",
|
|
page_count => $per_node_2M[2],
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if $nr_hugepages_1G != undef {
|
|
$nr_hugepages_1G_array = regsubst($nr_hugepages_1G , '[\(\)\"]', '', 'G').split(' ')
|
|
$nr_hugepages_1G_array.each | String $val | {
|
|
$per_node_1G = $val.split(':')
|
|
if size($per_node_1G)== 3 {
|
|
$node = $per_node_1G[0]
|
|
$page_size = $per_node_1G[1]
|
|
allocate_pages { "Start ${node} ${page_size}":
|
|
path => "${nodefs}/${node}/hugepages/hugepages-${page_size}/nr_hugepages",
|
|
page_count => $per_node_1G[2],
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class platform::compute::extend
|
|
inherits ::platform::compute::hugepage::params {
|
|
|
|
# nova-compute reads on init, extended nova compute options
|
|
# used with nova accounting
|
|
file { "/etc/nova/compute_extend.conf":
|
|
ensure => 'present',
|
|
replace => true,
|
|
content => template('platform/compute_extend.conf.erb')
|
|
}
|
|
}
|
|
|
|
# Mount resctrl to allow Cache Allocation Technology per VM
|
|
class platform::compute::resctrl {
|
|
|
|
if str2bool($::is_resctrl_supported) {
|
|
mount { "/sys/fs/resctrl":
|
|
name => '/sys/fs/resctrl',
|
|
device => 'resctrl',
|
|
fstype => 'resctrl',
|
|
ensure => 'mounted',
|
|
atboot => 'yes',
|
|
remounts => true,
|
|
}
|
|
}
|
|
}
|
|
|
|
# Set Power Management QoS resume latency constraints for CPUs.
|
|
# The PM QoS resume latency limit is set to shallow C-state for vswitch CPUs.
|
|
# All other CPUs are allowed to go to the deepest C-state available.
|
|
class platform::compute::pmqos (
|
|
$low_wakeup_cpus = '',
|
|
$hight_wakeup_cpus = '',
|
|
) {
|
|
|
|
if str2bool($::is_compute_subfunction) and str2bool($::is_lowlatency_subfunction) {
|
|
|
|
$script = "/usr/bin/set-cpu-wakeup-latency.sh"
|
|
|
|
# Set low wakeup latency (shallow C-state) for vswitch CPUs using PM QoS interface
|
|
exec { "low-wakeup-latency":
|
|
command => "${script} low ${low_wakeup_cpus}",
|
|
onlyif => "test -f ${script}",
|
|
logoutput => true,
|
|
}
|
|
|
|
#Set high wakeup latency (deep C-state) for non-vswitch CPUs using PM QoS interface
|
|
exec { "high-wakeup-latency":
|
|
command => "${script} high ${hight_wakeup_cpus}",
|
|
onlyif => "test -f ${script}",
|
|
logoutput => true,
|
|
}
|
|
}
|
|
}
|
|
|
|
class platform::compute {
|
|
|
|
Class[$name] -> Class['::platform::vswitch']
|
|
Class[$name] -> Class['::nova::compute']
|
|
|
|
require ::platform::compute::grub::audit
|
|
require ::platform::compute::hugetlbf
|
|
require ::platform::compute::allocate
|
|
require ::platform::compute::pmqos
|
|
require ::platform::compute::resctrl
|
|
require ::platform::compute::extend
|
|
require ::platform::compute::config
|
|
}
|