[libvirt] [PATCH v4] memtune: Let virsh know the unlimited value for memory tunables

Nikunj A. Dadhania nikunj at linux.vnet.ibm.com
Thu Jan 13 06:55:39 UTC 2011


On Wed, 12 Jan 2011 10:21:04 -0700, Eric Blake <eblake at redhat.com> wrote:
> On 01/12/2011 12:56 AM, Nikunj A. Dadhania wrote:
> > Here is the patch, now the set calls are also ull. 
> > 
> > Still virCgroupGetMemoryUsage is not changed, this will require changes
> > in virDomainInfoPtr (info->memory). I am not sure if I should have them
> > in this patch.
> 
> It can be a separate patch, if desired, but it is probably still needed.
>
virCgroupGetMemoryUsage is called only from lxcDomainGetInfo, that is
the reason I thought that this change may not be needed.

> > +++ b/tools/virsh.c
> > @@ -2987,9 +2987,14 @@ cmdMemtune(vshControl * ctl, const vshCmd * cmd)
> >                               params[i].value.l);
> >                      break;
> >                  case VIR_DOMAIN_MEMORY_PARAM_ULLONG:
> > -                    vshPrint(ctl, "%-15s: %llu\n", params[i].field,
> > -                             params[i].value.ul);
> > +                {
> > +                    if (params[i].value.ul == VIR_DOMAIN_MEMORY_PARAM_UNLIMITED)
> > +                        vshPrint(ctl, "%-15s: unlimited\n", params[i].field);
> > +                    else
> > +                        vshPrint(ctl, "%-15s: %llu\n", params[i].field,
> > +                                 params[i].value.ul);
> 
> Do we want any back-compat considerations?  That is, if a newer virsh is
> talking to an older server, which still answered INT64_MAX>>10 instead
> of the new VIR_DOMAIN_MEMORY_PARAM_UNLIMITED, should we recognize that
> situation as another reason to print "unlimited"?
> 
As Mattias suggested in the other mail, this adds more complications. My
take is to have VIR_DOMAIN_MEMORY_PARAM_UNLIMITED as the max value.

Here is the patch which adds setting as well as displaying the
"unlimited" values. Now in virsh to specify "unlimited" the user would
need to pass "-1"

for example:
virsh # memtune lxcbb1 --hard-limit -1

From: Nikunj A. Dadhania <nikunj at linux.vnet.ibm.com>

Display and set unlimited when the memory cgroup settings. Unlimited is
represented by INT64_MAX in memory cgroup.

v4: Fix handling of setting unlimited values
v3: Make virCgroupSet memory call ull

Signed-off-by: Nikunj A. Dadhania <nikunj at linux.vnet.ibm.com>
Reported-by: Justin Clift <jclift at redhat.com>
---
 include/libvirt/libvirt.h.in |    1 
 src/lxc/lxc_driver.c         |    2 -
 src/qemu/qemu_driver.c       |    2 -
 src/util/cgroup.c            |   93 +++++++++++++++++++++++++++++++-----------
 src/util/cgroup.h            |   14 +++---
 tools/virsh.c                |   13 +++++-
 6 files changed, 90 insertions(+), 35 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 3c6a54a..3ee47b9 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -696,6 +696,7 @@ typedef enum {
  */
 
 #define VIR_DOMAIN_MEMORY_FIELD_LENGTH 80
+#define VIR_DOMAIN_MEMORY_PARAM_UNLIMITED INT64_MAX
 
 /**
  * VIR_DOMAIN_MEMORY_HARD_LIMIT:
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index eb58086..2db9954 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -815,7 +815,7 @@ static int lxcDomainGetMemoryParameters(virDomainPtr dom,
     int i;
     virCgroupPtr cgroup = NULL;
     virDomainObjPtr vm = NULL;
-    unsigned long val;
+    unsigned long long val;
     int ret = -1;
     int rc;
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e915705..6648c6a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7077,7 +7077,7 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom,
     int i;
     virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
-    unsigned long val;
+    unsigned long long val;
     int ret = -1;
     int rc;
 
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index 3ba6325..03a1263 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -355,8 +355,6 @@ static int virCgroupSetValueU64(virCgroupPtr group,
 }
 
 
-#if 0
-/* This is included for completeness, but not yet used */
 
 static int virCgroupSetValueI64(virCgroupPtr group,
                                 int controller,
@@ -376,6 +374,8 @@ static int virCgroupSetValueI64(virCgroupPtr group,
     return rc;
 }
 
+#if 0
+/* This is included for completeness, but not yet used */
 static int virCgroupGetValueI64(virCgroupPtr group,
                                 int controller,
                                 const char *key,
@@ -858,12 +858,22 @@ int virCgroupForDomain(virCgroupPtr driver ATTRIBUTE_UNUSED,
  *
  * Returns: 0 on success
  */
-int virCgroupSetMemory(virCgroupPtr group, unsigned long kb)
+int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb)
 {
-    return virCgroupSetValueU64(group,
-                                VIR_CGROUP_CONTROLLER_MEMORY,
-                                "memory.limit_in_bytes",
-                                kb << 10);
+    unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED >> 10;
+
+    if (kb > maxkb)
+        return -EINVAL;
+    else if (kb == maxkb)
+        return virCgroupSetValueI64(group,
+                                    VIR_CGROUP_CONTROLLER_MEMORY,
+                                    "memory.limit_in_bytes",
+                                    -1);
+    else
+        return virCgroupSetValueU64(group,
+                                    VIR_CGROUP_CONTROLLER_MEMORY,
+                                    "memory.limit_in_bytes",
+                                    kb << 10);
 }
 
 /**
@@ -894,7 +904,7 @@ int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb)
  *
  * Returns: 0 on success
  */
-int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long kb)
+int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb)
 {
     return virCgroupSetMemory(group, kb);
 }
@@ -907,7 +917,7 @@ int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long kb)
  *
  * Returns: 0 on success
  */
-int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long *kb)
+int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb)
 {
     long long unsigned int limit_in_bytes;
     int ret;
@@ -915,7 +925,12 @@ int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long *kb)
                                VIR_CGROUP_CONTROLLER_MEMORY,
                                "memory.limit_in_bytes", &limit_in_bytes);
     if (ret == 0)
