v1: add 2 host node memory cases and update conf - node_mem_param: tuning host node memory parameters - node_memory: get host node memory info, including host free memory, node free memory and node memory stats - numa_param conf is updated with the 2 new cases v2: node_mem_param: polish codes with better readability node_memory: direct fetch info in /sys/devices/system/node/node* other than using command 'numastat' Signed-off-by: Wayne Sun <gsun@xxxxxxxxxx> --- cases/numa_param.conf | 8 ++++ repos/numa/node_mem_param.py | 81 ++++++++++++++++++++++++++++++++ repos/numa/node_memory.py | 107 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 repos/numa/node_mem_param.py create mode 100644 repos/numa/node_memory.py diff --git a/cases/numa_param.conf b/cases/numa_param.conf index 64268a3..515fb1f 100644 --- a/cases/numa_param.conf +++ b/cases/numa_param.conf @@ -1,3 +1,11 @@ +numa:node_memory + +numa:node_mem_param + shm_pages_to_scan + 200 + shm_sleep_millisecs + 20 + domain:install_linux_cdrom guestname $defaultname diff --git a/repos/numa/node_mem_param.py b/repos/numa/node_mem_param.py new file mode 100644 index 0000000..86242b1 --- /dev/null +++ b/repos/numa/node_mem_param.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# Test tuning host node memory parameters + +import libvirt +from libvirt import libvirtError + +from src import sharedmod + +required_params = () +optional_params = {"shm_pages_to_scan": 100, + "shm_sleep_millisecs": 20, + "shm_merge_across_nodes": 1 + } + +KSM_PATH = "/sys/kernel/mm/ksm/" + +def node_mem_param(params): + """test set host node memory parameters + """ + logger = params['logger'] + shm_pages_to_scan = params.get('shm_pages_to_scan') + shm_sleep_millisecs = params.get('shm_sleep_millisecs') + shm_merge_across_nodes = params.get('shm_merge_across_nodes') + + if not shm_pages_to_scan \ + and not shm_sleep_millisecs \ + and not shm_merge_across_nodes: + logger.error("given param is none") + return 1 + + param_dict = {} + for i in optional_params.keys(): + if eval(i): + param_dict[i] = int(eval(i)) + + logger.info("the given param dict is: %s" % param_dict) + + conn = sharedmod.libvirtobj['conn'] + + try: + logger.info("get host node memory parameters") + mem_pre = conn.getMemoryParameters(0) + logger.info("host node memory parameters is: %s" % mem_pre) + + logger.info("set host node memory parameters with given param %s" % + param_dict) + conn.setMemoryParameters(param_dict, 0) + logger.info("set host node memory parameters done") + + logger.info("get host node memory parameters") + mem_pos = conn.getMemoryParameters(0) + logger.info("host node memory parameters is: %s" % mem_pos) + + for i in param_dict.keys(): + if not mem_pos[i] == param_dict[i]: + logger.error("%s is not set as expected" % i) + + logger.info("node memory parameters is set as expected") + + logger.info("check tuning detail under %s" % KSM_PATH) + + ksm_dict = {} + for i in param_dict.keys(): + path = "%s%s" % (KSM_PATH, i[4:]) + f = open(path) + ret = int(f.read().split('\n')[0]) + f.close() + logger.info("%s value is: %s" % (path, ret)) + ksm_dict[i] = ret + + if ksm_dict == param_dict: + logger.info("tuning detail under %s is expected" % KSM_PATH) + else: + logger.error("check with tuning detail under %s failed" % KSM_PATH) + return 1 + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return 1 + + return 0 diff --git a/repos/numa/node_memory.py b/repos/numa/node_memory.py new file mode 100644 index 0000000..0241f3c --- /dev/null +++ b/repos/numa/node_memory.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python +# Test get host node memory info, including host free +# memory, node free memory and node memory stats. + +import math + +import libvirt +from libvirt import libvirtError + +from src import sharedmod +from utils import utils + +required_params = () +optional_params = {} + +NODE_MEMINFO_PATH = "/sys/devices/system/node/node*/meminfo" + +def node_memory(params): + """test get host node memory info + """ + logger = params['logger'] + + cmd = "lscpu|grep 'NUMA node(s)'" + ret, output = utils.exec_cmd(cmd, shell=True) + node_num = int(output[0].split(' ')[-1]) + logger.info("host total nodes number is: %s" % node_num) + + conn = sharedmod.libvirtobj['conn'] + + cmd = "grep 'MemFree' %s" % NODE_MEMINFO_PATH + node_mem = [] + free_total = 0 + ret, out = utils.exec_cmd(cmd, shell=True) + for i in range(node_num): + mem_free = int(out[i].split()[-2]) + node_mem.append(mem_free) + free_total += mem_free + + try: + logger.info("get host total free memory") + mem = conn.getFreeMemory()/1024 + logger.info("host free memory total is: %s KiB" % mem) + logger.info("free memory collected in %s is: %s KiB" % + (NODE_MEMINFO_PATH, free_total)) + + if math.fabs(mem - free_total) > 1024: + logger.error("free memory mismatch with info collected in %s" % + NODE_MEMINFO_PATH) + return 1 + else: + logger.info("get host free memory succeed") + + logger.info("get free memory of nodes") + ret = conn.getCellsFreeMemory(0, node_num) + mem_list = [i/1024 for i in ret] + logger.info("node free memory list is: %s" % mem_list) + logger.info("node free memory list collected in %s is: %s" % + (NODE_MEMINFO_PATH, node_mem)) + + for i in range(node_num): + if math.fabs(mem_list[i] - node_mem[i]) > 1024: + path = NODE_MEMINFO_PATH.replace('*', '%s') % i + logger.error("node %s free memory mismatch with collected in %s" + % (i, path)) + return 1 + + logger.info("get node free memory succeed") + + logger.info("get node memory stats") + node_dict = {} + for i in range(node_num): + ret = conn.getMemoryStats(i, 0) + node_dict[i] = ret + logger.info("node %s memory stats is: %s" % (i, node_dict[i])) + + node_tmp = {} + cmd_new = "grep 'MemTotal' %s" % NODE_MEMINFO_PATH + ret, out_free = utils.exec_cmd(cmd, shell=True) + ret, out_total = utils.exec_cmd(cmd_new, shell=True) + for i in range(node_num): + dict_tmp = {} + path = NODE_MEMINFO_PATH.replace('*', '%s') % i + dict_tmp['free'] = int(out_free[i].split()[-2]) + dict_tmp['total'] = int(out_total[i].split()[-2]) + node_tmp[i] = dict_tmp + logger.info("node %s memory stats collected in %s is: %s" % + (i, path, node_tmp[i])) + + for i in range(node_num): + path = NODE_MEMINFO_PATH.replace('*', '%s') % i + if math.fabs(node_tmp[i]['total'] - node_dict[i]['total']) > 1024: + logger.error("node %s total memory is mismatch with %s" % + (i, path)) + return 1 + + if math.fabs(node_tmp[i]['free'] - node_dict[i]['free']) > 1024: + logger.error("node %s free memory is mismatch with %s" % + (i, path)) + return 1 + + logger.info("get node memory stats succeed") + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return 1 + + return 0 -- 1.8.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list