[libvirt] [PATCH v2] node_memory: Add new parameter field to tune the new sysfs knob

Osier Yang jyang at redhat.com
Mon Oct 15 08:48:47 UTC 2012


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(&params[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




More information about the libvir-list mailing list