-        *kb = (unsigned long) limit_in_bytes >> 10;
+    {
+        if (limit_in_bytes != INT64_MAX)
+            *kb = (unsigned long long) limit_in_bytes >> 10;
+        else
+            *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
+    }
     return ret;
 }
 
@@ -927,12 +942,22 @@ int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long *kb)
  *
  * Returns: 0 on success
  */
-int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long kb)
+int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb)
 {
-    return virCgroupSetValueU64(group,
-                                VIR_CGROUP_CONTROLLER_MEMORY,
-                                "memory.soft_limit_in_bytes",
-                                kb << 10);
+    unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED >> 10;
+
+    if (kb > maxkb)
+        return -EINVAL;
+    else if (kb == maxkb)
+        return virCgroupSetValueI64(group,
+                                    VIR_CGROUP_CONTROLLER_MEMORY,
+                                    "memory.soft_limit_in_bytes",
+                                    -1);
+    else
+        return virCgroupSetValueU64(group,
+                                    VIR_CGROUP_CONTROLLER_MEMORY,
+                                    "memory.soft_limit_in_bytes",
+                                    kb << 10);
 }
 
 
@@ -944,7 +969,7 @@ int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long kb)
  *
  * Returns: 0 on success
  */
-int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long *kb)
+int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb)
 {
     long long unsigned int limit_in_bytes;
     int ret;
@@ -952,7 +977,12 @@ int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long *kb)
                                VIR_CGROUP_CONTROLLER_MEMORY,
                                "memory.soft_limit_in_bytes", &limit_in_bytes);
     if (ret == 0)
-        *kb = (unsigned long) limit_in_bytes >> 10;
+    {
+        if (limit_in_bytes != INT64_MAX)
+            *kb = (unsigned long long) limit_in_bytes >> 10;
+        else
+            *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
+    }
     return ret;
 }
 
