[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2 of 8 [RFC]] xl: allow for changing NUMA node affinity on-line



by implementing the "node-affinity" command, acting pretty much like
"vcpu-pin", although it of course affects node and not vcpu affinity.

Signed-off-by: Dario Faggioli <dario.faggioli@xxxxxxxxxx>

diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1
--- a/docs/man/xl.pod.1
+++ b/docs/man/xl.pod.1
@@ -626,6 +626,29 @@ different run state is appropriate.  Pin
 this, by ensuring certain VCPUs can only run on certain physical
 CPUs.
 
+=item B<node-affinity> I<domain-id> I<nodes>
+
+Sets or changes the NUMA node affinity for the domain. All the future
+memory allocations for the domain will use memory belonging to I<nodes>.
+Also (if the credit scheduler is in use), the VCPUs of the domain will
+run on the CPUs belonging to I<nodes> as much as possible.
+
+This is different than VCPU pinning, as VCPUs are not prohibited to run
+on CPUs not belonging to I<nodes>, and that can happen, for instance, in
+order to avoid having VCPUs waiting to run in some PCPU's runqueue when
+other PCPUs are idle.
+
+Changing a domain's node-affinity does not affect all the memory that
+has been allocated already, before the command is invoked.
+
+The keyword B<all> can be used to have the domain affine to all the
+NUMA nodes in the host. The keyword B<none> can be used to reset the
+node affinity. In that case, and from that point on, the node affinity
+of the domain will be automatically calculated basing on its vcpu affinity
+(see B<vcpu-pin> above). More specifically, the node affinity will be
+constituted by the nodes to which the physical CPUs its VCPUs have
+vcpu affinity with belong.
+
 =item B<vm-list>
 
 Prints information about guests. This list excludes information about
diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -58,6 +58,7 @@ int main_vm_list(int argc, char **argv);
 int main_create(int argc, char **argv);
 int main_config_update(int argc, char **argv);
 int main_button_press(int argc, char **argv);
+int main_nodeaffinity(int argc, char **argv);
 int main_vcpupin(int argc, char **argv);
 int main_vcpuset(int argc, char **argv);
 int main_memmax(int argc, char **argv);
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -601,6 +601,54 @@ static int vcpupin_parse(char *cpu, libx
     return rc;
 }
 
+static int nodeaffinity_parse(char *node, libxl_bitmap *nodemap)
+{
+    char *ptr, *saveptr = NULL;
+    int i, rc = 0, isnot;
+    libxl_bitmap map;
+
+    if (!strcmp(node, "all")) {
+        libxl_bitmap_set_any(nodemap);
+        return 0;
+    } else if (!strcmp(node, "none")) {
+        libxl_bitmap_set_none(nodemap);
+        return 0;
+    }
+
+    rc = libxl_node_bitmap_alloc(ctx, &map, 0);
+    if (rc) {
+        fprintf(stderr, "Error: Failed to allocate nodemap.\n");
+        goto out;
+    }
+
+    for (ptr = strtok_r(node, ",", &saveptr); ptr;
+         ptr = strtok_r(NULL, ",", &saveptr)) {
+        isnot = false;
+
+        /* Adding or removing nodes? */
+        if (*ptr == '^') {
+            isnot = true;
+            ptr++;
+        }
+        /* Get in map a bitmap representative of the range */
+        if (range_parse_bitmap(ptr, &map)) {
+            fprintf(stderr, "Error: Invalid argument.\n");
+            rc = EINVAL;
+            goto out;
+        }
+
+        libxl_for_each_set_bit(i, map) {
+            isnot ? libxl_bitmap_reset(nodemap, i)
+                  : libxl_bitmap_set(nodemap, i);
+        }
+    }
+
+ out:
+    libxl_bitmap_dispose(&map);
+
+    return rc;
+}
+
 static void parse_config_data(const char *config_source,
                               const char *config_data,
                               int config_len,
@@ -4583,6 +4631,39 @@ int main_vcpuset(int argc, char **argv)
     return 0;
 }
 
+static void nodeaffinity(uint32_t domid, char *node)
+{
+    libxl_bitmap nodemap;
+
+    if (libxl_node_bitmap_alloc(ctx, &nodemap, 0)) {
+        fprintf(stderr, "libxl_node_bitmap_alloc failed.\n");
+        goto out;
+    }
+
+    if (nodeaffinity_parse(node, &nodemap)) {
+        fprintf(stderr, "Could not parse node affinity.\n");
+        goto out;
+    }
+
+    if (libxl_domain_set_nodeaffinity(ctx, domid, &nodemap) == -1)
+        fprintf(stderr, "Could not set node affinity for dom `%d'.\n", domid);
+
+ out:
+    libxl_bitmap_dispose(&nodemap);
+}
+
+int main_nodeaffinity(int argc, char **argv)
+{
+    int opt;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "node-affinity", 2) {
+        /* No options */
+    }
+
+    nodeaffinity(find_domain(argv[optind]), argv[optind+1]);
+    return 0;
+}
+
 static void output_xeninfo(void)
 {
     const libxl_version_info *info;
diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -214,6 +214,11 @@ struct cmd_spec cmd_table[] = {
       "Set which CPUs a VCPU can use",
       "<Domain> <VCPU|all> <CPUs|all>",
     },
+    { "node-affinity",
+      &main_nodeaffinity, 0, 1,
+      "Set the NUMA node affinity for the domain",
+      "<Domain> [<NODEs|all|none>]",
+    },
     { "vcpu-set",
       &main_vcpuset, 0, 1,
       "Set the number of active VCPUs allowed for the domain",

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.