Merge "fix hugepage allocation overflow"

This commit is contained in:
Zuul 2019-07-12 16:33:01 +00:00 committed by Gerrit Code Review
commit e5203ea4f1
2 changed files with 79 additions and 35 deletions

View File

@ -3591,8 +3591,15 @@ class HostController(rest.RestController):
elif m.vm_hugepages_nr_1G:
allocated += constants.MIB_1G * m.vm_hugepages_nr_1G
LOG.debug("MemTotal=%s allocated=%s" % (memtotal, allocated))
if memtotal < allocated:
LOG.info("Memory: Total=%s MiB, Allocated=%s MiB, "
"2M: %s pages %s pages pending, "
"1G: %s pages %s pages pending"
% (memtotal, allocated,
m.vm_hugepages_possible_2M, m.vm_hugepages_nr_2M_pending,
m.vm_hugepages_possible_1G, m.vm_hugepages_nr_1G_pending))
if (memtotal < allocated or
m.vm_hugepages_possible_2M < m.vm_hugepages_nr_2M_pending or
m.vm_hugepages_possible_1G < m.vm_hugepages_nr_1G_pending):
msg = (_("Rejected: Total allocated memory exceeds the total memory of "
"%(host)s numa node %(node)s "
) %
@ -3704,19 +3711,46 @@ class HostController(rest.RestController):
if m.vm_hugepages_nr_1G_pending is not None \
else m.vm_hugepages_nr_1G
hp_possible_mib = (m.node_memtotal_mib -
m.platform_reserved_mib)
vs_mem_mib = (vs_hugepages_nr *
m.vswitch_hugepages_size_mib)
vm_mem_mib = hp_possible_mib - vs_mem_mib
vm_mem_mib_possible = m.vm_hugepages_possible_2M * constants.MIB_2M
LOG.info("host(%s) node(%d): vm_mem_mib=%d,"
"vm_mem_mib_possible (from agent) = %d"
% (ihost['hostname'], node['id'], vm_mem_mib,
vm_mem_mib_possible))
# vm_mem_mib should not be negative
if vm_mem_mib < constants.MIB_2M:
vm_mem_mib = 0
# worker_reserved.conf might have different setting
# during upgrading or patching
if vm_mem_mib > vm_mem_mib_possible:
vm_mem_mib = vm_mem_mib_possible
# Current value might not be suitable after upgrading or
# patching
if vm_hugepages_nr_2M > int((vm_mem_mib * 0.9) /
constants.MIB_2M):
vm_hugepages_nr_2M = int((vm_mem_mib * 0.9) /
constants.MIB_2M)
value.update({'vm_hugepages_nr_2M': vm_hugepages_nr_2M})
# calculate 90% 2M pages if the huge pages have not been
# allocated and the compute label is set
if cutils.has_openstack_compute(labels) and \
vm_hugepages_nr_2M == 0 and \
vm_hugepages_nr_1G == 0 and \
vm_hugepages_nr_2M == 0 and \
vm_hugepages_nr_1G == 0 and \
vm_mem_mib > 0 and \
cutils.is_default_huge_pages_required(ihost):
vm_hugepages_nr_2M = int(m.vm_hugepages_possible_2M * 0.9)
vm_hugepages_nr_2M = int((vm_mem_mib * 0.9) /
constants.MIB_2M)
value.update({'vm_hugepages_nr_2M': vm_hugepages_nr_2M})
vm_hugepages_4K = \
(m.node_memtotal_mib - m.platform_reserved_mib)
vm_hugepages_4K -= \
(vs_hugepages_nr * m.vswitch_hugepages_size_mib)
vm_hugepages_4K = vm_mem_mib
vm_hugepages_4K -= \
(constants.MIB_2M * vm_hugepages_nr_2M)
vm_hugepages_4K -= \

View File

@ -420,8 +420,11 @@ class MemoryController(rest.RestController):
try:
# Semantics checks and update hugepage memory accounting
patch = _check_huge_values(rpc_port, patch,
vm_hugepages_nr_2M_pending, vm_hugepages_nr_1G_pending,
vswitch_hugepages_reqd, vswitch_hugepages_size_mib)
vm_hugepages_nr_2M_pending,
vm_hugepages_nr_1G_pending,
vswitch_hugepages_reqd,
vswitch_hugepages_size_mib,
platform_reserved_mib)
except wsme.exc.ClientSideError as e:
inode = pecan.request.dbapi.inode_get(inode_id=rpc_port.forinodeid)
numa_node = inode.numa_node
@ -519,8 +522,11 @@ def _update(mem_uuid, mem_values):
# Semantics checks and update hugepage memory accounting
mem_values = _check_huge_values(rpc_port, mem_values,
vm_hugepages_nr_2M_pending, vm_hugepages_nr_1G_pending,
vswitch_hugepages_reqd, vswitch_hugepages_size_mib)
vm_hugepages_nr_2M_pending,
vm_hugepages_nr_1G_pending,
vswitch_hugepages_reqd,
vswitch_hugepages_size_mib,
platform_reserved_mib)
# Semantics checks for platform memory
_check_memory(rpc_port, host_id, platform_reserved_mib,
@ -549,16 +555,6 @@ def _check_memory(rpc_port, ihost, platform_reserved_mib=None,
vm_hugepages_nr_2M_pending=None, vm_hugepages_nr_1G_pending=None,
vswitch_hugepages_reqd=None, vswitch_hugepages_size_mib=None):
if platform_reserved_mib:
# Check for invalid characters
try:
val = int(platform_reserved_mib)
except ValueError:
raise wsme.exc.ClientSideError((
"Platform memory must be a number"))
if val < 0:
raise wsme.exc.ClientSideError((
"Platform memory must be greater than zero"))
# Check for lower limit
inode_id = rpc_port['forinodeid']
inode = pecan.request.dbapi.inode_get(inode_id)
@ -636,7 +632,8 @@ def _check_memory(rpc_port, ihost, platform_reserved_mib=None,
def _check_huge_values(rpc_port, patch, vm_hugepages_nr_2M=None,
vm_hugepages_nr_1G=None, vswitch_hugepages_reqd=None,
vswitch_hugepages_size_mib=None):
vswitch_hugepages_size_mib=None,
platform_reserved_mib=None):
if rpc_port['vm_hugepages_use_1G'] == 'False':
vs_hp_size = vswitch_hugepages_size_mib
@ -741,16 +738,33 @@ def _check_huge_values(rpc_port, patch, vm_hugepages_nr_2M=None,
vs_hp_size_mib = constants.MIB_2M
vs_hp_reqd_mib = new_vs_pages * vs_hp_size_mib
# The size of possible hugepages is the size of reported possible
# vm pages + the reported current number of vswitch pages.
# The size of possible hugepages is the node mem total - platform reserved
base_mem_mib = rpc_port['platform_reserved_mib']
if platform_reserved_mib:
# Check for invalid characters
try:
val = int(platform_reserved_mib)
except ValueError:
raise wsme.exc.ClientSideError((
"Platform memory must be a number"))
if val < 0:
raise wsme.exc.ClientSideError((
"Platform memory must be greater than zero"))
base_mem_mib = int(platform_reserved_mib)
hp_possible_mib = rpc_port['node_memtotal_mib'] - base_mem_mib
if vs_hp_size_mib == constants.MIB_2M:
hp_possible_mib = int(
agent_hp_possible_mib = int(
rpc_port.get('vm_hugepages_possible_2M', 0) +
rpc_port.get('vswitch_hugepages_nr', 0)) * vs_hp_size_mib
if hp_possible_mib > agent_hp_possible_mib:
hp_possible_mib = agent_hp_possible_mib
elif vs_hp_size_mib == constants.MIB_1G:
hp_possible_mib = int(
rpc_port.get('vm_hugepages_possible_1G', 0) +
rpc_port.get('vswitch_hugepages_nr', 0)) * vs_hp_size_mib
agent_hp_possible_mib = int(
rpc_port.get('vm_hugepages_possible_1G', 0) +
rpc_port.get('vswitch_hugepages_nr', 0)) * vs_hp_size_mib
if hp_possible_mib > agent_hp_possible_mib:
hp_possible_mib = agent_hp_possible_mib
# Total requested huge pages
hp_requested_mib = vm_hp_2M_reqd_mib + vm_hp_1G_reqd_mib + vs_hp_reqd_mib
@ -762,12 +776,8 @@ def _check_huge_values(rpc_port, patch, vm_hugepages_nr_2M=None,
vm_max_hp_1G = ((hp_possible_mib - vs_hp_reqd_mib - vm_hp_2M_reqd_mib)
/ constants.MIB_1G)
if vm_max_hp_2M < 0:
vm_max_hp_2M = 0
if vm_max_hp_1G < 0:
vm_max_hp_1G = 0
if new_2M_pages > 0 and new_1G_pages > 0:
msg = _("For a requested vSwitch hugepage allocation of %s MiB, "
"max 1G pages is %s when 2M is %s, or "
"max 2M pages is %s when 1G is %s." % (