@@ -964,12 +994,22 @@ int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long *kb)
  *
  * Returns: 0 on success
  */
-int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long kb)
+int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long long kb)
 {
-    return virCgroupSetValueU64(group,
-                                VIR_CGROUP_CONTROLLER_MEMORY,
-                                "memory.memsw.limit_in_bytes",
-                                kb << 10);
+    unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED >> 10;
+
+    if (kb > maxkb)
+        return -EINVAL;
+    else if (kb == maxkb)
+        return virCgroupSetValueI64(group,
+                                    VIR_CGROUP_CONTROLLER_MEMORY,
+                                    "memory.memsw.limit_in_bytes",
+                                    -1);
+    else
+        return virCgroupSetValueU64(group,
+                                    VIR_CGROUP_CONTROLLER_MEMORY,
+                                    "memory.memsw.limit_in_bytes",
+                                    kb << 10);
 }
 
 /**
@@ -980,7 +1020,7 @@ int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long kb)
  *
  * Returns: 0 on success
  */
-int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long *kb)
+int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long long *kb)
 {
     long long unsigned int limit_in_bytes;
     int ret;
@@ -988,7 +1028,12 @@ int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long *kb)
                                VIR_CGROUP_CONTROLLER_MEMORY,
                                "memory.memsw.limit_in_bytes", &limit_in_bytes);
     if (ret == 0)
-        *kb = (unsigned long) limit_in_bytes >> 10;
+    {
+        if (limit_in_bytes != INT64_MAX)
+            *kb = (unsigned long long) limit_in_bytes >> 10;
+        else
+            *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
+    }
     return ret;
 }
 
diff --git a/src/util/cgroup.h b/src/util/cgroup.h
index 9e1c61f..964da7a 100644
--- a/src/util/cgroup.h
+++ b/src/util/cgroup.h
@@ -40,15 +40,15 @@ int virCgroupForDomain(virCgroupPtr driver,
 
 int virCgroupAddTask(virCgroupPtr group, pid_t pid);
 
-int virCgroupSetMemory(virCgroupPtr group, unsigned long kb);
+int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb);
 int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb);
 
-int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long kb);
-int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long *kb);
-int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long kb);
-int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long *kb);
-int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long kb);
-int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long *kb);
+int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb);
+int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb);
+int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb);
+int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb);
+int virCgroupSetSwapHardLimit(virCgroupPtr group, unsigned long long kb);
+int virCgroupGetSwapHardLimit(virCgroupPtr group, unsigned long long *kb);
 
 int virCgroupDenyAllDevices(virCgroupPtr group);
 
diff --git a/tools/virsh.c b/tools/virsh.c
index 55e2a68..e855d1d 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2987,9 +2987,14 @@ cmdMemtune(vshControl * ctl, const vshCmd * cmd)
                              params[i].value.l);
                     break;
                 case VIR_DOMAIN_MEMORY_PARAM_ULLONG:
-                    vshPrint(ctl, "%-15s: %llu\n", params[i].field,
-                             params[i].value.ul);
+                {
+                    if (params[i].value.ul == VIR_DOMAIN_MEMORY_PARAM_UNLIMITED)
+                        vshPrint(ctl, "%-15s: unlimited\n", params[i].field);
+                    else
+                        vshPrint(ctl, "%-15s: %llu kB\n", params[i].field,
+                                 params[i].value.ul);
                     break;
+                }
                 case VIR_DOMAIN_MEMORY_PARAM_DOUBLE:
                     vshPrint(ctl, "%-15s: %f\n", params[i].field,
                              params[i].value.d);
@@ -3039,6 +3044,10 @@ cmdMemtune(vshControl * ctl, const vshCmd * cmd)
                         sizeof(temp->field));
                 min_guarantee = 0;
             }
+
+            /* If the user has passed -1, we interpret it as unlimited */
+            if(temp->value.ul == -1)
+                temp->value.ul = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED >> 10;
         }
         if (virDomainSetMemoryParameters(dom, params, nparams, 0) != 0)
             vshError(ctl, "%s", _("Unable to change memory parameters"));




More information about the libvir-list mailing list