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, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list