From: Dario Faggioli <dario.faggioli@citrix.com>
To: xen-devel@lists.xen.org
Cc: Marcus Granado <Marcus.Granado@eu.citrix.com>,
Keir Fraser <keir@xen.org>,
Ian Campbell <Ian.Campbell@citrix.com>,
Li Yechen <lccycc123@gmail.com>,
George Dunlap <george.dunlap@eu.citrix.com>,
Andrew Cooper <Andrew.Cooper3@citrix.com>,
Juergen Gross <juergen.gross@ts.fujitsu.com>,
Ian Jackson <Ian.Jackson@eu.citrix.com>,
Jan Beulich <JBeulich@suse.com>,
Justin Weaver <jtweaver@hawaii.edu>, Matt Wilson <msw@amazon.com>,
Elena Ufimtseva <ufimtseva@gmail.com>
Subject: [PATCH v2 02/16] xl: allow for node-wise specification of vcpu pinning
Date: Wed, 13 Nov 2013 20:11:15 +0100 [thread overview]
Message-ID: <20131113191114.18086.91666.stgit@Solace> (raw)
In-Reply-To: <20131113190852.18086.5437.stgit@Solace>
Making it possible to use something like the following:
* "nodes:0-3": all pCPUs of nodes 0,1,2,3;
* "nodes:0-3,^node:2": all pCPUS of nodes 0,1,3;
* "1,nodes:1-2,^6": pCPU 1 plus all pCPUs of nodes 1,2
but not pCPU 6;
* ...
In both domain config file and `xl vcpu-pin'.
Signed-off-by: Dario Faggioli <dario.faggioli@citrix.com>
---
Changes from v1 (of this very series):
* actually checking for both "nodes:" and "node:" as per
the doc says;
* using strcmp() (rather than strncmp()) when matching
"all", to avoid returning success on any longer string
that just begins with "all";
* fixing the handling (well, the rejection, actually) of
"^all" and "^nodes:all";
* make some string pointers const.
Changes from v2 (of original series):
* turned a 'return' into 'goto out', consistently with the
most of exit patterns;
* harmonized error handling: now parse_range() return a
libxl error code, as requested during review;
* dealing with "all" moved inside update_cpumap_range().
It's tricky to move it in parse_range() (as requested
during review), since we need the cpumap being modified
handy when dealing with it. However, having it in
update_cpumap_range() simplifies the code just as much
as that;
* explicitly checking for junk after a valid value or range
in parse_range(), as requested during review;
* xl exits on parsing failing, so no need to reset the
cpumap to something sensible in vcpupin_parse(), as
suggested during review;
Changes from v1 (of original series):
* code rearranged in order to look more simple to follow
and understand, as requested during review;
* improved docs in xl.cfg.pod.5, as requested during
review;
* strtoul() now returns into unsigned long, and the
case where it returns ULONG_MAX is now taken into
account, as requested during review;
* stuff like "all,^7" now works, as requested during
review. Specifying just "^7" does not work either
before or after this change
* killed some magic (i.e., `ptr += 5 + (ptr[4] == 's'`)
by introducing STR_SKIP_PREFIX() macro, as requested
during review.
---
docs/man/xl.cfg.pod.5 | 20 ++++++
tools/libxl/xl_cmdimpl.c | 153 +++++++++++++++++++++++++++++++++-------------
2 files changed, 128 insertions(+), 45 deletions(-)
diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index e6fc83f..5dbc73c 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -115,7 +115,25 @@ To allow all the vcpus of the guest to run on all the cpus on the host.
=item "0-3,5,^1"
-To allow all the vcpus of the guest to run on cpus 0,2,3,5.
+To allow all the vcpus of the guest to run on cpus 0,2,3,5. Combining
+this with "all" is possible, meaning "all,^7" results in all the vcpus
+of the guest running on all the cpus on the host except cpu 7.
+
+=item "nodes:0-3,node:^2"
+
+To allow all the vcpus of the guest to run on the cpus from NUMA nodes
+0,1,3 of the host. So, if cpus 0-3 belongs to node 0, cpus 4-7 belongs
+to node 1 and cpus 8-11 to node 3, the above would mean all the vcpus
+of the guest will run on cpus 0-3,8-11.
+
+Combining this notation with the one above is possible. For instance,
+"1,node:2,^6", means all the vcpus of the guest will run on cpu 1 and
+on all the cpus of NUMA node 2, but not on cpu 6. Following the same
+example as above, that would be cpus 1,4,5,7.
+
+Combining this with "all" is also possible, meaning "all,^nodes:1"
+results in all the vcpus of the guest running on all the cpus on the
+host, except for the cpus belonging to the host NUMA node 1.
=item ["2", "3"] (or [2, 3])
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 13e97b3..5f5cc43 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -59,6 +59,11 @@
} \
})
+#define STR_HAS_PREFIX( a, b ) \
+ ( strncmp(a, b, strlen(b)) == 0 )
+#define STR_SKIP_PREFIX( a, b ) \
+ ( STR_HAS_PREFIX(a, b) ? ((a) += strlen(b), 1) : 0 )
+
int logfile = 2;
@@ -513,61 +518,121 @@ static void split_string_into_string_list(const char *str,
free(s);
}
-static int vcpupin_parse(char *cpu, libxl_bitmap *cpumap)
+static int parse_range(const char *str, unsigned long *a, unsigned long *b)
{
- libxl_bitmap exclude_cpumap;
- uint32_t cpuida, cpuidb;
- char *endptr, *toka, *tokb, *saveptr = NULL;
- int i, rc = 0, rmcpu;
+ const char *nstr;
+ char *endptr;
- if (!strcmp(cpu, "all")) {
- libxl_bitmap_set_any(cpumap);
- return 0;
+ *a = *b = strtoul(str, &endptr, 10);
+ if (endptr == str || *a == ULONG_MAX)
+ return ERROR_INVAL;
+
+ if (*endptr == '-') {
+ nstr = endptr + 1;
+
+ *b = strtoul(nstr, &endptr, 10);
+ if (endptr == nstr || *b == ULONG_MAX || *b < *a)
+ return ERROR_INVAL;
+ }
+
+ /* Valid value or range so far, but we also don't want junk after that */
+ if (*endptr != '\0')
+ return ERROR_INVAL;
+
+ return 0;
+}
+
+/*
+ * Add or removes a specific set of cpus (specified in str, either as
+ * single cpus or as entire NUMA nodes) to/from cpumap.
+ */
+static int update_cpumap_range(const char *str, libxl_bitmap *cpumap)
+{
+ unsigned long ida, idb;
+ libxl_bitmap node_cpumap;
+ bool is_not = false, is_nodes = false;
+ int rc = 0;
+
+ libxl_bitmap_init(&node_cpumap);
+
+ rc = libxl_node_bitmap_alloc(ctx, &node_cpumap, 0);
+ if (rc) {
+ fprintf(stderr, "libxl_node_bitmap_alloc failed.\n");
+ goto out;
}
- if (libxl_cpu_bitmap_alloc(ctx, &exclude_cpumap, 0)) {
- fprintf(stderr, "Error: Failed to allocate cpumap.\n");
- return ENOMEM;
+ /* Are we adding or removing cpus/nodes? */
+ if (STR_SKIP_PREFIX(str, "^")) {
+ is_not = true;
}
- for (toka = strtok_r(cpu, ",", &saveptr); toka;
- toka = strtok_r(NULL, ",", &saveptr)) {
- rmcpu = 0;
- if (*toka == '^') {
- /* This (These) Cpu(s) will be removed from the map */
- toka++;
- rmcpu = 1;
- }
- /* Extract a valid (range of) cpu(s) */
- cpuida = cpuidb = strtoul(toka, &endptr, 10);
- if (endptr == toka) {
- fprintf(stderr, "Error: Invalid argument.\n");
- rc = EINVAL;
- goto vcpp_out;
- }
- if (*endptr == '-') {
- tokb = endptr + 1;
- cpuidb = strtoul(tokb, &endptr, 10);
- if (endptr == tokb || cpuida > cpuidb) {
- fprintf(stderr, "Error: Invalid argument.\n");
- rc = EINVAL;
- goto vcpp_out;
+ /* Are we dealing with cpus or full nodes? */
+ if (STR_SKIP_PREFIX(str, "node:") || STR_SKIP_PREFIX(str, "nodes:")) {
+ is_nodes = true;
+ }
+
+ if (strcmp(str, "all") == 0) {
+ /* We do not accept "^all" or "^nodes:all" */
+ if (is_not) {
+ fprintf(stderr, "Can't combine \"^\" and \"all\".\n");
+ rc = ERROR_INVAL;
+ } else
+ libxl_bitmap_set_any(cpumap);
+ goto out;
+ }
+
+ rc = parse_range(str, &ida, &idb);
+ if (rc) {
+ fprintf(stderr, "Invalid pcpu range: %s.\n", str);
+ goto out;
+ }
+
+ /* Add or remove the specified cpus in the range */
+ while (ida <= idb) {
+ if (is_nodes) {
+ /* Add/Remove all the cpus of a NUMA node */
+ int i;
+
+ rc = libxl_node_to_cpumap(ctx, ida, &node_cpumap);
+ if (rc) {
+ fprintf(stderr, "libxl_node_to_cpumap failed.\n");
+ goto out;
}
+
+ /* Add/Remove all the cpus in the node cpumap */
+ libxl_for_each_set_bit(i, node_cpumap) {
+ is_not ? libxl_bitmap_reset(cpumap, i) :
+ libxl_bitmap_set(cpumap, i);
+ }
+ } else {
+ /* Add/Remove this cpu */
+ is_not ? libxl_bitmap_reset(cpumap, ida) :
+ libxl_bitmap_set(cpumap, ida);
}
- while (cpuida <= cpuidb) {
- rmcpu == 0 ? libxl_bitmap_set(cpumap, cpuida) :
- libxl_bitmap_set(&exclude_cpumap, cpuida);
- cpuida++;
- }
+ ida++;
}
- /* Clear all the cpus from the removal list */
- libxl_for_each_set_bit(i, exclude_cpumap) {
- libxl_bitmap_reset(cpumap, i);
- }
+ out:
+ libxl_bitmap_dispose(&node_cpumap);
+ return rc;
+}
-vcpp_out:
- libxl_bitmap_dispose(&exclude_cpumap);
+/*
+ * Takes a string representing a set of cpus (specified either as
+ * single cpus or as eintire NUMA nodes) and turns it into the
+ * corresponding libxl_bitmap (in cpumap).
+ */
+static int vcpupin_parse(char *cpu, libxl_bitmap *cpumap)
+{
+ char *ptr, *saveptr = NULL;
+ int rc = 0;
+
+ for (ptr = strtok_r(cpu, ",", &saveptr); ptr;
+ ptr = strtok_r(NULL, ",", &saveptr)) {
+ rc = update_cpumap_range(ptr, cpumap);
+ if (rc)
+ break;
+ }
return rc;
}
next prev parent reply other threads:[~2013-11-13 19:11 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-13 19:10 [PATCH v2 00/16] Implement vcpu soft affinity for credit1 Dario Faggioli
2013-11-13 19:11 ` [PATCH v2 01/16] xl: match output of vcpu-list with pinning syntax Dario Faggioli
2013-11-14 10:50 ` George Dunlap
2013-11-14 11:11 ` Dario Faggioli
2013-11-14 11:14 ` George Dunlap
2013-11-14 11:13 ` Dario Faggioli
2013-11-14 12:44 ` Ian Jackson
2013-11-14 14:19 ` Ian Jackson
2013-11-13 19:11 ` Dario Faggioli [this message]
2013-11-14 11:02 ` [PATCH v2 02/16] xl: allow for node-wise specification of vcpu pinning George Dunlap
2013-11-14 14:24 ` Ian Jackson
2013-11-14 14:37 ` Dario Faggioli
2013-11-13 19:11 ` [PATCH v2 03/16] xl: implement and enable dryrun mode for `xl vcpu-pin' Dario Faggioli
2013-11-13 19:11 ` [PATCH v2 04/16] xl: test script for the cpumap parser (for vCPU pinning) Dario Faggioli
2013-11-13 19:11 ` [PATCH v2 05/16] xen: fix leaking of v->cpu_affinity_saved Dario Faggioli
2013-11-14 11:11 ` George Dunlap
2013-11-14 11:58 ` Dario Faggioli
2013-11-14 14:25 ` Ian Jackson
2013-11-13 19:11 ` [PATCH v2 06/16] xen: sched: make space for cpu_soft_affinity Dario Faggioli
2013-11-14 15:03 ` George Dunlap
2013-11-14 16:14 ` Dario Faggioli
2013-11-15 10:07 ` George Dunlap
2013-11-13 19:12 ` [PATCH v2 07/16] xen: sched: rename v->cpu_affinity into v->cpu_hard_affinity Dario Faggioli
2013-11-14 14:17 ` George Dunlap
2013-11-13 19:12 ` [PATCH v2 08/16] xen: derive NUMA node affinity from hard and soft CPU affinity Dario Faggioli
2013-11-14 15:21 ` George Dunlap
2013-11-14 16:30 ` Dario Faggioli
2013-11-15 10:52 ` George Dunlap
2013-11-15 14:17 ` Dario Faggioli
2013-11-13 19:12 ` [PATCH v2 09/16] xen: sched: DOMCTL_*vcpuaffinity works with hard and soft affinity Dario Faggioli
2013-11-14 14:42 ` George Dunlap
2013-11-14 16:21 ` Dario Faggioli
2013-11-13 19:12 ` [PATCH v2 10/16] xen: sched: use soft-affinity instead of domain's node-affinity Dario Faggioli
2013-11-14 15:30 ` George Dunlap
2013-11-15 0:39 ` Dario Faggioli
2013-11-15 11:23 ` George Dunlap
2013-11-13 19:12 ` [PATCH v2 11/16] libxc: get and set soft and hard affinity Dario Faggioli
2013-11-14 14:58 ` Ian Jackson
2013-11-14 16:18 ` Dario Faggioli
2013-11-14 15:38 ` George Dunlap
2013-11-14 16:41 ` Dario Faggioli
2013-11-13 19:12 ` [PATCH v2 12/16] libxl: get and set soft affinity Dario Faggioli
2013-11-13 19:16 ` Dario Faggioli
2013-11-14 15:11 ` Ian Jackson
2013-11-14 15:55 ` George Dunlap
2013-11-14 16:25 ` Ian Jackson
2013-11-15 5:13 ` Dario Faggioli
2013-11-15 12:02 ` George Dunlap
2013-11-15 17:29 ` Dario Faggioli
2013-11-15 3:45 ` Dario Faggioli
2013-11-13 19:12 ` [PATCH v2 13/16] xl: show soft affinity in `xl vcpu-list' Dario Faggioli
2013-11-14 15:12 ` Ian Jackson
2013-11-13 19:13 ` [PATCH v2 14/16] xl: enable setting soft affinity Dario Faggioli
2013-11-13 19:13 ` [PATCH v2 15/16] xl: enable for specifying node-affinity in the config file Dario Faggioli
2013-11-14 15:14 ` Ian Jackson
2013-11-14 16:12 ` Dario Faggioli
2013-11-13 19:13 ` [PATCH v2 16/16] libxl: automatic NUMA placement affects soft affinity Dario Faggioli
2013-11-14 15:17 ` Ian Jackson
2013-11-14 16:11 ` Dario Faggioli
2013-11-14 16:03 ` George Dunlap
2013-11-14 16:48 ` Dario Faggioli
2013-11-14 17:49 ` George Dunlap
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131113191114.18086.91666.stgit@Solace \
--to=dario.faggioli@citrix.com \
--cc=Andrew.Cooper3@citrix.com \
--cc=Ian.Campbell@citrix.com \
--cc=Ian.Jackson@eu.citrix.com \
--cc=JBeulich@suse.com \
--cc=Marcus.Granado@eu.citrix.com \
--cc=george.dunlap@eu.citrix.com \
--cc=jtweaver@hawaii.edu \
--cc=juergen.gross@ts.fujitsu.com \
--cc=keir@xen.org \
--cc=lccycc123@gmail.com \
--cc=msw@amazon.com \
--cc=ufimtseva@gmail.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.