2M hugepage appears to be larger than the context help

On a newly installed system, the 2M huge page value is set by
calculating 100% remaining available memory on the initial boot.
The remaining memory in subsequent boot could be less than the
initial boot, therefore the recalculated 2M Max value (shown in the
context help) can be less than the previous set 2M huge pages.

This update calculates the initial 2M huge page value using 90%
remaining memory during the initial boot. In addition, it adds a
notification to force sysinv-agent report memory when a host
is locked. This prevents the audit delay causes the memory info not
updated on time when the user attempts to modify the memory. The
subsequent audit report is ignored when the host is locked. In this
way host memory modify and host unlock semantic check use
the same memory info as each audit could provide slightly different
available memory value (depending on the activities performed on
the system).

Closes-Bug: # 1794547

Change-Id: If3884946365254fc6be16f24df03dbd090454a76
Signed-off-by: Tao Liu <tao.liu@windriver.com>
This commit is contained in:
Tao Liu 2018-10-02 11:31:45 -04:00
parent 3290e3221b
commit 121c76760e
6 changed files with 70 additions and 4 deletions

View File

@ -1771,3 +1771,19 @@ class AgentManager(service.PeriodicService):
return self._idisk_operator.disk_format_gpt(host_uuid,
idisk_dict,
is_cinder_device)
def update_host_memory(self, context, host_uuid):
"""update the host memory
:param context: an admin context
:param host_uuid: ihost uuid unique id
:return: None
"""
if self._ihost_uuid and self._ihost_uuid == host_uuid:
rpcapi = conductor_rpcapi.ConductorAPI(
topic=conductor_rpcapi.MANAGER_TOPIC)
memory = self._inode_operator.inodes_get_imemory()
rpcapi.imemory_update_by_ihost(context,
self._ihost_uuid,
memory,
force_update=True)

View File

@ -502,9 +502,10 @@ class NodeOperator(object):
'vm_hugepages_possible_1G': max_vm_pages_1G,
})
# calculate 100% 2M pages if it is initial report and the huge
# calculate 90% 2M pages if it is initial report and the huge
# pages have not been allocated
if initial_report:
max_vm_pages_2M = max_vm_pages_2M * 0.9
Total_HP_MiB += int(max_vm_pages_2M * (SZ_2M_Ki / Ki))
Free_HP_MiB = Total_HP_MiB
attr.update({

View File

@ -271,3 +271,14 @@ class AgentAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
host_uuid=host_uuid,
idisk_dict=idisk_dict,
is_cinder_device=is_cinder_device))
def update_host_memory(self, context, host_uuid):
"""Asynchronously, have the agent to send host memory update
:param context: request context.
:param host_uuid: ihost uuid unique id
:returns: pass or fail
"""
return self.fanout_cast(context,
self.make_msg('update_host_memory',
host_uuid=host_uuid))

View File

@ -2140,6 +2140,12 @@ class HostController(rest.RestController):
LOG.info("host %s %s patch" % (ihost_obj.hostname,
log_end))
if ('administrative' in hostupdate.delta and
hostupdate.ihost_patch['administrative'] ==
constants.ADMIN_LOCKED):
LOG.info("Update host memory for (%s)" % ihost_obj['hostname'])
pecan.request.rpcapi.update_host_memory(pecan.request.context,
ihost_obj['uuid'])
return Host.convert_with_links(ihost_obj)
def _vim_host_add(self, ihost):

View File

@ -2744,7 +2744,8 @@ class ConductorManager(service.PeriodicService):
return {'platform_reserved_mib': reserved} if reserved else {}
def imemory_update_by_ihost(self, context,
ihost_uuid, imemory_dict_array):
ihost_uuid, imemory_dict_array,
force_update):
"""Create or update imemory for an ihost with the supplied data.
This method allows records for memory for ihost to be created,
@ -2753,6 +2754,7 @@ class ConductorManager(service.PeriodicService):
:param context: an admin context
:param ihost_uuid: ihost uuid unique id
:param imemory_dict_array: initial values for cpu objects
:param: force_update: force host memory update
:returns: pass or fail
"""
@ -2763,6 +2765,12 @@ class ConductorManager(service.PeriodicService):
LOG.exception("Invalid ihost_uuid %s" % ihost_uuid)
return
if ihost['administrative'] == constants.ADMIN_LOCKED and \
ihost['invprovision'] == constants.PROVISIONED and \
not force_update:
LOG.debug("Ignore the host memory audit after the host is locked")
return
forihostid = ihost['id']
ihost_inodes = self.dbapi.inode_get_by_ihost(ihost_uuid)
@ -10212,3 +10220,13 @@ class ConductorManager(service.PeriodicService):
}
body['metadata']['labels'].update(label_dict)
self._kube.kube_patch_node(host.hostname, body)
def update_host_memory(self, context, host_uuid):
try:
host = self.dbapi.ihost_get(host_uuid)
except exception.ServerNotFound:
LOG.error("Cannot find host by id %s" % host_uuid)
return
rpcapi = agent_rpcapi.AgentAPI()
rpcapi.update_host_memory(context, host.uuid)

View File

@ -308,7 +308,8 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
force_grub_update=force_grub_update))
def imemory_update_by_ihost(self, context,
ihost_uuid, imemory_dict_array):
ihost_uuid, imemory_dict_array,
force_update=False):
"""Create or update memory for an ihost with the supplied data.
This method allows records for memory for ihost to be created,
@ -317,13 +318,15 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
:param context: an admin context
:param ihost_uuid: ihost uuid unique id
:param imemory_dict_array: initial values for memory objects
:param force_update: force a memory update
:returns: pass or fail
"""
return self.call(context,
self.make_msg('imemory_update_by_ihost',
ihost_uuid=ihost_uuid,
imemory_dict_array=imemory_dict_array))
imemory_dict_array=imemory_dict_array,
force_update=force_update))
def idisk_update_by_ihost(self, context,
ihost_uuid, idisk_dict_array):
@ -1648,3 +1651,14 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
self.make_msg('update_kubernetes_label',
host_uuid=host_uuid,
label_dict=label_dict))
def update_host_memory(self, context, host_uuid):
"""Asynchronously, have a conductor update the host memory
:param context: request context.
:param host_uuid: duuid or id of the host.
"""
LOG.info("ConductorApi.update_host_memory: sending"
" host memory update request to conductor")
return self.cast(context, self.make_msg('update_host_memory',
host_uuid=host_uuid))