config/puppet-manifests/src/modules/platform/manifests/compute.pp

316 lines
8.7 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"
if $low_wakeup_cpus != '""' {
# 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,
}
}
if $hight_wakeup_cpus != '""' {
#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
}