On 2012年10月15日 14:55, Daniel Veillard wrote: > On Fri, Oct 12, 2012 at 04:25:42PM +0800, Osier Yang wrote: >> Upstream kernel introduced new sysfs knob "merge_across_nodes" to >> specify if pages from different numa nodes can be merged. When set >> to 0, only pages which physically reside in the memory area of >> same NUMA node can be merged. When set to 1, pages from all nodes >> can be merged. >> >> This patch supports the tuning by adding new param field >> "shm_merge_across_nodes". >> --- >> include/libvirt/libvirt.h.in | 12 ++++++++++++ >> src/nodeinfo.c | 28 +++++++++++++++++++++++++--- >> tools/virsh-host.c | 20 ++++++++++++++++++++ >> tools/virsh.pod | 5 ++++- >> 4 files changed, 61 insertions(+), 4 deletions(-) >> >> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in >> index a4e8ca9..1490558 100644 >> --- a/include/libvirt/libvirt.h.in >> +++ b/include/libvirt/libvirt.h.in >> @@ -4490,6 +4490,18 @@ typedef virMemoryParameter *virMemoryParameterPtr; >> */ >> # define VIR_NODE_MEMORY_SHARED_FULL_SCANS "shm_full_scans" >> >> +/* VIR_NODE_MEMORY_SHARED_MERGE_ACROSS_NODES: >> + * >> + * Macro for typed parameter that represents whether pages from >> + * different NUMA nodes can be merged. The parameter has type int, >> + * when its value is 0, only pages which physically reside in the >> + * memory area of same NUMA node are merged; When its value is 1, >> + * pages from all nodes can be merged. Other values are reserved >> + * for future use. >> + */ >> +# define VIR_NODE_MEMORY_SHARED_MERGE_ACROSS_NODES "shm_merge_across_nodes" >> + >> + >> int virNodeGetMemoryParameters(virConnectPtr conn, >> virTypedParameterPtr params, >> int *nparams, >> diff --git a/src/nodeinfo.c b/src/nodeinfo.c >> index c0e60d8..8f96b8b 100644 >> --- a/src/nodeinfo.c >> +++ b/src/nodeinfo.c >> @@ -1005,6 +1005,8 @@ nodeSetMemoryParameters(virConnectPtr conn ATTRIBUTE_UNUSED, >> VIR_TYPED_PARAM_UINT, >> VIR_NODE_MEMORY_SHARED_SLEEP_MILLISECS, >> VIR_TYPED_PARAM_UINT, >> + VIR_NODE_MEMORY_SHARED_MERGE_ACROSS_NODES, >> + VIR_TYPED_PARAM_UINT, >> NULL)< 0) >> return -1; >> >> @@ -1025,6 +1027,13 @@ nodeSetMemoryParameters(virConnectPtr conn ATTRIBUTE_UNUSED, >> /* Out of memory */ >> if (ret == -2) >> return -1; >> + } else if (STREQ(param->field, >> + VIR_NODE_MEMORY_SHARED_MERGE_ACROSS_NODES)) { >> + ret = nodeSetMemoryParameterValue("merge_across_nodes", param); >> + >> + /* Out of memory */ >> + if (ret == -2) >> + return -1; >> } >> } >> >> @@ -1060,8 +1069,9 @@ nodeGetMemoryParameterValue(const char *field, >> if ((tmp = strchr(buf, '\n'))) >> *tmp = '\0'; >> >> - if (STREQ(field, "pages_to_scan") || >> - STREQ(field, "sleep_millisecs")) >> + if (STREQ(field, "pages_to_scan") || >> + STREQ(field, "sleep_millisecs") || >> + STREQ(field, "merge_across_nodes")) >> rc = virStrToLong_ui(buf, NULL, 10, (unsigned int *)value); >> else if (STREQ(field, "pages_shared") || >> STREQ(field, "pages_sharing") || >> @@ -1084,7 +1094,7 @@ cleanup: >> } >> #endif >> >> -#define NODE_MEMORY_PARAMETERS_NUM 7 >> +#define NODE_MEMORY_PARAMETERS_NUM 8 >> int >> nodeGetMemoryParameters(virConnectPtr conn ATTRIBUTE_UNUSED, >> virTypedParameterPtr params ATTRIBUTE_UNUSED, >> @@ -1096,6 +1106,7 @@ nodeGetMemoryParameters(virConnectPtr conn ATTRIBUTE_UNUSED, >> #ifdef __linux__ >> unsigned int pages_to_scan; >> unsigned int sleep_millisecs; >> + unsigned int merge_across_nodes; >> unsigned long long pages_shared; >> unsigned long long pages_sharing; >> unsigned long long pages_unshared; >> @@ -1189,6 +1200,17 @@ nodeGetMemoryParameters(virConnectPtr conn ATTRIBUTE_UNUSED, >> >> break; >> >> + case 7: >> + if (nodeGetMemoryParameterValue("merge_across_nodes", >> +&merge_across_nodes)< 0) >> + return -1; >> + >> + if (virTypedParameterAssign(param, VIR_NODE_MEMORY_SHARED_MERGE_ACROSS_NODES, >> + VIR_TYPED_PARAM_UINT, merge_across_nodes)< 0) >> + return -1; >> + >> + break; >> + >> default: >> break; >> } >> diff --git a/tools/virsh-host.c b/tools/virsh-host.c >> index 5cf192d..106f5e9 100644 >> --- a/tools/virsh-host.c >> +++ b/tools/virsh-host.c >> @@ -920,6 +920,8 @@ static const vshCmdOptDef opts_node_memory_tune[] = { >> {"shm-sleep-millisecs", VSH_OT_INT, VSH_OFLAG_NONE, >> N_("number of millisecs the shared memory service should " >> "sleep before next scan")}, >> + {"shm-merge-across-nodes", VSH_OT_INT, VSH_OFLAG_NONE, >> + N_("Specifies if pages from different numa nodes can be merged")}, >> {NULL, 0, 0, NULL} >> }; >> >> @@ -931,6 +933,7 @@ cmdNodeMemoryTune(vshControl *ctl, const vshCmd *cmd) >> unsigned int flags = 0; >> unsigned int shm_pages_to_scan = 0; >> unsigned int shm_sleep_millisecs = 0; >> + unsigned int shm_merge_across_nodes = 0; >> bool ret = false; >> int i = 0; >> >> @@ -946,12 +949,21 @@ cmdNodeMemoryTune(vshControl *ctl, const vshCmd *cmd) >> return false; >> } >> >> + if (vshCommandOptUInt(cmd, "shm-merge-across-nodes", >> +&shm_merge_across_nodes)< 0) { >> + vshError(ctl, "%s", _("invalid shm-merge-across-nodes number")); >> + return false; >> + } >> + >> if (shm_pages_to_scan) >> nparams++; >> >> if (shm_sleep_millisecs) >> nparams++; >> >> + if (shm_merge_across_nodes) >> + nparams++; >> + >> if (nparams == 0) { >> /* Get the number of memory parameters */ >> if (virNodeGetMemoryParameters(ctl->conn, NULL,&nparams, flags) != 0) { >> @@ -1003,6 +1015,14 @@ cmdNodeMemoryTune(vshControl *ctl, const vshCmd *cmd) >> goto error; >> } >> >> + if (i< nparams&& shm_merge_across_nodes) { >> + if (virTypedParameterAssign(¶ms[i++], >> + VIR_NODE_MEMORY_SHARED_MERGE_ACROSS_NODES, >> + VIR_TYPED_PARAM_UINT, >> + shm_merge_across_nodes)< 0) >> + goto error; >> + } >> + >> if (virNodeSetMemoryParameters(ctl->conn, params, nparams, flags) != 0) >> goto error; >> else >> diff --git a/tools/virsh.pod b/tools/virsh.pod >> index 2d90b7b..0481e1f 100644 >> --- a/tools/virsh.pod >> +++ b/tools/virsh.pod >> @@ -303,7 +303,10 @@ Allows you to display or set the node memory parameters. >> I<shm-pages-to-scan> can be used to set the number of pages to scan >> before the shared memory service goes to sleep; I<shm-sleep-millisecs> >> can be used to set the number of millisecs the shared memory service should >> -sleep before next scan. >> +sleep before next scan; I<shm-merge-across-nodes> specifies if pages from >> +different numa nodes can be merged. When set to 0, only pages which physically >> +reside in the memory area of same NUMA node can be merged. When set to 1, >> +pages from all nodes can be merged. Default to 1. >> >> =item B<capabilities> >> > > Okay, ACK, > Thanks, pushed. Regards, Osier -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list