Series short description
v3 cover Series short description
Implement vcpu soft affinity for credit1
Hello everyone,
Take 3 for his series.
Very briefly, what it does is allowing each vcpu to have:
- an hard affinity, which they already do, and we usually call pinning. This is the list of pcpus where a vcpu is allowed to run;
- a soft affinity, which this series introduces. This is the list of pcpus where a vcpu *prefers* to run.
Once that is done, per-vcpu NUMA-aware scheduling is easily implemented on top of that, just by instructing libxl to issue the proper call to setup the soft affinity of the domain's vcpus to be equal to its node-affinity.
Wrt v2 review[*] I have addressed all the comments (see individual changelogs). In particular, I have completely redesigned the libxl interface. It now allows both the following usage patterns:
1. changing either soft affinity only or hard affinity only or both of them to the same value, and getting DEBUG or WARN output if that results in an inconsistent state;
2. changing both hard and soft affinity, each one to its own value, and getting DEBUG or WARN output only if the *final* state is inconsistent.
The series is also available here:
git://xenbits.xen.org/people/dariof/xen.git numa/per-vcpu-affinity-v3
Thanks and Regards,
Dario
[*] http://bugs.xenproject.org/xen/mid/%3C20131113190852.18086.5437.stgit@Solace%3E/
---
Dario Faggioli (14):
a xl: match output of vcpu-list with pinning syntax
n libxl: sanitize error handling in libxl_get_max_{cpus,nodes}
ra xl: allow for node-wise specification of vcpu pinning
a xl: implement and enable dryrun mode for `xl vcpu-pin'
a xl: test script for the cpumap parser (for vCPU pinning)
r xen: sched: rename v->cpu_affinity into v->cpu_hard_affinity
r xen: sched: introduce soft-affinity and use it instead d->node-affinity xen: derive NUMA node affinity from hard and soft CPU affinity
xen: sched: DOMCTL_*vcpuaffinity works with hard and soft affinity
libxc: get and set soft and hard affinity
libxl: get and set soft affinity
xl: enable getting and setting soft
* xl: enable for specifying node-affinity in the config file
a libxl: automatic NUMA placement affects soft affinity
n = new in v3
r = has been 'Reviewed-by'
a = has been 'Acked-by'
* = has been 'Acked-by' but the implementation changed a bit (IanJ explicitly said to point this out)
docs/man/xl.cfg.pod.5 | 66 +++- docs/man/xl.pod.1 | 24 +- docs/misc/xl-numa-placement.markdown | 164 +++++++---- tools/libxc/xc_domain.c | 47 ++- tools/libxc/xenctrl.h | 44 +++ tools/libxl/Makefile | 2 tools/libxl/check-xl-vcpupin-parse | 294 +++++++++++++++++++ tools/libxl/check-xl-vcpupin-parse.data-example | 53 +++ tools/libxl/libxl.c | 146 +++++++++ tools/libxl/libxl.h | 30 ++ tools/libxl/libxl_create.c | 6 tools/libxl/libxl_dom.c | 23 + tools/libxl/libxl_types.idl | 4 tools/libxl/libxl_utils.c | 48 +++ tools/libxl/libxl_utils.h | 41 +-- tools/libxl/xl_cmdimpl.c | 356 ++++++++++++++++------- tools/libxl/xl_cmdtable.c | 5 tools/ocaml/libs/xc/xenctrl_stubs.c | 8 - tools/python/xen/lowlevel/xc/xc.c | 6 xen/arch/x86/traps.c | 13 - xen/common/domain.c | 87 +++--- xen/common/domctl.c | 54 +++ xen/common/keyhandler.c | 4 xen/common/sched_credit.c | 161 ++++------ xen/common/sched_sedf.c | 2 xen/common/schedule.c | 57 ++-- xen/common/wait.c | 10 - xen/include/public/domctl.h | 15 + xen/include/xen/sched.h | 14 + 29 files changed, 1377 insertions(+), 407 deletions(-) create mode 100755 tools/libxl/check-xl-vcpupin-parse create mode 100644 tools/libxl/check-xl-vcpupin-parse.data-example
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
PATCH v3 1/14 xl: match output of vcpu-list with pinning syntax
in fact, pinning to all the pcpus happens by specifying "all" (either on the command line or in the config file), while `xl vcpu-list' report it as "any cpu".
Change this into something more consistent, by using "all" everywhere.
---
Changes since v1:
* this patch was not there in v1. It is now as using the same syntax for both input and output was requested during review.
--- tools/libxl/xl_cmdimpl.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-)
tools/libxl/xl_cmdimpl.c +7 -20
@@ -3101,8 +3101,7 @@ out: } } -/* If map is not full, prints it and returns 0. Returns 1 otherwise. */ -static int print_bitmap (uint8_t *map,int maplen,FILE *stream) +static void print_bitmap (uint8_t *map,int maplen,FILE *stream) {int i;uint8_t pmap =0 , bitmask =0 ;
@@ -3140,28 +3139,16 @@ static int print_bitmap(uint8_t *map, int maplen, FILE *stream)case 2 :break ;case 1 : -if (firstset ==0 ) -return 1 ; +if (firstset ==0 ) { +fprintf (stream,"all" ); +break ; + }case 3 :fprintf (stream,"%s%d" , state >1 ?"," :"" , firstset);if (i -1 > firstset)fprintf (stream,"-%d" , i -1 );break ; } - -return 0 ; -} - -static void print_cpumap (uint8_t *map,int maplen,FILE *stream) -{ -if (print_bitmap (map, maplen, stream)) -fprintf (stream,"any cpu" ); -} - -static void print_nodemap (uint8_t *map,int maplen,FILE *stream) -{ -if (print_bitmap (map, maplen, stream)) -fprintf (stream,"any node" ); } static void list_domains(int verbose, int context, int claim, int numa,
@@ -3234,7 +3221,7 @@ static void list_domains(int verbose, int context, int claim, int numa,libxl_domain_get_nodeaffinity (ctx, info[i].domid, &nodemap);putchar (' ' ); -print_nodemap (nodemap.map, physinfo.nr_nodes, stdout); +print_bitmap (nodemap.map, physinfo.nr_nodes, stdout); }putchar ('\n' ); }
@@ -4446,7 +4433,7 @@ static void print_vcpuinfo(uint32_t tdomid,/* TIM */ printf ("%9.1f " , ((float )vcpuinfo->vcpu_time /1e9 ));/* CPU AFFINITY */ -print_cpumap (vcpuinfo->cpumap.map, nr_cpus, stdout); +print_bitmap (vcpuinfo->cpumap.map, nr_cpus, stdout);printf ("\n" ); }
PATCH v3 2/14 libxl: sanitize error handling in libxl_get_max_{cpus, nodes}
In reply to Dario Faggiolias well as both error handling and logging in libxl_cpu_bitmap_alloc and libxl_node_bitmap_alloc.
Now libxl_get_max_{cpus,nodes} either return a positive number, or a libxl error code. Thanks to that, it is possible to fix loggig for the two bitmap allocation functions, which now happens _inside_ the functions themselves, and report what happens more accurately.
---
Changes from v2:
* this wasn't there in v2, but fixing this for v3 was requested during v2 review.
--- tools/libxl/libxl.c | 8 ++------ tools/libxl/libxl_utils.c | 48 +++++++++++++++++++++++++++++++++++++++++++-- tools/libxl/libxl_utils.h | 32 ++++++------------------------ 3 files changed, 54 insertions(+), 34 deletions(-)
tools/libxl/libxl.c +2 -6
@@ -616,10 +616,8 @@ static int cpupool_info(libxl__gc *gc, info->n_dom = xcinfo->n_dom; rc =libxl_cpu_bitmap_alloc (CTX , &info->cpumap,0 );if (rc) - { -LOG (ERROR ,"unable to allocate cpumap %d\n" , rc); goto out; - } +memcpy (info->cpumap.map, xcinfo->cpumap, info->cpumap.size); rc =0 ;
@@ -4204,10 +4202,8 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid, }for (*nb_vcpu =0 ; *nb_vcpu <= domaininfo.max_vcpu_id; ++*nb_vcpu, ++ptr) { -if (libxl_cpu_bitmap_alloc (ctx, &ptr->cpumap,0 )) { -LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR ,"allocating cpumap" ); +if (libxl_cpu_bitmap_alloc (ctx, &ptr->cpumap,0 ))return NULL ; - }if (xc_vcpu_getinfo (ctx->xch, domid, *nb_vcpu, &vcpuinfo) ==-1 ) {LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR ,"getting vcpu info" );return NULL ;
tools/libxl/libxl_utils.c +46 -2
64 lines not on this page · raw message
tools/libxl/libxl_utils.h +6 -26
@@ -98,32 +98,12 @@ static inline int libxl_bitmap_cpu_valid(libxl_bitmap *bitmap, int bit)#define libxl_for_each_set_bit (v, m) for (v = 0; v < (m).size * 8; v++) \ if (libxl_bitmap_test(&(m), v)) -static inline int libxl_cpu_bitmap_alloc (libxl_ctx *ctx,libxl_bitmap *cpumap, -int max_cpus) -{ -if (max_cpus <0 ) -return ERROR_INVAL ; -if (max_cpus ==0 ) - max_cpus =libxl_get_max_cpus (ctx); -if (max_cpus ==0 ) -return ERROR_FAIL ; - -return libxl_bitmap_alloc (ctx, cpumap, max_cpus); -} - -static inline int libxl_node_bitmap_alloc (libxl_ctx *ctx, -libxl_bitmap *nodemap, -int max_nodes) -{ -if (max_nodes <0 ) -return ERROR_INVAL ; -if (max_nodes ==0 ) - max_nodes =libxl_get_max_nodes (ctx); -if (max_nodes ==0 ) -return ERROR_FAIL ; - -return libxl_bitmap_alloc (ctx, nodemap, max_nodes); -} +int libxl_cpu_bitmap_alloc (libxl_ctx *ctx, +libxl_bitmap *cpumap, +int max_cpus); +int libxl_node_bitmap_alloc (libxl_ctx *ctx, +libxl_bitmap *nodemap, +int max_nodes);/* Populate cpumap with the cpus spanned by the nodes in nodemap */ int libxl_nodemap_to_cpumap(libxl_ctx *ctx,
Re: [PATCH v3 02/14] libxl: sanitize error handling in libxl_get_max_{cpus, nodes}
Quoted 9 lines · Dario Faggioli
as well as both error handling and logging in
libxl_cpu_bitmap_allocandlibxl_node_bitmap_alloc.Now libxl_get_max_{cpus,nodes} either return a positive number, or a libxl error code. Thanks to that, it is possible to fix loggig for the two bitmap allocation functions, which now happens _inside_ the functions themselves, and report what happens more accurately.
Signed-off-by Dario Faggioli <[email protected]>
With one caveat...
tools/libxl/libxl_utils.c char *libxl_bitmap_to_hex_string(libxl_ctx *ctx, const libxl_bitmap *bitmap) · line 650
Quoted 11 lines
tools/libxl/libxl_utils.c +3
-0@@ -645,6 +645,46 @@ char *libxl_bitmap_to_hex_string(libxl_ctx *ctx, const libxl_bitmap *bitmap)return q; } +inline int libxl_cpu_bitmap_alloc (libxl_ctx *ctx, +libxl_bitmap *cpumap, +int max_cpus)
Stray 'inline'. :-)
-George
Re: [PATCH v3 02/14] libxl: sanitize error handling in libxl_get_max_{cpus, nodes}
Quoted 4 lines · George Dunlap
Quoted 3 lines · Dario Faggioli
as well as both error handling and logging in
libxl_cpu_bitmap_allocandlibxl_node_bitmap_alloc.
Quoted 9 lines
Quoted 6 lines
Now libxl_get_max_{cpus,nodes} either return a positive number, or a libxl error code. Thanks to that, it is possible to fix loggig for the two bitmap allocation functions, which now happens _inside_ the functions themselves, and report what happens more accurately.
Signed-off-by Dario Faggioli <[email protected]>Reviewed-by George Dunlap <[email protected]>
Thanks.
Quoted 8 lines
Quoted 8 lines
tools/libxl/libxl_utils.c +0
-0@@ -645,6 +645,46 @@ char *libxl_bitmap_to_hex_string(libxl_ctx *ctx, const libxl_bitmap *bitmap)return q; }
Quoted 6 lines
tools/libxl/libxl_utils.c char *libxl_bitmap_to_hex_string(libxl_ctx *ctx, const libxl_bitmap *bitmap) · line 650
Quoted 3 lines
tools/libxl/libxl_utils.c +3
-0+inline int libxl_cpu_bitmap_alloc (libxl_ctx *ctx, +libxl_bitmap *cpumap, +int max_cpus)Stray 'inline'. :-)
Wow... How did he manage to survive? I mean, I killed his 'static' buddy but kept him? I guess I'm getting too old for late night hacking sessions! :-P
Anyway, let's see how the rest of the review goes. If I have to resend, I will fix this. Otherwise I can just resend this patch, or do whatever the maintainers/committers are most comfortable with.
Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
PATCH v3 3/14 xl: allow for node-wise specification of vcpu pinning
In reply to Dario FaggioliMaking 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'.
---
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(-)
docs/man/xl.cfg.pod.5 +19 -1
@@ -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])
tools/libxl/xl_cmdimpl.c +109 -44
176 lines not on this page · raw message
PATCH v3 4/14 xl: implement and enable dryrun mode for `xl vcpu-pin'
In reply to Dario FaggioliAs it can be useful to see if the outcome of some complex vCPU pinning bitmap specification looks as expected.
This also allow for the introduction of some automatic testing and verification for the bitmap parsing code, as it happens already in check-xl-disk-parse and check-xl-vif-parse.
In particular, to make the above possible, this commit also changes the implementation of the vcpu-pin command so that, instead of always returning 0, it returns an error if the parsing fails.
---
Changes since v2 (of original series):
* fixed a typo in the changelog
--- tools/libxl/xl_cmdimpl.c | 49 +++++++++++++++++++++++++++++++++------------ tools/libxl/xl_cmdtable.c | 2 +- 2 files changed, 37 insertions(+), 14 deletions(-)
tools/libxl/xl_cmdimpl.c +36 -13
@@ -4566,30 +4566,53 @@ int main_vcpulist(int argc, char **argv)return 0 ; } -static void vcpupin (uint32_t domid,const char *vcpu,char *cpu) +static int vcpupin (uint32_t domid,const char *vcpu,char *cpu) {libxl_vcpuinfo *vcpuinfo;libxl_bitmap cpumap;uint32_t vcpuid;char *endptr; -int i, nb_vcpu; +int i =0 , nb_vcpu, rc =-1 ; + +libxl_bitmap_init (&cpumap); vcpuid =strtoul (vcpu, &endptr,10 );if (vcpu == endptr) {if (strcmp (vcpu,"all" )) {fprintf (stderr,"Error: Invalid argument.\n" ); -return ; + goto out; } vcpuid =-1 ; } -if (libxl_cpu_bitmap_alloc (ctx, &cpumap,0 )) { - goto vcpupin_out; - } +if (libxl_cpu_bitmap_alloc (ctx, &cpumap,0 )) + goto out;if (vcpupin_parse (cpu, &cpumap)) - goto vcpupin_out1; + goto out; + +if (dryrun_only) { +libxl_cputopology *info =libxl_get_cpu_topology (ctx, &i); + +if (!info) { +fprintf (stderr,"libxl_get_cpu_topology failed.\n" ); + goto out; + } +libxl_cputopology_list_free (info, i); + +fprintf (stdout,"cpumap: " ); +print_bitmap (cpumap.map, i, stdout); +fprintf (stdout,"\n" ); + +if (ferror (stdout) ||fflush (stdout)) { +perror ("stdout" ); +exit (-1 ); + } + + rc =0 ; + goto out; + }if (vcpuid !=-1 ) {if (libxl_set_vcpuaffinity (ctx, domid, vcpuid, &cpumap) ==-1 ) {
@@ -4599,7 +4622,7 @@ static void vcpupin(uint32_t domid, const char *vcpu, char *cpu)else {if (!(vcpuinfo =libxl_list_vcpu (ctx, domid, &nb_vcpu, &i))) {fprintf (stderr,"libxl_list_vcpu failed.\n" ); - goto vcpupin_out1; + goto out; }for (i =0 ; i < nb_vcpu; i++) { if (libxl_set_vcpuaffinity(ctx, domid, vcpuinfo[i].vcpuid,
@@ -4610,10 +4633,11 @@ static void vcpupin(uint32_t domid, const char *vcpu, char *cpu) }libxl_vcpuinfo_list_free (vcpuinfo, nb_vcpu); } - vcpupin_out1: + + rc =0 ; + out:libxl_bitmap_dispose (&cpumap); - vcpupin_out: - ; +return rc; }int main_vcpupin (int argc,char **argv)
@@ -4624,8 +4648,7 @@ int main_vcpupin(int argc, char **argv)/* No options */ } -vcpupin (find_domain (argv[optind]), argv[optind+1 ] , argv[optind+2 ]); -return 0 ; +return vcpupin (find_domain (argv[optind]), argv[optind+1 ] , argv[optind+2 ]); }static void vcpuset (uint32_t domid,const char * nr_vcpus,int check_host)
tools/libxl/xl_cmdtable.c +1 -1
@@ -211,7 +211,7 @@ struct cmd_spec cmd_table[] = {"[Domain, ...]" , }, { "vcpu-pin", - &main_vcpupin,0 ,1 , + &main_vcpupin,1 ,1 ,"Set which CPUs a VCPU can use" , "<Domain> <VCPU|all> <CPUs|all>", },
PATCH v3 5/14 xl: test script for the cpumap parser (for vCPU pinning)
In reply to Dario FaggioliThis commit introduces "check-xl-vcpupin-parse" for helping verifying and debugging the (v)CPU bitmap parsing code in xl.
The script runs "xl -N vcpu-pin 0 all <some strings>" repeatedly, with various input strings, and checks that the output is as expected.
This is what the script can do:
# ./check-xl-vcpupin-parse -h usage: ./check-xl-vcpupin-parse [options]
Tests various vcpu-pinning strings. If run without arguments acts as follows:
- generates some test data and saves them in
check-xl-vcpupin-parse.data;
- tests all the generated configurations (reading them back from check-xl-vcpupin-parse.data).
An example of a test vector file is provided in
check-xl-vcpupin-parse.data-example.
Options:
-h prints this message
-r seed uses seed for initializing the rundom number generator
(default: the script PID)
-s string tries using string as a vcpu pinning configuration and
reports whether that succeeds or not
-o ofile save the test data in ofile
(default: check-xl-vcpupin-parse.data)
-i ifile read test data from ifile
An example test data file (generated on a 2 NUMA nodes, 16 CPUs host) is being provided in check-xl-vcpupin-parse.data-example.
---
Changes from v2 (of original series):
* killed the `sleep 1', as requested during review;
* allow for passing a custom randon seed, and report what is the actual random seed used, as requested during review;
* allow for testing for specific pinning configuration strings, as suggested during review;
* stores the test data in a file, after generating them, and read them back from there for actual testing, as suggested during review;
* allow for reading the test data from an existing test file instead than always generating new ones.
Changes from v1 (of original series):
* this was not there in v1, and adding it has been requested during review.
--- tools/libxl/check-xl-vcpupin-parse | 294 +++++++++++++++++++++++ tools/libxl/check-xl-vcpupin-parse.data-example | 53 ++++ 2 files changed, 347 insertions(+) create mode 100755 tools/libxl/check-xl-vcpupin-parse create mode 100644 tools/libxl/check-xl-vcpupin-parse.data-example
tools/libxl/check-xl-vcpupin-parse new file +294 -0
@@ -0,0 +1,294 @@ +#!/bin/bash + +set -e + +if [ -x ./xl ] ; then + export LD_LIBRARY_PATH=.:../libxc:../xenstore: + XL=./xl +else + XL=xl +fi + +fprefix=tmp.check-xl-vcpupin-parse +outfile=check-xl-vcpupin-parse.data + +usage () { +cat <<END +usage: $0 [options] + +Tests various vcpu-pinning strings. If run without arguments acts +as follows: + - generates some test data and saves them in $outfile; + - tests all the generated configurations (reading them back from + $outfile). + +An example of a test vector file is provided in ${outfile}-example. + +Options: + -h prints this message + -r seed uses seed for initializing the rundom number generator + (default: the script PID) + -s string tries using string as a vcpu pinning configuration and + reports whether that succeeds or not + -o ofile save the test data in ofile (default: $outfile) + -i ifile read test data from ifile +END +} + +expected () { + cat >$fprefix.expected +} + +# by default, re-seed with our PID +seed=$$ +failures=0 + +# Execute one test and check the result against the provided +# rc value and output +one () { + expected_rc=$1; shift + printf "test case %s...\n" "$*" + set +e + ${XL} -N vcpu-pin 0 all "$@" </dev/null >$fprefix.actual 2>/dev/null + actual_rc=$? + if [ $actual_rc != $expected_rc ]; then + diff -u $fprefix.expected $fprefix.actual + echo >&2 "test case \`$*' failed ($actual_rc $diff_rc)" + failures=$(( $failures + 1 )) + fi + set -e +} + +# Write an entry in the test vector file. Format is as follows: +# test-string*expected-rc*expected-output +write () { + printf "$1*$2*$3\n" >> $outfile +} + +complete () { + if [ "$failures" = 0 ]; then + echo all ok.; exit 0 + else + echo "$failures tests failed."; exit 1 + fi +} + +# Test a specific pinning string +string () { + expected_rc=$1; shift + printf "test case %s...\n" "$*" + set +e + ${XL} -N vcpu-pin 0 all "$@" &> /dev/null + actual_rc=$? + set -e + + if [ $actual_rc != $expected_rc ]; then + echo >&2 "test case \`$*' failed ($actual_rc)" + else + echo >&2 "test case \`$*' succeeded" + fi + + exit 0 +} + +# Read a test vector file (provided as $1) line by line and +# test all the entries it contains +run () +{ + while read line + do + if [ ${line:0:1} != '#' ]; then + test_string="`echo $line | cut -f1 -d'*'`" + exp_rc="`echo $line | cut -f2 -d'*'`" + exp_output="`echo $line | cut -f3 -d'*'`" + + expected <<END +$exp_output +END + one $exp_rc "$test_string" + fi + done < $1 + + complete + + exit 0 +} + +while getopts "hr:s:o:i:" option +do + case $option in + h) + usage + exit 0 + ;; + r) + seed=$OPTARG + ;; + s) + string 0 "$OPTARG" + ;; + o) + outfile=$OPTARG + ;; + i) + run $OPTARG + ;; + esac +done + +#---------- test data ---------- +# +nr_cpus=`xl info | grep nr_cpus | cut -f2 -d':'` +nr_nodes=`xl info | grep nr_nodes | cut -f2 -d':'` +nr_cpus_per_node=`xl info -n | sed '/cpu:/,/numa_info/!d' | head -n -1 | \ + awk '{print $4}' | uniq -c | tail -1 | awk '{print $1}'` +cat >$outfile <<END +# WARNING: some of these tests are topology based tests. +# Expect failures if the topology is not detected correctly +# detected topology: $nr_cpus CPUs, $nr_nodes nodes, $nr_cpus_per_node CPUs per node. +# +# seed used for random number generation: seed=${seed}. +# +# Format is as follows: +# test-string*expected-return-code*expected-output +# +END + +# Re-seed the random number generator +RANDOM=$seed + +echo "# Testing a wrong configuration" >> $outfile +write foo 255 "" + +echo "# Testing the 'all' syntax" >> $outfile +write "all" 0 "cpumap: all" +write "nodes:all" 0 "cpumap: all" +write "all,nodes:all" 0 "cpumap: all" +write "all,^nodes:0,all" 0 "cpumap: all" + +echo "# Testing the empty cpumap case" >> $outfile +write "^0" 0 "cpumap: none" + +echo "# A few attempts of pinning to just one random cpu" >> $outfile +if [ $nr_cpus -gt 1 ]; then + for i in `seq 0 3`; do + cpu=$(($RANDOM % nr_cpus)) + write "$cpu" 0 "cpumap: $cpu" + done +fi + +echo "# A few attempts of pinning to all but one random cpu" >> $outfile +if [ $nr_cpus -gt 2 ]; then + for i in `seq 0 3`; do + cpu=$(($RANDOM % nr_cpus)) + if [ $cpu -eq 0 ]; then + expected_range="1-$((nr_cpus - 1))" + elif [ $cpu -eq 1 ]; then + expected_range="0,2-$((nr_cpus - 1))" + elif [ $cpu -eq $((nr_cpus - 2)) ]; then + expected_range="0-$((cpu - 1)),$((nr_cpus - 1))" + elif [ $cpu -eq $((nr_cpus - 1)) ]; then + expected_range="0-$((nr_cpus - 2))" + else + expected_range="0-$((cpu - 1)),$((cpu + 1))-$((nr_cpus - 1))" + fi + write "all,^$cpu" 0 "cpumap: $expected_range" + done +fi + +echo "# A few attempts of pinning to a random range of cpus" >> $outfile +if [ $nr_cpus -gt 2 ]; then + for i in `seq 0 3`; do + cpua=$(($RANDOM % nr_cpus)) + range=$((nr_cpus - cpua)) + cpub=$(($RANDOM % range)) + cpubb=$((cpua + cpub)) + if [ $cpua -eq $cpubb ]; then + expected_range="$cpua" + else + expected_range="$cpua-$cpubb" + fi + write "$expected_range" 0 "cpumap: $expected_range" + done +fi + +echo "# A few attempts of pinning to just one random node" >> $outfile +if [ $nr_nodes -gt 1 ]; then + for i in `seq 0 3`; do + node=$(($RANDOM % nr_nodes)) + # this assumes that the first $nr_cpus_per_node (from cpu + # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node + # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node + # to 2*$nr_cpus_per_node-1) are assigned to the second node (node + # 1), etc. Expect failures if that is not the case. + write "nodes:$node" 0 "cpumap: $((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1)-1))" + done +fi + +echo "# A few attempts of pinning to all but one random node" >> $outfile +if [ $nr_nodes -gt 1 ]; then + for i in `seq 0 3`; do + node=$(($RANDOM % nr_nodes)) + # this assumes that the first $nr_cpus_per_node (from cpu + # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node + # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node + # to 2*$nr_cpus_per_node-1) are assigned to the second node (node + # 1), etc. Expect failures if that is not the case. + if [ $node -eq 0 ]; then + expected_range="$nr_cpus_per_node-$((nr_cpus - 1))" + elif [ $node -eq $((nr_nodes - 1)) ]; then + expected_range="0-$((nr_cpus - nr_cpus_per_node - 1))" + else + expected_range="0-$((nr_cpus_per_node*node-1)),$((nr_cpus_per_node*(node+1)))-$nr_cpus" + fi + write "all,^nodes:$node" 0 "cpumap: $expected_range" + done +fi + +echo "# A few attempts of pinning to a random range of nodes" >> $outfile +if [ $nr_nodes -gt 1 ]; then + for i in `seq 0 3`; do + nodea=$(($RANDOM % nr_nodes)) + range=$((nr_nodes - nodea)) + nodeb=$(($RANDOM % range)) + nodebb=$((nodea + nodeb)) + # this assumes that the first $nr_cpus_per_node (from cpu + # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node + # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node + # to 2*$nr_cpus_per_node-1) are assigned to the second node (node + # 1), etc. Expect failures if that is not the case. + if [ $nodea -eq 0 ] && [ $nodebb -eq $((nr_nodes - 1)) ]; then + expected_range="all" + else + expected_range="$((nr_cpus_per_node*nodea))-$((nr_cpus_per_node*(nodebb+1) - 1))" + fi + write "nodes:$nodea-$nodebb" 0 "cpumap: $expected_range" + done +fi + +echo "# A few attempts of pinning to a node but excluding one random cpu" >> $outfile +if [ $nr_nodes -gt 1 ]; then + for i in `seq 0 3`; do + node=$(($RANDOM % nr_nodes)) + # this assumes that the first $nr_cpus_per_node (from cpu + # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node + # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node + # to 2*$nr_cpus_per_node-1) are assigned to the second node (node + # 1), etc. Expect failures if that is not the case. + cpu=$(($RANDOM % nr_cpus_per_node + nr_cpus_per_node*node)) + if [ $cpu -eq $((nr_cpus_per_node*node)) ]; then + expected_range="$((nr_cpus_per_node*node + 1))-$((nr_cpus_per_node*(node+1) - 1))" + elif [ $cpu -eq $((nr_cpus_per_node*node + 1)) ]; then + expected_range="$((nr_cpus_per_node*node)),$((nr_cpus_per_node*node + 2))-$((nr_cpus_per_node*(node+1) - 1))" + elif [ $cpu -eq $((nr_cpus_per_node*(node+1) - 2)) ]; then + expected_range="$((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1) - 3)),$((nr_cpus_per_node*(node+1) - 1))" + elif [ $cpu -eq $((nr_cpus_per_node*(node+1) - 1)) ]; then + expected_range="$((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1) - 2))" + else + expected_range="$((nr_cpus_per_node*node))-$((cpu - 1)),$((cpu + 1))-$((nr_cpus_per_node*(node+1) - 1))" + fi + write "nodes:$node,^$cpu" 0 "cpumap: $expected_range" + done +fi + +run $outfile
tools/libxl/check-xl-vcpupin-parse.data-example new file +53 -0
53 lines not on this page · raw message
PATCH v3 6/14 xen: sched: rename v->cpu_affinity into v->cpu_hard_affinity
In reply to Dario Faggioliin order to distinguish it from the cpu_soft_affinity which will be introduced a later commit ("xen: sched: introduce soft-affinity and use it instead d->node-affinity").
This patch does not imply any functional change, it is basically the result of something like the following:
s/cpu_affinity/cpu_hard_affinity/g
s/cpu_affinity_tmp/cpu_hard_affinity_tmp/g
s/cpu_affinity_saved/cpu_hard_affinity_saved/g
---
Changes from v2:
* patch has been moved one step up in the series.
--- xen/arch/x86/traps.c | 11 ++++++----- xen/common/domain.c | 22 +++++++++++----------- xen/common/domctl.c | 2 +- xen/common/keyhandler.c | 2 +- xen/common/sched_credit.c | 12 ++++++------ xen/common/sched_sedf.c | 2 +- xen/common/schedule.c | 21 +++++++++++---------- xen/common/wait.c | 4 ++-- xen/include/xen/sched.h | 8 ++++---- 9 files changed, 43 insertions(+), 41 deletions(-)
xen/arch/x86/traps.c +6 -5
@@ -3083,7 +3083,8 @@ static void nmi_mce_softirq(void)/* Set the tmp value unconditionally, so that * the check in the iret hypercall works. */ -cpumask_copy (st->vcpu->cpu_affinity_tmp, st->vcpu->cpu_affinity); +cpumask_copy (st->vcpu->cpu_hard_affinity_tmp, + st->vcpu->cpu_hard_affinity);if ((cpu != st->processor) || (st->processor != st->vcpu->processor))
@@ -3118,11 +3119,11 @@ void async_exception_cleanup(struct vcpu *curr)return ;/* Restore affinity. */ -if ( !cpumask_empty (curr->cpu_affinity_tmp) && - !cpumask_equal (curr->cpu_affinity_tmp, curr->cpu_affinity) ) +if ( !cpumask_empty (curr->cpu_hard_affinity_tmp) && + !cpumask_equal (curr->cpu_hard_affinity_tmp, curr->cpu_hard_affinity) ) { -vcpu_set_affinity (curr, curr->cpu_affinity_tmp); -cpumask_clear (curr->cpu_affinity_tmp); +vcpu_set_affinity (curr, curr->cpu_hard_affinity_tmp); +cpumask_clear (curr->cpu_hard_affinity_tmp); }if ( !(curr->async_exception_mask & (curr->async_exception_mask -1 )) )
xen/common/domain.c +11 -11
@@ -125,9 +125,9 @@ struct vcpu *alloc_vcpu(tasklet_init (&v->continue_hypercall_tasklet,NULL ,0 ); -if ( !zalloc_cpumask_var (&v->cpu_affinity) || - !zalloc_cpumask_var (&v->cpu_affinity_tmp) || - !zalloc_cpumask_var (&v->cpu_affinity_saved) || +if ( !zalloc_cpumask_var (&v->cpu_hard_affinity) || + !zalloc_cpumask_var (&v->cpu_hard_affinity_tmp) || + !zalloc_cpumask_var (&v->cpu_hard_affinity_saved) || !zalloc_cpumask_var (&v->vcpu_dirty_cpumask) ) goto fail_free;
@@ -156,9 +156,9 @@ struct vcpu *alloc_vcpu( fail_wq:destroy_waitqueue_vcpu (v); fail_free: -free_cpumask_var (v->cpu_affinity); -free_cpumask_var (v->cpu_affinity_tmp); -free_cpumask_var (v->cpu_affinity_saved); +free_cpumask_var (v->cpu_hard_affinity); +free_cpumask_var (v->cpu_hard_affinity_tmp); +free_cpumask_var (v->cpu_hard_affinity_saved);free_cpumask_var (v->vcpu_dirty_cpumask);free_vcpu_struct (v);return NULL ;
@@ -371,7 +371,7 @@ void domain_update_node_affinity(struct domain *d) for_each_vcpu ( d, v ) { -cpumask_and (online_affinity, v->cpu_affinity, online); +cpumask_and (online_affinity, v->cpu_hard_affinity, online);cpumask_or (cpumask, cpumask, online_affinity); }
@@ -734,9 +734,9 @@ static void complete_domain_destroy(struct rcu_head *head)for ( i = d->max_vcpus -1 ; i >=0 ; i-- )if ( (v = d->vcpu[i]) !=NULL ) { -free_cpumask_var (v->cpu_affinity); -free_cpumask_var (v->cpu_affinity_tmp); -free_cpumask_var (v->cpu_affinity_saved); +free_cpumask_var (v->cpu_hard_affinity); +free_cpumask_var (v->cpu_hard_affinity_tmp); +free_cpumask_var (v->cpu_hard_affinity_saved);free_cpumask_var (v->vcpu_dirty_cpumask);free_vcpu_struct (v); }
@@ -875,7 +875,7 @@ int vcpu_reset(struct vcpu *v) v->async_exception_mask =0 ;memset (v->async_exception_state,0 ,sizeof (v->async_exception_state));#endif -cpumask_clear (v->cpu_affinity_tmp); +cpumask_clear (v->cpu_hard_affinity_tmp);clear_bit (_VPF_blocked, &v->pause_flags);clear_bit (_VPF_in_reset, &v->pause_flags);
xen/common/domctl.c +1 -1
@@ -629,7 +629,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)else { ret =cpumask_to_xenctl_bitmap ( - &op->u.vcpuaffinity.cpumap, v->cpu_affinity); + &op->u.vcpuaffinity.cpumap, v->cpu_hard_affinity); } }break ;
xen/common/keyhandler.c +1 -1
@@ -296,7 +296,7 @@ static void dump_domains(unsigned char key) !vcpu_event_delivery_is_enabled(v));cpuset_print (tmpstr,sizeof (tmpstr), v->vcpu_dirty_cpumask);printk ("dirty_cpus=%s " , tmpstr); -cpuset_print (tmpstr,sizeof (tmpstr), v->cpu_affinity); +cpuset_print (tmpstr,sizeof (tmpstr), v->cpu_hard_affinity);printk ("cpu_affinity=%s\n" , tmpstr);printk (" pause_count=%d pause_flags=%lx\n" ,atomic_read (&v->pause_count), v->pause_flags);
xen/common/sched_credit.c +6 -6
@@ -332,13 +332,13 @@ csched_balance_cpumask(const struct vcpu *vc, int step, cpumask_t *mask)if ( step ==CSCHED_BALANCE_NODE_AFFINITY ) {cpumask_and (mask,CSCHED_DOM (vc->domain)->node_affinity_cpumask, - vc->cpu_affinity); + vc->cpu_hard_affinity);if (unlikely (cpumask_empty (mask)) ) -cpumask_copy (mask, vc->cpu_affinity); +cpumask_copy (mask, vc->cpu_hard_affinity); }else /* step == CSCHED_BALANCE_CPU_AFFINITY */ -cpumask_copy (mask, vc->cpu_affinity); +cpumask_copy (mask, vc->cpu_hard_affinity); }static void burn_credits (struct csched_vcpu *svc,s_time_t now)
@@ -407,7 +407,7 @@ __runq_tickle(unsigned int cpu, struct csched_vcpu *new)if ( balance_step ==CSCHED_BALANCE_NODE_AFFINITY && !__vcpu_has_node_affinity (new->vcpu, - new->vcpu->cpu_affinity) ) + new->vcpu->cpu_hard_affinity) )continue ;/* Are there idlers suitable for new (for this balance step)? */
@@ -642,7 +642,7 @@ _csched_cpu_pick(const struct scheduler *ops, struct vcpu *vc, bool_t commit)/* Store in cpus the mask of online cpus on which the domain can run */ online =cpupool_scheduler_cpumask (vc->domain->cpupool); -cpumask_and (&cpus, vc->cpu_affinity, online); +cpumask_and (&cpus, vc->cpu_hard_affinity, online);for_each_csched_balance_step ( balance_step ) {
@@ -1498,7 +1498,7 @@ csched_runq_steal(int peer_cpu, int cpu, int pri, int balance_step)* or counter. */ if ( balance_step ==CSCHED_BALANCE_NODE_AFFINITY - && !__vcpu_has_node_affinity (vc, vc->cpu_affinity) ) + && !__vcpu_has_node_affinity (vc, vc->cpu_hard_affinity) )continue ;csched_balance_cpumask (vc, balance_step, csched_balance_mask);
xen/common/sched_sedf.c +1 -1
@@ -396,7 +396,7 @@ static int sedf_pick_cpu(const struct scheduler *ops, struct vcpu *v)cpumask_t *online; online =cpupool_scheduler_cpumask (v->domain->cpupool); -cpumask_and (&online_affinity, v->cpu_affinity, online); +cpumask_and (&online_affinity, v->cpu_hard_affinity, online);return cpumask_cycle (v->vcpu_id %cpumask_weight (&online_affinity) -1 , &online_affinity); }
xen/common/schedule.c +11 -10
@@ -194,9 +194,9 @@ int sched_init_vcpu(struct vcpu *v, unsigned int processor)*/ v->processor = processor;if (is_idle_domain (d) || d->is_pinned ) -cpumask_copy (v->cpu_affinity,cpumask_of (processor)); +cpumask_copy (v->cpu_hard_affinity,cpumask_of (processor));else -cpumask_setall (v->cpu_affinity); +cpumask_setall (v->cpu_hard_affinity);/* Initialise the per-vcpu timers. */ init_timer(&v->periodic_timer, vcpu_periodic_timer_fn,
@@ -285,7 +285,7 @@ int sched_move_domain(struct domain *d, struct cpupool *c)migrate_timer (&v->singleshot_timer, new_p);migrate_timer (&v->poll_timer, new_p); -cpumask_setall (v->cpu_affinity); +cpumask_setall (v->cpu_hard_affinity); lock =vcpu_schedule_lock_irq (v); v->processor = new_p;
@@ -457,7 +457,7 @@ static void vcpu_migrate(struct vcpu *v)*/ if ( pick_called && (new_lock ==per_cpu (schedule_data, new_cpu).schedule_lock) && -cpumask_test_cpu (new_cpu, v->cpu_affinity) && +cpumask_test_cpu (new_cpu, v->cpu_hard_affinity) &&cpumask_test_cpu (new_cpu, v->domain->cpupool->cpu_valid) )break ;
@@ -561,7 +561,7 @@ void restore_vcpu_affinity(struct domain *d) {printk (XENLOG_DEBUG "Restoring affinity for d%dv%d\n" , d->domain_id, v->vcpu_id); -cpumask_copy (v->cpu_affinity, v->cpu_affinity_saved); +cpumask_copy (v->cpu_hard_affinity, v->cpu_hard_affinity_saved); v->affinity_broken =0 ; }
@@ -604,20 +604,21 @@ int cpu_disable_scheduler(unsigned int cpu)unsigned long flags;spinlock_t *lock =vcpu_schedule_lock_irqsave (v, &flags); -cpumask_and (&online_affinity, v->cpu_affinity, c->cpu_valid); +cpumask_and (&online_affinity, v->cpu_hard_affinity, c->cpu_valid);if (cpumask_empty (&online_affinity) && -cpumask_test_cpu (cpu, v->cpu_affinity) ) +cpumask_test_cpu (cpu, v->cpu_hard_affinity) ) {printk (XENLOG_DEBUG "Breaking affinity for d%dv%d\n" , d->domain_id, v->vcpu_id);if (system_state == SYS_STATE_suspend) { -cpumask_copy (v->cpu_affinity_saved, v->cpu_affinity); +cpumask_copy (v->cpu_hard_affinity_saved, + v->cpu_hard_affinity); v->affinity_broken =1 ; } -cpumask_setall (v->cpu_affinity); +cpumask_setall (v->cpu_hard_affinity); }if ( v->processor == cpu )
@@ -665,7 +666,7 @@ int vcpu_set_affinity(struct vcpu *v, const cpumask_t *affinity) lock =vcpu_schedule_lock_irq (v); -cpumask_copy (v->cpu_affinity, affinity); +cpumask_copy (v->cpu_hard_affinity, affinity);/* Always ask the scheduler to re-evaluate placement * when changing the affinity */
xen/common/wait.c +2 -2
@@ -134,7 +134,7 @@ static void __prepare_to_wait(struct waitqueue_vcpu *wqv)/* Save current VCPU affinity; force wakeup on *this* CPU only. */ wqv->wakeup_cpu =smp_processor_id (); -cpumask_copy (&wqv->saved_affinity, curr->cpu_affinity); +cpumask_copy (&wqv->saved_affinity, curr->cpu_hard_affinity);if (vcpu_set_affinity (curr,cpumask_of (wqv->wakeup_cpu)) ) {gdprintk (XENLOG_ERR ,"Unable to set vcpu affinity\n" );
@@ -183,7 +183,7 @@ void check_wakeup_from_wait(void) {/* Re-set VCPU affinity and re-enter the scheduler. */ struct vcpu *curr = current; -cpumask_copy (&wqv->saved_affinity, curr->cpu_affinity); +cpumask_copy (&wqv->saved_affinity, curr->cpu_hard_affinity);if (vcpu_set_affinity (curr,cpumask_of (wqv->wakeup_cpu)) ) {gdprintk (XENLOG_ERR ,"Unable to set vcpu affinity\n" );
xen/include/xen/sched.h +4 -4
@@ -192,11 +192,11 @@ struct vcpuspinlock_t virq_lock;/* Bitmask of CPUs on which this VCPU may run. */ -cpumask_var_t cpu_affinity; +cpumask_var_t cpu_hard_affinity;/* Used to change affinity temporarily. */ -cpumask_var_t cpu_affinity_tmp; +cpumask_var_t cpu_hard_affinity_tmp;/* Used to restore affinity across S3. */ -cpumask_var_t cpu_affinity_saved; +cpumask_var_t cpu_hard_affinity_saved;/* Bitmask of CPUs which are holding onto this VCPU's state. */ cpumask_var_t vcpu_dirty_cpumask;
@@ -792,7 +792,7 @@ void watchdog_domain_destroy(struct domain *d);#define has_hvm_container_domain (d) ((d)->guest_type != guest_type_pv)#define has_hvm_container_vcpu (v) (has_hvm_container_domain((v)->domain))#define is_pinned_vcpu (v) ((v)->domain->is_pinned || \ - cpumask_weight((v)->cpu_affinity) == 1) + cpumask_weight((v)->cpu_hard_affinity) == 1)#ifdef HAS_PASSTHROUGH #define need_iommu (d) ((d)->need_iommu)#else
PATCH v3 7/14 xen: sched: introduce soft-affinity and use it instead d->node-affinity
In reply to Dario FaggioliBefore this change, each vcpu had its own vcpu-affinity (in v->cpu_affinity), representing the set of pcpus where the vcpu is allowed to run. Since when NUMA-aware scheduling was introduced the (credit1 only, for now) scheduler also tries as much as it can to run all the vcpus of a domain on one of the nodes that constitutes the domain's node-affinity.
The idea here is making the mechanism more general by:
* allowing for this 'preference' for some pcpus/nodes to be expressed on a per-vcpu basis, instead than for the domain as a whole. That is to say, each vcpu should have its own set of preferred pcpus/nodes, instead than it being the very same for all the vcpus of the domain;
* generalizing the idea of 'preferred pcpus' to not only NUMA awareness and support. That is to say, independently from it being or not (mostly) useful on NUMA systems, it should be possible to specify, for each vcpu, a set of pcpus where it prefers to run (in addition, and possibly unrelated to, the set of pcpus where it is allowed to run).
We will be calling this set of *preferred* pcpus the vcpu's soft affinity, and this changes introduce it, and starts using it for scheduling, replacing the indirect use of the domain's NUMA node-affinity. This is more general, as soft affinity does not have to be related to NUMA. Nevertheless, it allows to achieve the same results of NUMA-aware scheduling, just by making soft affinity equal to the domain's node affinity, for all the vCPUs (e.g., from the toolstack).
This also means renaming most of the NUMA-aware scheduling related functions, in credit1, to something more generic, hinting toward the concept of soft affinity rather than directly to NUMA awareness.
As a side effects, this simplifies the code quit a bit. In fact, prior to this change, we needed to cache the translation of d->node_affinity (which is a nodemask_t) to a cpumask_t, since that is what scheduling decisions require (we used to keep it in node_affinity_cpumask). This, and all the complicated logic required to keep it updated, is not necessary any longer.
The high level description of NUMA placement and scheduling in docs/misc/xl-numa-placement.markdown is being updated too, to match the new architecture.
---
Changes from v2:
* this patch folds patches 6 ("xen: sched: make space for cpu_soft_affinity") and 10 ("xen: sched: use soft-affinity instead of domain's node-affinity"), as suggested during review. 'Reviewed-by' from George is there since both patch 6 and 10 had it, and I didn't do anything else than squashing them.
Changes from v1:
* in v1, "7/12 xen: numa-sched: use per-vcpu node-affinity for actual scheduling" was doing something very similar to this patch.
--- docs/misc/xl-numa-placement.markdown | 148 ++++++++++++++++++++++----------- xen/common/domain.c | 5 + xen/common/keyhandler.c | 2 xen/common/sched_credit.c | 153 +++++++++++++--------------------- xen/common/schedule.c | 3 + xen/include/xen/sched.h | 3 + 6 files changed, 168 insertions(+), 146 deletions(-)
docs/misc/xl-numa-placement.markdown +97 -51
@@ -12,13 +12,6 @@ is quite more complex and slow. On these machines, a NUMA node is usually defined as a set of processor cores (typically a physical CPU package) and the memory directly attached to the set of cores. -The Xen hypervisor deals with NUMA machines by assigning to each domain -a "node affinity", i.e., a set of NUMA nodes of the host from which they -get their memory allocated. Also, even if the node affinity of a domain -is allowed to change on-line, it is very important to "place" the domain -correctly when it is fist created, as the most of its memory is allocated -at that time and can not (for now) be moved easily. - NUMA awareness becomes very important as soon as many domains start running memory-intensive workloads on a shared host. In fact, the cost of accessing non node-local memory locations is very high, and the
@@ -27,14 +20,37 @@ performance degradation is likely to be noticeable. For more information, have a look at the [Xen NUMA Introduction][numa_intro] page on the Wiki. +## Xen and NUMA machines: the concept of _node-affinity_ ## + +The Xen hypervisor deals with NUMA machines throughout the concept of +_node-affinity_. The node-affinity of a domain is the set of NUMA nodes +of the host where the memory for the domain is being allocated (mostly, +at domain creation time). This is, at least in principle, different and +unrelated with the vCPU (hard and soft, see below) scheduling affinity, +which instead is the set of pCPUs where the vCPU is allowed (or prefers) +to run. + +Of course, despite the fact that they belong to and affect different +subsystems, the domain node-affinity and the vCPUs affinity are not +completely independent. +In fact, if the domain node-affinity is not explicitly specified by the +user, via the proper libxl calls or xl config item, it will be computed +basing on the vCPUs' scheduling affinity. + +Notice that, even if the node affinity of a domain may change on-line, +it is very important to "place" the domain correctly when it is fist +created, as the most of its memory is allocated at that time and can +not (for now) be moved easily. + ### Placing via pinning and cpupools ### -The simplest way of placing a domain on a NUMA node is statically pinning -the domain's vCPUs to the pCPUs of the node. This goes under the name of -CPU affinity and can be set through the "cpus=" option in the config file -(more about this below). Another option is to pool together the pCPUs -spanning the node and put the domain in such a cpupool with the "pool=" -config option (as documented in our [Wiki][cpupools_howto]). +The simplest way of placing a domain on a NUMA node is setting the hard +scheduling affinity of the domain's vCPUs to the pCPUs of the node. This +also goes under the name of vCPU pinning, and can be done through the +"cpus=" option in the config file (more about this below). Another option +is to pool together the pCPUs spanning the node and put the domain in +such a _cpupool_ with the "pool=" config option (as documented in our +[Wiki][cpupools_howto]). In both the above cases, the domain will not be able to execute outside the specified set of pCPUs for any reasons, even if all those pCPUs are
@@ -45,24 +61,45 @@ may come at he cost of some load imbalances. ### NUMA aware scheduling ### -If the credit scheduler is in use, the concept of node affinity defined -above does not only apply to memory. In fact, starting from Xen 4.3, the -scheduler always tries to run the domain's vCPUs on one of the nodes in -its node affinity. Only if that turns out to be impossible, it will just -pick any free pCPU. - -This is, therefore, something more flexible than CPU affinity, as a domain -can still run everywhere, it just prefers some nodes rather than others. -Locality of access is less guaranteed than in the pinning case, but that -comes along with better chances to exploit all the host resources (e.g., -the pCPUs). - -In fact, if all the pCPUs in a domain's node affinity are busy, it is -possible for the domain to run outside of there, but it is very likely that -slower execution (due to remote memory accesses) is still better than no -execution at all, as it would happen with pinning. For this reason, NUMA -aware scheduling has the potential of bringing substantial performances -benefits, although this will depend on the workload. +If using the credit1 scheduler, and starting from Xen 4.3, the scheduler +itself always tries to run the domain's vCPUs on one of the nodes in +its node-affinity. Only if that turns out to be impossible, it will just +pick any free pCPU. Locality of access is less guaranteed than in the +pinning case, but that comes along with better chances to exploit all +the host resources (e.g., the pCPUs). + +Starting from Xen 4.4, credit1 supports two forms of affinity: hard and +soft, both on a per-vCPU basis. This means each vCPU can have its own +soft affinity, stating where such vCPU prefers to execute on. This is +less strict than what it (also starting from 4.4) is called hard affinity, +as the vCPU can potentially run everywhere, it just prefers some pCPUs +rather than others. +In Xen 4.4, therefore, NUMA-aware scheduling is achieved by matching the +soft affinity of the vCPUs of a domain with its node-affinity. + +In fact, as it was for 4.3, if all the pCPUs in a vCPU's soft affinity +are busy, it is possible for the domain to run outside from there. The +idea is that slower execution (due to remote memory accesses) is still +better than no execution at all (as it would happen with pinning). For +this reason, NUMA aware scheduling has the potential of bringing +substantial performances benefits, although this will depend on the +workload. + +Notice that, for each vCPU, the following three scenarios are possbile: + + * a vCPU *is pinned* to some pCPUs and *does not have* any soft affinity + In this case, the vCPU is always scheduled on one of the pCPUs to which + it is pinned, without any specific peference among them. + * a vCPU *has* its own soft affinity and *is not* pinned to any particular + pCPU. In this case, the vCPU can run on every pCPU. Nevertheless, the + scheduler will try to have it running on one of the pCPUs in its soft + affinity; + * a vCPU *has* its own vCPU soft affinity and *is also* pinned to some + pCPUs. In this case, the vCPU is always scheduled on one of the pCPUs + onto which it is pinned, with, among them, a preference for the ones + that also forms its soft affinity. In case pinning and soft affinity + form two disjoint sets of pCPUs, pinning "wins", and the soft affinity + is just ignored. ## Guest placement in xl ##
@@ -71,25 +108,23 @@ both manual or automatic placement of them across the host's NUMA nodes. Note that xm/xend does a very similar thing, the only differences being the details of the heuristics adopted for automatic placement (see below), -and the lack of support (in both xm/xend and the Xen versions where that\ +and the lack of support (in both xm/xend and the Xen versions where that was the default toolstack) for NUMA aware scheduling. ### Placing the guest manually ### Thanks to the "cpus=" option, it is possible to specify where a domain should be created and scheduled on, directly in its config file. This -affects NUMA placement and memory accesses as the hypervisor constructs -the node affinity of a VM basing right on its CPU affinity when it is -created. +affects NUMA placement and memory accesses as, in this case, the +hypervisor constructs the node-affinity of a VM basing right on its +vCPU pinning when it is created. This is very simple and effective, but requires the user/system -administrator to explicitly specify affinities for each and every domain, +administrator to explicitly specify the pinning for each and every domain, or Xen won't be able to guarantee the locality for their memory accesses. -Notice that this also pins the domain's vCPUs to the specified set of -pCPUs, so it not only sets the domain's node affinity (its memory will -come from the nodes to which the pCPUs belong), but at the same time -forces the vCPUs of the domain to be scheduled on those same pCPUs. +That, of course, also mean the vCPUs of the domain will only be able to +execute on those same pCPUs. ### Placing the guest automatically ###
@@ -97,7 +132,9 @@ If no "cpus=" option is specified in the config file, libxl tries to figure out on its own on which node(s) the domain could fit best. If it finds one (some), the domain's node affinity get set to there, and both memory allocations and NUMA aware scheduling (for the credit -scheduler and starting from Xen 4.3) will comply with it. +scheduler and starting from Xen 4.3) will comply with it. Starting from +Xen 4.4, this also means that the mask resulting from this "fitting" +procedure will become the soft affinity of all the vCPUs of the domain. It is worthwhile noting that optimally fitting a set of VMs on the NUMA nodes of an host is an incarnation of the Bin Packing Problem. In fact,
@@ -142,34 +179,43 @@ any placement from happening: libxl_defbool_set(&domain_build_info->numa_placement, false); -Also, if `numa_placement` is set to `true`, the domain must not -have any CPU affinity (i.e., `domain_build_info->cpumap` must -have all its bits set, as it is by default), or domain creation -will fail returning `ERROR_INVAL`. +Also, if `numa_placement` is set to `true`, the domain's vCPUs must +not be pinned (i.e., `domain_build_info->cpumap` must have all its +bits set, as it is by default), or domain creation will fail with +`ERROR_INVAL`. Starting from Xen 4.3, in case automatic placement happens (and is -successful), it will affect the domain's node affinity and _not_ its -CPU affinity. Namely, the domain's vCPUs will not be pinned to any +successful), it will affect the domain's node-affinity and _not_ its +vCPU pinning. Namely, the domain's vCPUs will not be pinned to any pCPU on the host, but the memory from the domain will come from the selected node(s) and the NUMA aware scheduling (if the credit scheduler -is in use) will try to keep the domain there as much as possible. +is in use) will try to keep the domain's vCPUs there as much as possible. Besides than that, looking and/or tweaking the placement algorithm search "Automatic NUMA placement" in libxl\_internal.h. Note this may change in future versions of Xen/libxl. +## Xen < 4.4 ## + +The concept of vCPU soft affinity has been introduced for the first time +in Xen 4.4. In 4.3, it is the domain's node-affinity that drives the +NUMA-aware scheduler. The main difference is soft affinity is per-vCPU, +and so each vCPU can have its own mask of pCPUs, while node-affinity is +per-domain, that is the equivalent of having all the vCPUs with the same +soft affinity. + ## Xen < 4.3 ## As NUMA aware scheduling is a new feature of Xen 4.3, things are a little bit different for earlier version of Xen. If no "cpus=" option is specified and Xen 4.2 is in use, the automatic placement algorithm still runs, but the results is used to _pin_ the vCPUs of the domain to the output node(s). -This is consistent with what was happening with xm/xend, which were also -affecting the domain's CPU affinity. +This is consistent with what was happening with xm/xend. On a version of Xen earlier than 4.2, there is not automatic placement at -all in xl or libxl, and hence no node or CPU affinity being affected. +all in xl or libxl, and hence no node-affinity, vCPU affinity or pinning +being introduced/modified. ## Limitations ##
xen/common/domain.c +3 -2
@@ -128,6 +128,7 @@ struct vcpu *alloc_vcpu(if ( !zalloc_cpumask_var (&v->cpu_hard_affinity) || !zalloc_cpumask_var (&v->cpu_hard_affinity_tmp) || !zalloc_cpumask_var (&v->cpu_hard_affinity_saved) || + !zalloc_cpumask_var (&v->cpu_soft_affinity) || !zalloc_cpumask_var (&v->vcpu_dirty_cpumask) ) goto fail_free;
@@ -159,6 +160,7 @@ struct vcpu *alloc_vcpu(free_cpumask_var (v->cpu_hard_affinity);free_cpumask_var (v->cpu_hard_affinity_tmp);free_cpumask_var (v->cpu_hard_affinity_saved); +free_cpumask_var (v->cpu_soft_affinity);free_cpumask_var (v->vcpu_dirty_cpumask);free_vcpu_struct (v);return NULL ;
@@ -390,8 +392,6 @@ void domain_update_node_affinity(struct domain *d)node_set (node, d->node_affinity); } -sched_set_node_affinity (d, &d->node_affinity); -spin_unlock (&d->node_affinity_lock);free_cpumask_var (online_affinity);
@@ -737,6 +737,7 @@ static void complete_domain_destroy(struct rcu_head *head)free_cpumask_var (v->cpu_hard_affinity);free_cpumask_var (v->cpu_hard_affinity_tmp);free_cpumask_var (v->cpu_hard_affinity_saved); +free_cpumask_var (v->cpu_soft_affinity);free_cpumask_var (v->vcpu_dirty_cpumask);free_vcpu_struct (v); }
xen/common/keyhandler.c +2 -0
@@ -298,6 +298,8 @@ static void dump_domains(unsigned char key)printk ("dirty_cpus=%s " , tmpstr);cpuset_print (tmpstr,sizeof (tmpstr), v->cpu_hard_affinity);printk ("cpu_affinity=%s\n" , tmpstr); +cpuset_print (tmpstr,sizeof (tmpstr), v->cpu_soft_affinity); +printk ("cpu_soft_affinity=%s\n" , tmpstr);printk (" pause_count=%d pause_flags=%lx\n" ,atomic_read (&v->pause_count), v->pause_flags);arch_dump_vcpu_info (v);
xen/common/sched_credit.c +60 -93
283 lines not on this page · raw message
xen/common/schedule.c +3 -0
@@ -198,6 +198,8 @@ int sched_init_vcpu(struct vcpu *v, unsigned int processor)else cpumask_setall (v->cpu_hard_affinity); +cpumask_setall (v->cpu_soft_affinity); +/* Initialise the per-vcpu timers. */ init_timer (&v->periodic_timer, vcpu_periodic_timer_fn, v, v->processor);
@@ -286,6 +288,7 @@ int sched_move_domain(struct domain *d, struct cpupool *c)migrate_timer (&v->poll_timer, new_p);cpumask_setall (v->cpu_hard_affinity); +cpumask_setall (v->cpu_soft_affinity); lock =vcpu_schedule_lock_irq (v); v->processor = new_p;
xen/include/xen/sched.h +3 -0
@@ -198,6 +198,9 @@ struct vcpu/* Used to restore affinity across S3. */ cpumask_var_t cpu_hard_affinity_saved; +/* Bitmask of CPUs on which this VCPU prefers to run. */ +cpumask_var_t cpu_soft_affinity; +/* Bitmask of CPUs which are holding onto this VCPU's state. */ cpumask_var_t vcpu_dirty_cpumask;
PATCH v3 8/14 xen: derive NUMA node affinity from hard and soft CPU affinity
In reply to Dario Faggioliif a domain's NUMA node-affinity (which is what controls memory allocations) is provided by the user/toolstack, it just is not touched. However, if the user does not say anything, leaving it all to Xen, let's compute it in the following way:
1. cpupool's cpus & hard-affinity & soft-affinity
2. if (1) is empty: cpupool's cpus & hard-affinity
This guarantees memory to be allocated from the narrowest possible set of NUMA nodes, ad makes it relatively easy to set up NUMA-aware scheduling on top of soft affinity.
---
Changes from v2:
* the loop computing the mask is now only executed when it really is useful, as suggested during review;
* the loop, and all the cpumask handling is optimized, in a way similar to what was suggested during review.
--- xen/common/domain.c | 62 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 22 deletions(-)
xen/common/domain.c +40 -22
@@ -353,17 +353,17 @@ struct domain *domain_create(void domain_update_node_affinity (struct domain *d) { -cpumask_var_t cpumask; -cpumask_var_t online_affinity; +cpumask_var_t dom_cpumask, dom_cpumask_soft; +cpumask_t *dom_affinity;const cpumask_t *online;struct vcpu *v; -unsigned int node; +unsigned int cpu; -if ( !zalloc_cpumask_var (&cpumask) ) +if ( !zalloc_cpumask_var (&dom_cpumask) )return ; -if ( !alloc_cpumask_var (&online_affinity) ) +if ( !zalloc_cpumask_var (&dom_cpumask_soft) ) { -free_cpumask_var (cpumask); +free_cpumask_var (dom_cpumask);return ; }
@@ -371,31 +371,49 @@ void domain_update_node_affinity(struct domain *d)spin_lock (&d->node_affinity_lock); - for_each_vcpu ( d, v ) - { -cpumask_and (online_affinity, v->cpu_hard_affinity, online); -cpumask_or (cpumask, cpumask, online_affinity); - } -/* -* If d->auto_node_affinity is true, the domain's node-affinity mask -* (d->node_affinity) is automaically computed from all the domain's -* vcpus' vcpu-affinity masks (the union of which we have just built -* above in cpumask). OTOH, if d->auto_node_affinity is false, we -* must leave the node-affinity of the domain alone. +* If d->auto_node_affinity is true, let's compute the domain's +* node-affinity and update d->node_affinity accordingly. if false, +* just leave d->auto_node_affinity alone. */ if ( d->auto_node_affinity ) { +/* +* We want the narrowest possible set of pcpus (to get the narowest +* possible set of nodes). What we need is the cpumask of where the +* domain can run (the union of the hard affinity of all its vcpus), +* and the full mask of where it would prefer to run (the union of +* the soft affinity of all its various vcpus). Let's build them. +*/ +cpumask_clear (dom_cpumask); +cpumask_clear (dom_cpumask_soft); + for_each_vcpu ( d, v ) + { +cpumask_or (dom_cpumask, dom_cpumask, v->cpu_hard_affinity); +cpumask_or (dom_cpumask_soft, dom_cpumask_soft, + v->cpu_soft_affinity); + } +/* Filter out non-online cpus */ +cpumask_and (dom_cpumask, dom_cpumask, online); +/* And compute the intersection between hard, online and soft */ +cpumask_and (dom_cpumask_soft, dom_cpumask_soft, dom_cpumask); + +/* +* If not empty, the intersection of hard, soft and online is the +* narrowest set we want. If empty, we fall back to hard&online. +*/ + dom_affinity =cpumask_empty (dom_cpumask_soft) ? + dom_cpumask : dom_cpumask_soft; +nodes_clear (d->node_affinity); - for_each_online_node ( node ) - if ( cpumask_intersects(&node_to_cpumask(node), cpumask) ) - node_set(node, d->node_affinity); +for_each_cpu ( cpu, dom_affinity ) +node_set (cpu_to_node (cpu), d->node_affinity); }spin_unlock (&d->node_affinity_lock); -free_cpumask_var (online_affinity); -free_cpumask_var (cpumask); +free_cpumask_var (dom_cpumask_soft); +free_cpumask_var (dom_cpumask); }
Re: [PATCH v3 08/14] xen: derive NUMA node affinity from hard and soft CPU affinity
Quoted 6 lines · Dario Faggioli
if a domain's NUMA node-affinity (which is what controls memory allocations) is provided by the user/toolstack, it just is not touched. However, if the user does not say anything, leaving it all to Xen, let's compute it in the following way:
Quoted 8 lines
1. cpupool's cpus & hard-affinity & soft-affinity
2. if (1) is empty: cpupool's cpus & hard-affinityThis guarantees memory to be allocated from the narrowest possible set of NUMA nodes, ad makes it relatively easy to set up NUMA-aware scheduling on top of soft affinity.
Signed-off-by Dario Faggioli <[email protected]>
Quoted 105 lines
---
Changes from v2:
* the loop computing the mask is now only executed whenit really is useful, as suggested during review; * the loop, and all the cpumask handling is optimized, in a way similar to what was suggested during review. --- xen/common/domain.c | 62 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 22 deletions(-)xen/common/domain.c +40
-22@@ -353,17 +353,17 @@ struct domain *domain_create(void domain_update_node_affinity (struct domain *d) { -cpumask_var_t cpumask; -cpumask_var_t online_affinity; +cpumask_var_t dom_cpumask, dom_cpumask_soft; +cpumask_t *dom_affinity;const cpumask_t *online;struct vcpu *v; -unsigned int node; +unsigned int cpu; -if ( !zalloc_cpumask_var (&cpumask) ) +if ( !zalloc_cpumask_var (&dom_cpumask) )return ; -if ( !alloc_cpumask_var (&online_affinity) ) +if ( !zalloc_cpumask_var (&dom_cpumask_soft) ) { -free_cpumask_var (cpumask); +free_cpumask_var (dom_cpumask);return ; }@@ -371,31 +371,49 @@ void domain_update_node_affinity(struct domain *d)spin_lock (&d->node_affinity_lock); - for_each_vcpu ( d, v ) - { -cpumask_and (online_affinity, v->cpu_hard_affinity, online); -cpumask_or (cpumask, cpumask, online_affinity); - } -/* -* If d->auto_node_affinity is true, the domain's node-affinity mask -* (d->node_affinity) is automaically computed from all the domain's -* vcpus' vcpu-affinity masks (the union of which we have just built -* above in cpumask). OTOH, if d->auto_node_affinity is false, we -* must leave the node-affinity of the domain alone. +* If d->auto_node_affinity is true, let's compute the domain's +* node-affinity and update d->node_affinity accordingly. if false, +* just leave d->auto_node_affinity alone. */ if ( d->auto_node_affinity ) { +/* +* We want the narrowest possible set of pcpus (to get the narowest +* possible set of nodes). What we need is the cpumask of where the +* domain can run (the union of the hard affinity of all its vcpus), +* and the full mask of where it would prefer to run (the union of +* the soft affinity of all its various vcpus). Let's build them. +*/ +cpumask_clear (dom_cpumask); +cpumask_clear (dom_cpumask_soft); + for_each_vcpu ( d, v ) + { +cpumask_or (dom_cpumask, dom_cpumask, v->cpu_hard_affinity); +cpumask_or (dom_cpumask_soft, dom_cpumask_soft, + v->cpu_soft_affinity); + } +/* Filter out non-online cpus */ +cpumask_and (dom_cpumask, dom_cpumask, online); +/* And compute the intersection between hard, online and soft */ +cpumask_and (dom_cpumask_soft, dom_cpumask_soft, dom_cpumask); + +/* +* If not empty, the intersection of hard, soft and online is the +* narrowest set we want. If empty, we fall back to hard&online. +*/ + dom_affinity =cpumask_empty (dom_cpumask_soft) ? + dom_cpumask : dom_cpumask_soft; +nodes_clear (d->node_affinity); - for_each_online_node ( node ) - if ( cpumask_intersects(&node_to_cpumask(node), cpumask) ) - node_set(node, d->node_affinity); +for_each_cpu ( cpu, dom_affinity ) +node_set (cpu_to_node (cpu), d->node_affinity); }spin_unlock (&d->node_affinity_lock); -free_cpumask_var (online_affinity); -free_cpumask_var (cpumask); +free_cpumask_var (dom_cpumask_soft); +free_cpumask_var (dom_cpumask); }
Re: [PATCH v3 08/14] xen: derive NUMA node affinity from hard and soft CPU affinity
In reply to Dario FaggioliQuoted 9 lines
Quoted 1 line
Quoted 1 line · Dario Faggioli
if a domain's NUMA node-affinity (which is what controls memory allocations) is provided by the user/toolstack, it just is not touched. However, if the user does not say anything, leaving it all to Xen, let's compute it in the following way:
1. cpupool's cpus & hard-affinity & soft-affinity
2. if (1) is empty: cpupool's cpus & hard-affinity
Is this really guaranteed to always be non-empty? At least an ASSERT() to that effect would be nice, as it's not immediately obvious.
xen/common/domain.c struct domain *domain_create( · line 364
Quoted 5 lines
xen/common/domain.c +2
-2-if ( !zalloc_cpumask_var (&cpumask) ) +if ( !zalloc_cpumask_var (&dom_cpumask) )return ; -if ( !alloc_cpumask_var (&online_affinity) ) +if ( !zalloc_cpumask_var (&dom_cpumask_soft) )
So you use zalloc_cpumask_var() here ...
xen/common/domain.c void domain_update_node_affinity(struct domain *d) · line 389
Quoted 11 lines
if ( d->auto_node_affinity ) {xen/common/domain.c +9
-0+/* +* We want the narrowest possible set of pcpus (to get the narowest +* possible set of nodes). What we need is the cpumask of where the +* domain can run (the union of the hard affinity of all its vcpus), +* and the full mask of where it would prefer to run (the union of +* the soft affinity of all its various vcpus). Let's build them. +*/ +cpumask_clear (dom_cpumask); +cpumask_clear (dom_cpumask_soft);
... and then clear the masks explicitly here?
Jan
Re: [PATCH v3 08/14] xen: derive NUMA node affinity from hard and soft CPU affinity
Quoted 7 lines · Jan Beulich
Quoted 7 lines
Quoted 1 line
Quoted 1 line · Dario Faggioli
if a domain's NUMA node-affinity (which is what controls memory allocations) is provided by the user/toolstack, it just is not touched. However, if the user does not say anything, leaving it all to Xen, let's compute it in the following way:
Quoted 7 lines
Quoted 2 lines
1. cpupool's cpus & hard-affinity & soft-affinity
2. if (1) is empty: cpupool's cpus & hard-affinityIs this really guaranteed to always be non-empty? At least an
ASSERT()to that effect would be nice, as it's not immediately obvious.
I think it is, basing on how cpupools and hard affinity interact, even before this series (where hard affinity is v->cpu_affinity, the only per-vcpu affinity we have).
For instance, when you move a domain to a new cpupool, it always reset v->cpu_affinity to "all" for all the domain's vcpus (see sched_move_domain()). Similarly, when removing cpus from a cpupools, if some v->cpu_affinity become empty, they get reset to "all" too (see cpu_disable_scheduler()). It also uses "all" as v->cpu_affinity for all the vcpus that, at domain creation time, have an affinity which has an empty intersection with the cpupool where the domain is being created.
So, yes, I really think (2.) is guaranteed to be non empty, and yes, I can add an ASSERT there.
Quoted 20 lines
xen/common/domain.c struct domain *domain_create( · line 364
Quoted 5 lines
xen/common/domain.c +2
-2-if ( !zalloc_cpumask_var (&cpumask) ) +if ( !zalloc_cpumask_var (&dom_cpumask) )return ; -if ( !alloc_cpumask_var (&online_affinity) ) +if ( !zalloc_cpumask_var (&dom_cpumask_soft) )So you use
zalloc_cpumask_var()here ...xen/common/domain.c void domain_update_node_affinity(struct domain *d) · line 389
Quoted 11 lines
if ( d->auto_node_affinity ) {xen/common/domain.c +9
-0+/* +* We want the narrowest possible set of pcpus (to get the narowest +* possible set of nodes). What we need is the cpumask of where the +* domain can run (the union of the hard affinity of all its vcpus), +* and the full mask of where it would prefer to run (the union of +* the soft affinity of all its various vcpus). Let's build them. +*/ +cpumask_clear (dom_cpumask); +cpumask_clear (dom_cpumask_soft);
Quoted 2 lines
... and then clear the masks explicitly here?
AhA, right... I probably got a bit lost while reshuffling things. :-)
I'll ditch these two cpumask_clear().
Thanks and Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
PATCH v3 9/14 xen: sched: DOMCTL_*vcpuaffinity works with hard and soft affinity
In reply to Dario Faggioliby adding a flag for the caller to specify which one he cares about.
Add also another cpumap there. This way, in case of DOMCTL_setvcpuaffinity, Xen can return back to the caller the "effective affinity" of the vcpu. We call the effective affinity the intersection between cpupool's cpus, the (new?) hard affinity and the (new?) soft affinity.
The purpose of this is allowing the toolstack to figure out whether or not the requested change produced sensible results, when combined with the other settings that are already in place.
---
Changes from v2:
* in DOMCTL_[sg]etvcpuaffinity, flag is really a flag now, i.e., we accept request for setting and getting: (1) only hard affinity; (2) only soft affinity; (3) both; as suggested during review.
--- tools/libxc/xc_domain.c | 4 ++- xen/arch/x86/traps.c | 4 ++- xen/common/domctl.c | 54 ++++++++++++++++++++++++++++++++++++++++--- xen/common/schedule.c | 35 +++++++++++++++++++--------- xen/common/wait.c | 6 ++--- xen/include/public/domctl.h | 15 ++++++++++-- xen/include/xen/sched.h | 3 ++ 7 files changed, 97 insertions(+), 24 deletions(-)
tools/libxc/xc_domain.c +3 -1
@@ -215,7 +215,9 @@ int xc_vcpu_setaffinity(xc_interface *xch, domctl.cmd = XEN_DOMCTL_setvcpuaffinity; domctl.domain = (domid_t )domid; - domctl.u.vcpuaffinity.vcpu = vcpu; + domctl.u.vcpuaffinity.vcpu = vcpu; +/* Soft affinity is there, but not used anywhere for now, so... */ + domctl.u.vcpuaffinity.flags =XEN_VCPUAFFINITY_HARD ;memcpy (local, cpumap, cpusize);
xen/arch/x86/traps.c +2 -2
@@ -3093,7 +3093,7 @@ static void nmi_mce_softirq(void)* Make sure to wakeup the vcpu on the * specified processor. */ -vcpu_set_affinity (st->vcpu,cpumask_of (st->processor)); +vcpu_set_hard_affinity (st->vcpu,cpumask_of (st->processor));/* Affinity is restored in the iret hypercall. */ }
@@ -3122,7 +3122,7 @@ void async_exception_cleanup(struct vcpu *curr)if ( !cpumask_empty (curr->cpu_hard_affinity_tmp) && !cpumask_equal (curr->cpu_hard_affinity_tmp, curr->cpu_hard_affinity) ) { -vcpu_set_affinity (curr, curr->cpu_hard_affinity_tmp); +vcpu_set_hard_affinity (curr, curr->cpu_hard_affinity_tmp);cpumask_clear (curr->cpu_hard_affinity_tmp); }
xen/common/domctl.c +50 -4
69 lines not on this page · raw message
xen/common/schedule.c +24 -11
@@ -654,22 +654,14 @@ void sched_set_node_affinity(struct domain *d, nodemask_t *mask)SCHED_OP (DOM2OP (d), set_node_affinity, d, mask); } -int vcpu_set_affinity (struct vcpu *v,const cpumask_t *affinity) +static int vcpu_set_affinity ( +struct vcpu *v,const cpumask_t *affinity,cpumask_t **which) { -cpumask_t online_affinity; -cpumask_t *online;spinlock_t *lock; -if ( v->domain->is_pinned ) -return -EINVAL ; - online =VCPU2ONLINE (v); -cpumask_and (&online_affinity, affinity, online); -if (cpumask_empty (&online_affinity) ) -return -EINVAL ; - lock =vcpu_schedule_lock_irq (v); -cpumask_copy (v->cpu_hard_affinity, affinity); +cpumask_copy (*which, affinity);/* Always ask the scheduler to re-evaluate placement * when changing the affinity */
@@ -688,6 +680,27 @@ int vcpu_set_affinity(struct vcpu *v, const cpumask_t *affinity)return 0 ; } +int vcpu_set_hard_affinity (struct vcpu *v,const cpumask_t *affinity) +{ +cpumask_t online_affinity; +cpumask_t *online; + +if ( v->domain->is_pinned ) +return -EINVAL ; + + online =VCPU2ONLINE (v); +cpumask_and (&online_affinity, affinity, online); +if (cpumask_empty (&online_affinity) ) +return -EINVAL ; + +return vcpu_set_affinity (v, affinity, &v->cpu_hard_affinity); +} + +int vcpu_set_soft_affinity (struct vcpu *v,const cpumask_t *affinity) +{ +return vcpu_set_affinity (v, affinity, &v->cpu_soft_affinity); +} +/* Block the currently-executing domain until a pertinent event occurs. */ void vcpu_block (void ) {
xen/common/wait.c +3 -3
@@ -135,7 +135,7 @@ static void __prepare_to_wait(struct waitqueue_vcpu *wqv)/* Save current VCPU affinity; force wakeup on *this* CPU only. */ wqv->wakeup_cpu =smp_processor_id ();cpumask_copy (&wqv->saved_affinity, curr->cpu_hard_affinity); -if (vcpu_set_affinity (curr,cpumask_of (wqv->wakeup_cpu)) ) +if (vcpu_set_hard_affinity (curr,cpumask_of (wqv->wakeup_cpu)) ) {gdprintk (XENLOG_ERR ,"Unable to set vcpu affinity\n" );domain_crash_synchronous ();
@@ -166,7 +166,7 @@ static void __prepare_to_wait(struct waitqueue_vcpu *wqv)static void __finish_wait (struct waitqueue_vcpu *wqv) { wqv->esp =NULL ; - (void )vcpu_set_affinity (current, &wqv->saved_affinity); + (void )vcpu_set_hard_affinity (current, &wqv->saved_affinity); }void check_wakeup_from_wait (void )
@@ -184,7 +184,7 @@ void check_wakeup_from_wait(void)/* Re-set VCPU affinity and re-enter the scheduler. */ struct vcpu *curr = current;cpumask_copy (&wqv->saved_affinity, curr->cpu_hard_affinity); -if (vcpu_set_affinity (curr,cpumask_of (wqv->wakeup_cpu)) ) +if (vcpu_set_hard_affinity (curr,cpumask_of (wqv->wakeup_cpu)) ) {gdprintk (XENLOG_ERR ,"Unable to set vcpu affinity\n" );domain_crash_synchronous ();
xen/include/public/domctl.h +13 -2
@@ -300,8 +300,19 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_nodeaffinity_t);/* XEN_DOMCTL_setvcpuaffinity */ /* XEN_DOMCTL_getvcpuaffinity */ struct xen_domctl_vcpuaffinity { -uint32_t vcpu;/* IN */ -struct xenctl_bitmap cpumap;/* IN/OUT */ +/* IN variables. */ +uint32_t vcpu; +/* Set/get the hard affinity for vcpu */ +#define _XEN_VCPUAFFINITY_HARD 0 +#define XEN_VCPUAFFINITY_HARD (1U<<_XEN_VCPUAFFINITY_HARD) +/* Set/get the soft affinity for vcpu */ +#define _XEN_VCPUAFFINITY_SOFT 1 +#define XEN_VCPUAFFINITY_SOFT (1U<<_XEN_VCPUAFFINITY_SOFT) +uint32_t flags; +/* IN/OUT variables. */ +struct xenctl_bitmap cpumap; +/* OUT variables. */ +struct xenctl_bitmap eff_cpumap; };typedef struct xen_domctl_vcpuaffinity xen_domctl_vcpuaffinity_t ;DEFINE_XEN_GUEST_HANDLE (xen_domctl_vcpuaffinity_t);
xen/include/xen/sched.h +2 -1
@@ -755,7 +755,8 @@ void scheduler_free(struct scheduler *sched);int schedule_cpu_switch (unsigned int cpu,struct cpupool *c);void vcpu_force_reschedule (struct vcpu *v);int cpu_disable_scheduler (unsigned int cpu); -int vcpu_set_affinity (struct vcpu *v,const cpumask_t *affinity); +int vcpu_set_hard_affinity (struct vcpu *v,const cpumask_t *affinity); +int vcpu_set_soft_affinity (struct vcpu *v,const cpumask_t *affinity);void restore_vcpu_affinity (struct domain *d);void vcpu_runstate_get (struct vcpu *v,struct vcpu_runstate_info *runstate);
Re: [PATCH v3 09/14] xen: sched: DOMCTL_*vcpuaffinity works with hard and soft affinity
Quoted 8 lines · Dario Faggioli
by adding a flag for the caller to specify which one he cares about.
Add also another cpumap there. This way, in case of
DOMCTL_setvcpuaffinity, Xen can return back to the caller the "effective affinity" of the vcpu. We call the effective affinity the intersection between cpupool's cpus, the (new?) hard affinity and the (new?) soft affinity.
Quoted 5 lines
The purpose of this is allowing the toolstack to figure out whether or not the requested change produced sensible results, when combined with the other settings that are already in place.
Signed-off-by Dario Faggioli <[email protected]>
Looks good:
Quoted 257 lines
---
Changes from v2:
* in DOMCTL_[sg]etvcpuaffinity, flag is really a flag now, i.e., we accept request for setting and getting: (1) only hard affinity; (2) only soft affinity; (3) both; as suggested during review.--- tools/libxc/xc_domain.c | 4 ++- xen/arch/x86/traps.c | 4 ++- xen/common/domctl.c | 54 ++++++++++++++++++++++++++++++++++++++++--- xen/common/schedule.c | 35 +++++++++++++++++++--------- xen/common/wait.c | 6 ++--- xen/include/public/domctl.h | 15 ++++++++++-- xen/include/xen/sched.h | 3 ++ 7 files changed, 97 insertions(+), 24 deletions(-)tools/libxc/xc_domain.c +3
-1@@ -215,7 +215,9 @@ int xc_vcpu_setaffinity(xc_interface *xch, domctl.cmd = XEN_DOMCTL_setvcpuaffinity; domctl.domain = (domid_t )domid; - domctl.u.vcpuaffinity.vcpu = vcpu; + domctl.u.vcpuaffinity.vcpu = vcpu; +/* Soft affinity is there, but not used anywhere for now, so... */ + domctl.u.vcpuaffinity.flags =XEN_VCPUAFFINITY_HARD ;memcpy (local, cpumap, cpusize);xen/arch/x86/traps.c +2
-2@@ -3093,7 +3093,7 @@ static void nmi_mce_softirq(void)* Make sure to wakeup the vcpu on the * specified processor. */ -vcpu_set_affinity (st->vcpu,cpumask_of (st->processor)); +vcpu_set_hard_affinity (st->vcpu,cpumask_of (st->processor));/* Affinity is restored in the iret hypercall. */ }@@ -3122,7 +3122,7 @@ void async_exception_cleanup(struct vcpu *curr)if ( !cpumask_empty (curr->cpu_hard_affinity_tmp) && !cpumask_equal (curr->cpu_hard_affinity_tmp, curr->cpu_hard_affinity) ) { -vcpu_set_affinity (curr, curr->cpu_hard_affinity_tmp); +vcpu_set_hard_affinity (curr, curr->cpu_hard_affinity_tmp);cpumask_clear (curr->cpu_hard_affinity_tmp); }xen/common/domctl.c +50
-4@@ -617,19 +617,65 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)if ( op->cmd == XEN_DOMCTL_setvcpuaffinity ) {cpumask_var_t new_affinity; +cpumask_t *online; ret =xenctl_bitmap_to_cpumask ( &new_affinity, &op->u.vcpuaffinity.cpumap); -if ( !ret ) +if ( ret ) +break ; + + ret = -EINVAL ; +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_HARD ) + ret =vcpu_set_hard_affinity (v, new_affinity); +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_SOFT ) + ret =vcpu_set_soft_affinity (v, new_affinity); + +if ( ret ) + goto setvcpuaffinity_out; + +/* +* Report back to the caller what the "effective affinity", that +* is the intersection of cpupool's pcpus, the (new?) hard +* affinity and the (new?) soft-affinity. +*/ +if ( !guest_handle_is_null (op->u.vcpuaffinity.eff_cpumap.bitmap) ) { - ret =vcpu_set_affinity (v, new_affinity); -free_cpumask_var (new_affinity); + online =cpupool_online_cpumask (v->domain->cpupool); +cpumask_and (new_affinity, online, v->cpu_hard_affinity); +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_SOFT ) +cpumask_and (new_affinity, new_affinity, + v->cpu_soft_affinity); + + ret =cpumask_to_xenctl_bitmap ( + &op->u.vcpuaffinity.eff_cpumap, new_affinity); } + + setvcpuaffinity_out: +free_cpumask_var (new_affinity); }else { +cpumask_var_t affinity; + +/* +* If the caller asks for both _HARD and _SOFT, what we return +* is the intersection of hard and soft affinity for the vcpu. +*/ +if ( !alloc_cpumask_var (&affinity) ) { + ret = -EFAULT ; +break ; + } +cpumask_setall (affinity); + +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_HARD ) +cpumask_copy (affinity, v->cpu_hard_affinity); +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_SOFT ) +cpumask_and (affinity, affinity, v->cpu_soft_affinity); + ret =cpumask_to_xenctl_bitmap ( - &op->u.vcpuaffinity.cpumap, v->cpu_hard_affinity); + &op->u.vcpuaffinity.cpumap, affinity); + +free_cpumask_var (affinity); } }break ;xen/common/schedule.c +24
-11@@ -654,22 +654,14 @@ void sched_set_node_affinity(struct domain *d, nodemask_t *mask)SCHED_OP (DOM2OP (d), set_node_affinity, d, mask); } -int vcpu_set_affinity (struct vcpu *v,const cpumask_t *affinity) +static int vcpu_set_affinity ( +struct vcpu *v,const cpumask_t *affinity,cpumask_t **which) { -cpumask_t online_affinity; -cpumask_t *online;spinlock_t *lock; -if ( v->domain->is_pinned ) -return -EINVAL ; - online =VCPU2ONLINE (v); -cpumask_and (&online_affinity, affinity, online); -if (cpumask_empty (&online_affinity) ) -return -EINVAL ; - lock =vcpu_schedule_lock_irq (v); -cpumask_copy (v->cpu_hard_affinity, affinity); +cpumask_copy (*which, affinity);/* Always ask the scheduler to re-evaluate placement * when changing the affinity */ @@ -688,6 +680,27 @@ int vcpu_set_affinity(struct vcpu *v, const cpumask_t *affinity)return 0 ; } +int vcpu_set_hard_affinity (struct vcpu *v,const cpumask_t *affinity) +{ +cpumask_t online_affinity; +cpumask_t *online; + +if ( v->domain->is_pinned ) +return -EINVAL ; + + online =VCPU2ONLINE (v); +cpumask_and (&online_affinity, affinity, online); +if (cpumask_empty (&online_affinity) ) +return -EINVAL ; + +return vcpu_set_affinity (v, affinity, &v->cpu_hard_affinity); +} + +int vcpu_set_soft_affinity (struct vcpu *v,const cpumask_t *affinity) +{ +return vcpu_set_affinity (v, affinity, &v->cpu_soft_affinity); +} +/* Block the currently-executing domain until a pertinent event occurs. */ void vcpu_block (void ) {xen/common/wait.c +3
-3@@ -135,7 +135,7 @@ static void __prepare_to_wait(struct waitqueue_vcpu *wqv)/* Save current VCPU affinity; force wakeup on *this* CPU only. */ wqv->wakeup_cpu =smp_processor_id ();cpumask_copy (&wqv->saved_affinity, curr->cpu_hard_affinity); -if (vcpu_set_affinity (curr,cpumask_of (wqv->wakeup_cpu)) ) +if (vcpu_set_hard_affinity (curr,cpumask_of (wqv->wakeup_cpu)) ) {gdprintk (XENLOG_ERR ,"Unable to set vcpu affinity\n" );domain_crash_synchronous ();@@ -166,7 +166,7 @@ static void __prepare_to_wait(struct waitqueue_vcpu *wqv)static void __finish_wait (struct waitqueue_vcpu *wqv) { wqv->esp =NULL ; - (void )vcpu_set_affinity (current, &wqv->saved_affinity); + (void )vcpu_set_hard_affinity (current, &wqv->saved_affinity); }void check_wakeup_from_wait (void )@@ -184,7 +184,7 @@ void check_wakeup_from_wait(void)/* Re-set VCPU affinity and re-enter the scheduler. */ struct vcpu *curr = current;cpumask_copy (&wqv->saved_affinity, curr->cpu_hard_affinity); -if (vcpu_set_affinity (curr,cpumask_of (wqv->wakeup_cpu)) ) +if (vcpu_set_hard_affinity (curr,cpumask_of (wqv->wakeup_cpu)) ) {gdprintk (XENLOG_ERR ,"Unable to set vcpu affinity\n" );domain_crash_synchronous ();xen/include/public/domctl.h +13
-2@@ -300,8 +300,19 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_nodeaffinity_t);/* XEN_DOMCTL_setvcpuaffinity */ /* XEN_DOMCTL_getvcpuaffinity */ struct xen_domctl_vcpuaffinity { -uint32_t vcpu;/* IN */ -struct xenctl_bitmap cpumap;/* IN/OUT */ +/* IN variables. */ +uint32_t vcpu; +/* Set/get the hard affinity for vcpu */ +#define _XEN_VCPUAFFINITY_HARD 0 +#define XEN_VCPUAFFINITY_HARD (1U<<_XEN_VCPUAFFINITY_HARD) +/* Set/get the soft affinity for vcpu */ +#define _XEN_VCPUAFFINITY_SOFT 1 +#define XEN_VCPUAFFINITY_SOFT (1U<<_XEN_VCPUAFFINITY_SOFT) +uint32_t flags; +/* IN/OUT variables. */ +struct xenctl_bitmap cpumap; +/* OUT variables. */ +struct xenctl_bitmap eff_cpumap; };typedef struct xen_domctl_vcpuaffinity xen_domctl_vcpuaffinity_t ;DEFINE_XEN_GUEST_HANDLE (xen_domctl_vcpuaffinity_t);xen/include/xen/sched.h +2
-1@@ -755,7 +755,8 @@ void scheduler_free(struct scheduler *sched);int schedule_cpu_switch (unsigned int cpu,struct cpupool *c);void vcpu_force_reschedule (struct vcpu *v);int cpu_disable_scheduler (unsigned int cpu); -int vcpu_set_affinity (struct vcpu *v,const cpumask_t *affinity); +int vcpu_set_hard_affinity (struct vcpu *v,const cpumask_t *affinity); +int vcpu_set_soft_affinity (struct vcpu *v,const cpumask_t *affinity);void restore_vcpu_affinity (struct domain *d);void vcpu_runstate_get (struct vcpu *v,struct vcpu_runstate_info *runstate);
Re: [PATCH v3 09/14] xen: sched: DOMCTL_*vcpuaffinity works with hard and soft affinity
In reply to Dario FaggioliQuoted 11 lines
Quoted 1 line
Quoted 1 line · Dario Faggioli
xen/common/domctl.c +1
-0@@ -617,19 +617,65 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)if ( op->cmd == XEN_DOMCTL_setvcpuaffinity ) {cpumask_var_t new_affinity; +cpumask_t *online; ret = xenctl_bitmap_to_cpumask(
xen/common/domctl.c long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) · line 632
Quoted 10 lines
xen/common/domctl.c +8
-1&new_affinity, &op->u.vcpuaffinity.cpumap); -if ( !ret ) +if ( ret ) +break ; + + ret = -EINVAL ; +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_HARD ) + ret =vcpu_set_hard_affinity (v, new_affinity); +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_SOFT ) + ret =vcpu_set_soft_affinity (v, new_affinity);
You're discarding an eventual error indicator from vcpu_set_hard_affinity() here.
xen/common/domctl.c long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) · line 634
Quoted 3 lines
xen/common/domctl.c +3
-0+ +if ( ret ) + goto setvcpuaffinity_out;
Considering that you're going to return an error here, the caller may expect that the call did nothing, even if vcpu_set_hard_affinity() succeeded and vcpu_set_soft_affinity() failed. I know this is ugly to handle...
Quoted 8 lines
xen/common/domctl.c +7
-0+ +/* +* Report back to the caller what the "effective affinity", that +* is the intersection of cpupool's pcpus, the (new?) hard +* affinity and the (new?) soft-affinity. +*/ +if ( !guest_handle_is_null (op->u.vcpuaffinity.eff_cpumap.bitmap) ) {
xen/common/domctl.c long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) · line 650
Quoted 10 lines
xen/common/domctl.c +8
-2- ret =vcpu_set_affinity (v, new_affinity); -free_cpumask_var (new_affinity); + online =cpupool_online_cpumask (v->domain->cpupool); +cpumask_and (new_affinity, online, v->cpu_hard_affinity); +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_SOFT ) +cpumask_and (new_affinity, new_affinity, + v->cpu_soft_affinity); + + ret =cpumask_to_xenctl_bitmap ( + &op->u.vcpuaffinity.eff_cpumap, new_affinity);
Considering that you have two bitmaps available from the caller, can't you just return both when both flags are set?
xen/common/domctl.c long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) · line 664
Quoted 9 lines
xen/common/domctl.c +7
-0else { +cpumask_var_t affinity; + +/* +* If the caller asks for both _HARD and _SOFT, what we return +* is the intersection of hard and soft affinity for the vcpu. +*/ +if ( !alloc_cpumask_var (&affinity) ) {
Coding style.
xen/common/domctl.c long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) · line 665
Quoted 1 line
xen/common/domctl.c +1
-0+ ret = -EFAULT ;
-ENOMEM
xen/common/domctl.c long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) · line 673
Quoted 8 lines
xen/common/domctl.c +8
-0+break ; + } +cpumask_setall (affinity); + +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_HARD ) +cpumask_copy (affinity, v->cpu_hard_affinity); +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_SOFT ) +cpumask_and (affinity, affinity, v->cpu_soft_affinity);
Just like in the set case, you should fail when neither bit is set, and you could easily copy out both mask when both bits are set (or otherwise for the get case using the same interface structure is sort of bogus).
xen/common/schedule.c void sched_set_node_affinity(struct domain *d, nodemask_t *mask) · line 658
Quoted 9 lines
xen/common/schedule.c +2
-1@@ -654,22 +654,14 @@ void sched_set_node_affinity(struct domain *d, nodemask_t *mask)SCHED_OP (DOM2OP (d), set_node_affinity, d, mask); } -int vcpu_set_affinity (struct vcpu *v,const cpumask_t *affinity) +static int vcpu_set_affinity ( +struct vcpu *v,const cpumask_t *affinity,cpumask_t **which)
I don't think there's a need for the double * on "which".
Jan
Re: [PATCH v3 09/14] xen: sched: DOMCTL_*vcpuaffinity works with hard and soft affinity
So, about this, in the new version of this series I'm releasing right now.
Quoted 10 lines · Jan Beulich
Quoted 10 lines
Quoted 1 line
Quoted 1 line · Dario Faggioli
xen/common/domctl.c +1
-0@@ -617,19 +617,65 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)if ( op->cmd == XEN_DOMCTL_setvcpuaffinity ) {cpumask_var_t new_affinity; +cpumask_t *online;
Quoted 15 lines
xen/common/domctl.c long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) · line 631
Quoted 11 lines
xen/common/domctl.c +8
-1ret =xenctl_bitmap_to_cpumask ( &new_affinity, &op->u.vcpuaffinity.cpumap); -if ( !ret ) +if ( ret ) +break ; + + ret = -EINVAL ; +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_HARD ) + ret =vcpu_set_hard_affinity (v, new_affinity); +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_SOFT ) + ret =vcpu_set_soft_affinity (v, new_affinity);You're discarding an eventual error indicator from
vcpu_set_hard_affinity()here.
I fixed this.
Quoted 9 lines
xen/common/domctl.c long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) · line 634
Quoted 3 lines
xen/common/domctl.c +3
-0+ +if ( ret ) + goto setvcpuaffinity_out;Considering that you're going to return an error here, the caller may expect that the call did nothing, even if
vcpu_set_hard_affinity()succeeded andvcpu_set_soft_affinity()failed. I know this is ugly to handle...
And this too.
Quoted 13 lines
Quoted 13 lines
xen/common/domctl.c +10
-2+ +/* +* Report back to the caller what the "effective affinity", that +* is the intersection of cpupool's pcpus, the (new?) hard +* affinity and the (new?) soft-affinity. +*/ +if ( !guest_handle_is_null (op->u.vcpuaffinity.eff_cpumap.bitmap) ) { - ret =vcpu_set_affinity (v, new_affinity); -free_cpumask_var (new_affinity); + online =cpupool_online_cpumask (v->domain->cpupool); +cpumask_and (new_affinity, online, v->cpu_hard_affinity); +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_SOFT )
Quoted 9 lines
xen/common/domctl.c long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) · line 650
Quoted 5 lines
xen/common/domctl.c +5
-0+cpumask_and (new_affinity, new_affinity, + v->cpu_soft_affinity); + + ret =cpumask_to_xenctl_bitmap ( + &op->u.vcpuaffinity.eff_cpumap, new_affinity);Considering that you have two bitmaps available from the caller, can't you just return both when both flags are set?
Well, it's true that there are two cpumaps, but only one is meant to be an output parameter. Also, I think this is more useful like this, i.e., returning either:
- hard-affinity&online
- hard-affinity&soft-affinity&online,
As it can be seen in the libxl patch (in the new series).
Therefore, I kept this interface as it was here, also considering that:
- it's pretty late to re-re-redesign;
- neither this nor the xc one are stable interfaces, so we can come back and revisit this later, if we want to.
Do you think this could be acceptable?
Thanks and Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v3 09/14] xen: sched: DOMCTL_*vcpuaffinity works with hard and soft affinity
Quoted 12 lines
Quoted 1 line
Quoted 1 line · Dario Faggioli
Quoted 10 lines · Jan Beulich
Quoted 9 lines
Quoted 1 line
Quoted 1 line · Dario Faggioli
xen/common/domctl.c +8
-0+ online =cpupool_online_cpumask (v->domain->cpupool); +cpumask_and (new_affinity, online, v->cpu_hard_affinity); +if ( op->u.vcpuaffinity.flags &XEN_VCPUAFFINITY_SOFT ) +cpumask_and (new_affinity, new_affinity, + v->cpu_soft_affinity); + + ret =cpumask_to_xenctl_bitmap ( + &op->u.vcpuaffinity.eff_cpumap, new_affinity);
Quoted 5 lines
Quoted 3 lines
Considering that you have two bitmaps available from the caller, can't you just return both when both flags are set?
Well, it's true that there are two cpumaps, but only one is meant to be an output parameter.
"meant to be" based on what? Surely not because so far it was that way - as you say further down, this is not an interface required to be stable.
Quoted 5 lines
Also, I think this is more useful like this, i.e., returning either:
- hard-affinity&online
- hard-affinity&soft-affinity&online,
Quoted 8 lines
As it can be seen in the libxl patch (in the new series).
Therefore, I kept this interface as it was here, also considering that:
- it's pretty late to re-re-redesign;
- neither this nor the xc one are stable interfaces, so we can come back and revisit this later, if we want to.Do you think this could be acceptable?
I wouldn't veto it, but I also dislike reduced flexibility when more flexibility is obviously achievable without much effort.
Jan
Re: [PATCH v3 09/14] xen: sched: DOMCTL_*vcpuaffinity works with hard and soft affinity
Quoted 11 lines · Jan Beulich
Quoted 7 lines
Quoted 1 line
Quoted 1 line · Dario Faggioli
Therefore, I kept this interface as it was here, also considering that:
- it's pretty late to re-re-redesign;
- neither this nor the xc one are stable interfaces, so we can come back and revisit this later, if we want to.Do you think this could be acceptable?
I wouldn't veto it, but I also dislike reduced flexibility when more flexibility is obviously achievable without much effort.
Ok, understood. Ok, I'm up for changing this then. So, let m ask a few questions, just to make sure ot get it right this time! ;-P
You are saying the interface should look as follows:
int xc_vcpu_setaffinity(xc_interface *xch,
uint32_t domid,
int vcpu,
xc_cpumap_t cpumap_soft,
xc_cpumap_t cpumap_hard,
uint32_t flags);Where both cpumap_soft and cpumap_hard are IN/OUT parameters and, as far as OUT is concerned:
- cpumap_hard will contain hard-affinity&online
- cpumap_soft will contain what?
(a) soft-affinity?
(b) soft-affinity&online
(c) soft-affinity&hard-affinity&online?
I would make it (c), as (a) is what xc_vcpu_setaffinity() retrieves, while the '&online' part is particularly hard to get from other existing calls (either at libxc and libxl level). Among (b) and (c), (c) is what would be most useful for an high level caller (like libxl) to have it ready, but it's also true that, if I give (b) to it, it could in theory reconstruct (c) by himself (with the vice-versa not being true).
Thoughts?
Also, should I return something in either *only* of the maps when the corresponding flag is set (and of course fill both when both flags are)? Or do we always want to get something back (when non NULL, of course) and apply the content of flag only to the IN path (i.e., for setting either or both the afinities)?
Thanks and Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v3 09/14] xen: sched: DOMCTL_*vcpuaffinity works with hard and soft affinity
Quoted 25 lines
Quoted 1 line
Quoted 1 line · Dario Faggioli
Quoted 11 lines · Jan Beulich
Quoted 7 lines
Quoted 1 line
Quoted 1 line · Dario Faggioli
Therefore, I kept this interface as it was here, also considering that:
- it's pretty late to re-re-redesign;
- neither this nor the xc one are stable interfaces, so we can come back and revisit this later, if we want to.Do you think this could be acceptable?
I wouldn't veto it, but I also dislike reduced flexibility when more flexibility is obviously achievable without much effort.
Ok, understood. Ok, I'm up for changing this then. So, let m ask a few questions, just to make sure ot get it right this time! ;-P
You are saying the interface should look as follows:
int xc_vcpu_setaffinity(xc_interface *xch,
uint32_t domid, int vcpu, xc_cpumap_t cpumap_soft, xc_cpumap_t cpumap_hard, uint32_t flags);
Quoted 7 lines
Where both
cpumap_softandcpumap_hardare IN/OUT parameters and, as far as OUT is concerned:
-cpumap_hardwill contain hard-affinity&online
-cpumap_softwill contain what?
(a) soft-affinity?
(b) soft-affinity&online
(c) soft-affinity&hard-affinity&online?
(c) seems the best fit - after all it should represent what the hypervisor will effectively use.
Quoted 11 lines
I would make it (c), as (a) is what
xc_vcpu_setaffinity()retrieves, while the '&online' part is particularly hard to get from other existing calls (either at libxc and libxl level). Among (b) and (c), (c) is what would be most useful for an high level caller (like libxl) to have it ready, but it's also true that, if I give (b) to it, it could in theory reconstruct (c) by himself (with the vice-versa not being true).Thoughts?
Also, should I return something in either *only* of the maps when the corresponding flag is set (and of course fill both when both flags are)?
Of course - the other handle may validly be containing garbage in that case afaict.
Jan
Re: [PATCH v3 09/14] xen: sched: DOMCTL_*vcpuaffinity works with hard and soft affinity
Quoted 31 lines · Jan Beulich
Quoted 24 lines
Quoted 1 line
Quoted 1 line · Dario Faggioli
Quoted 10 lines · Jan Beulich
Quoted 7 lines
Quoted 1 line
Quoted 1 line · Dario Faggioli
Therefore, I kept this interface as it was here, also considering that:
- it's pretty late to re-re-redesign;
- neither this nor the xc one are stable interfaces, so we can come back and revisit this later, if we want to.Do you think this could be acceptable?
I wouldn't veto it, but I also dislike reduced flexibility when more flexibility is obviously achievable without much effort.
Ok, understood. Ok, I'm up for changing this then. So, let m ask a few questions, just to make sure ot get it right this time! ;-P
You are saying the interface should look as follows:
int xc_vcpu_setaffinity(xc_interface *xch,
uint32_t domid, int vcpu, xc_cpumap_t cpumap_soft, xc_cpumap_t cpumap_hard, uint32_t flags);Quoted 7 lines
Where both
cpumap_softandcpumap_hardare IN/OUT parameters and, as far as OUT is concerned:
-cpumap_hardwill contain hard-affinity&online
-cpumap_softwill contain what?
(a) soft-affinity?
(b) soft-affinity&online
(c) soft-affinity&hard-affinity&online?
Quoted 2 lines
(c) seems the best fit - after all it should represent what the hypervisor will effectively use.
+1
PATCH v3 10/14 libxc: get and set soft and hard affinity
In reply to Dario Faggioliby using the new flag introduced in the parameters of the DOMCTL_{get,set}_vcpuaffinity hypercall.
This happens by adding a new parameter (flags) to xc_vcpu_setaffinity() and xc_vcpu_getaffinity(), so that the caller can decide to set either the soft or hard affinity, or even both.
In case of setting both hard and soft, they are set to the same cpumap. xc_get_setaffinity() also takes another new param, for reporting back to the caller what the actual affinity the scheduler uses will be after a successful call.
In case of asking to get both hard and soft, what the caller gets is the intersection between them.
In-tree callers are also fixed to cope with the new interface.
---
Changes from v2:
* better cleanup logic in _vcpu_setaffinity() (regarding xc_hypercall_buffer_{alloc,free}()), as suggested during review;
* make it more evident that DOMCTL_setvcpuaffinity has an out parameter, by calling ecpumap_out, and improving the comment wrt that;
* change the interface and have xc_vcpu_[sg]etaffinity() so that they take the new parameters (flags and ecpumap_out) and fix the in tree callers.
--- tools/libxc/xc_domain.c | 47 +++++++++++++++++++++-------------- tools/libxc/xenctrl.h | 44 ++++++++++++++++++++++++++++++++- tools/libxl/libxl.c | 7 ++++- tools/ocaml/libs/xc/xenctrl_stubs.c | 8 ++++-- tools/python/xen/lowlevel/xc/xc.c | 6 +++- 5 files changed, 86 insertions(+), 26 deletions(-)
tools/libxc/xc_domain.c +28 -19
@@ -192,44 +192,52 @@ int xc_domain_node_getaffinity(xc_interface *xch,int xc_vcpu_setaffinity (xc_interface *xch,uint32_t domid,int vcpu, -xc_cpumap_t cpumap) +xc_cpumap_t cpumap, +uint32_t flags, +xc_cpumap_t ecpumap_out) {DECLARE_DOMCTL ; -DECLARE_HYPERCALL_BUFFER (uint8_t, local); +DECLARE_HYPERCALL_BUFFER (uint8_t, cpumap_local); +DECLARE_HYPERCALL_BUFFER (uint8_t, ecpumap_local);int ret =-1 ;int cpusize; cpusize =xc_get_cpumap_size (xch); -if (!cpusize) +if ( !cpusize ) {PERROR ("Could not get number of cpus" ); - goto out; +return -1 ;; } - local =xc_hypercall_buffer_alloc (xch, local, cpusize); -if ( local ==NULL ) + cpumap_local =xc_hypercall_buffer_alloc (xch, cpumap_local, cpusize); + ecpumap_local =xc_hypercall_buffer_alloc (xch, ecpumap_local, cpusize); +if ( cpumap_local ==NULL || cpumap_local ==NULL ) { -PERROR ("Could not allocate memory for setvcpuaffinity domctl hypercall" ); +PERROR ("Could not allocate hcall buffers for DOMCTL_setvcpuaffinity" ); goto out; } domctl.cmd = XEN_DOMCTL_setvcpuaffinity; domctl.domain = (domid_t )domid; domctl.u.vcpuaffinity.vcpu = vcpu; -/* Soft affinity is there, but not used anywhere for now, so... */ - domctl.u.vcpuaffinity.flags =XEN_VCPUAFFINITY_HARD ; - -memcpy (local, cpumap, cpusize); - -set_xen_guest_handle (domctl.u.vcpuaffinity.cpumap.bitmap, local); + domctl.u.vcpuaffinity.flags = flags; +memcpy (cpumap_local, cpumap, cpusize); +set_xen_guest_handle (domctl.u.vcpuaffinity.cpumap.bitmap, cpumap_local); domctl.u.vcpuaffinity.cpumap.nr_bits = cpusize *8 ; +set_xen_guest_handle (domctl.u.vcpuaffinity.eff_cpumap.bitmap, + ecpumap_local); + domctl.u.vcpuaffinity.eff_cpumap.nr_bits = cpusize *8 ; + ret =do_domctl (xch, &domctl); -xc_hypercall_buffer_free (xch, local); +if ( ecpumap_out !=NULL ) +memcpy (ecpumap_out, ecpumap_local, cpusize); out: +xc_hypercall_buffer_free (xch, cpumap_local); +xc_hypercall_buffer_free (xch, ecpumap_local);return ret; }
@@ -237,6 +245,7 @@ int xc_vcpu_setaffinity(xc_interface *xch,int xc_vcpu_getaffinity (xc_interface *xch,uint32_t domid,int vcpu, +uint32_t flags,xc_cpumap_t cpumap) {DECLARE_DOMCTL ;
@@ -245,22 +254,23 @@ int xc_vcpu_getaffinity(xc_interface *xch,int cpusize; cpusize =xc_get_cpumap_size (xch); -if (!cpusize) +if ( !cpusize ) {PERROR ("Could not get number of cpus" ); - goto out; +return -1 ; } local =xc_hypercall_buffer_alloc (xch, local, cpusize); -if (local ==NULL ) +if ( local ==NULL ) {PERROR ("Could not allocate memory for getvcpuaffinity domctl hypercall" ); - goto out; +return -1 ; } domctl.cmd = XEN_DOMCTL_getvcpuaffinity; domctl.domain = (domid_t )domid; domctl.u.vcpuaffinity.vcpu = vcpu; + domctl.u.vcpuaffinity.flags = flags;set_xen_guest_handle (domctl.u.vcpuaffinity.cpumap.bitmap, local); domctl.u.vcpuaffinity.cpumap.nr_bits = cpusize *8 ;
@@ -270,7 +280,6 @@ int xc_vcpu_getaffinity(xc_interface *xch,memcpy (cpumap, local, cpusize);xc_hypercall_buffer_free (xch, local); -out:return ret; }
tools/libxc/xenctrl.h +43 -1
56 lines not on this page · raw message
tools/libxl/libxl.c +5 -2
@@ -4208,7 +4208,9 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid,LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR ,"getting vcpu info" );return NULL ; } -if (xc_vcpu_getaffinity (ctx->xch, domid, *nb_vcpu, ptr->cpumap.map) ==-1 ) { +if (xc_vcpu_getaffinity (ctx->xch, domid, *nb_vcpu, +XEN_VCPUAFFINITY_HARD , + ptr->cpumap.map) ==-1 ) {LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR ,"getting vcpu affinity" );return NULL ; }
@@ -4225,7 +4227,8 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid,int libxl_set_vcpuaffinity (libxl_ctx *ctx,uint32_t domid,uint32_t vcpuid,libxl_bitmap *cpumap) { -if (xc_vcpu_setaffinity (ctx->xch, domid, vcpuid, cpumap->map)) { +if (xc_vcpu_setaffinity (ctx->xch, domid, vcpuid, cpumap->map, +XEN_VCPUAFFINITY_HARD ,NULL )) {LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR ,"setting vcpu affinity" );return ERROR_FAIL ; }
tools/ocaml/libs/xc/xenctrl_stubs.c +6 -2
@@ -438,7 +438,9 @@ CAMLprim value stub_xc_vcpu_setaffinity(value xch, value domid, c_cpumap[i/8 ] |=1 << (i&7 ); } retval =xc_vcpu_setaffinity (_H (xch),_D (domid), -Int_val (vcpu), c_cpumap); +Int_val (vcpu), c_cpumap, +XEN_VCPUAFFINITY_HARD , +NULL );free (c_cpumap);if (retval <0 )
@@ -460,7 +462,9 @@ CAMLprim value stub_xc_vcpu_getaffinity(value xch, value domid,failwith_xc (_H (xch)); retval =xc_vcpu_getaffinity (_H (xch),_D (domid), -Int_val (vcpu), c_cpumap); +Int_val (vcpu), +XEN_VCPUAFFINITY_HARD , + c_cpumap);if (retval <0 ) {free (c_cpumap);failwith_xc (_H (xch));
tools/python/xen/lowlevel/xc/xc.c +4 -2
@@ -256,7 +256,8 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self, } } -if (xc_vcpu_setaffinity (self->xc_handle, dom, vcpu, cpumap) !=0 ) +if (xc_vcpu_setaffinity (self->xc_handle, dom, vcpu, cpumap, +XEN_VCPUAFFINITY_HARD ,NULL ) !=0 ) {free (cpumap);return pyxc_error_to_exception (self->xc_handle);
@@ -403,7 +404,8 @@ static PyObject *pyxc_vcpu_getinfo(XcObject *self,if (cpumap ==NULL )return pyxc_error_to_exception (self->xc_handle); - rc =xc_vcpu_getaffinity (self->xc_handle, dom, vcpu, cpumap); + rc =xc_vcpu_getaffinity (self->xc_handle, dom, vcpu, +XEN_VCPUAFFINITY_HARD , cpumap);if ( rc <0 ) {free (cpumap);
Re: [PATCH v3 10/14] libxc: get and set soft and hard affinity
Quoted 15 lines · Dario Faggioli
by using the new flag introduced in the parameters of the DOMCTL_{get,set}_vcpuaffinity hypercall.
This happens by adding a new parameter (flags) to
xc_vcpu_setaffinity()andxc_vcpu_getaffinity(), so that the caller can decide to set either the soft or hard affinity, or even both.In case of setting both hard and soft, they are set to the same cpumap.
xc_get_setaffinity()also takes another new param, for reporting back to the caller what the actual affinity the scheduler uses will be after a successful call.
In case of asking to get both hard and soft, what the caller gets is the intersection between them.
Quoted 3 lines
In-tree callers are also fixed to cope with the new interface.
Signed-off-by Dario Faggioli <[email protected]>
But...
Quoted 32 lines
---
Changes from v2:
* better cleanup logic in_vcpu_setaffinity()(regarding xc_hypercall_buffer_{alloc,free}()), as suggested during review;
* make it more evident thatDOMCTL_setvcpuaffinityhas an out parameter, by callingecpumap_out, and improving the comment wrt that;
* change the interface and have xc_vcpu_[sg]etaffinity() so that they take the new parameters (flags andecpumap_out) and fix the in tree callers.--- tools/libxc/xc_domain.c | 47 +++++++++++++++++++++-------------- tools/libxc/xenctrl.h | 44 ++++++++++++++++++++++++++++++++- tools/libxl/libxl.c | 7 ++++- tools/ocaml/libs/xc/xenctrl_stubs.c | 8 ++++-- tools/python/xen/lowlevel/xc/xc.c | 6 +++- 5 files changed, 86 insertions(+), 26 deletions(-)tools/libxc/xc_domain.c +3
-1@@ -192,44 +192,52 @@ int xc_domain_node_getaffinity(xc_interface *xch,int xc_vcpu_setaffinity (xc_interface *xch,uint32_t domid,int vcpu, -xc_cpumap_t cpumap) +xc_cpumap_t cpumap, +uint32_t flags, +xc_cpumap_t ecpumap_out) {
tools/libxc/xc_domain.c int xc_domain_node_getaffinity(xc_interface *xch, · line 206
Quoted 10 lines
tools/libxc/xc_domain.c +3
-2DECLARE_DOMCTL ; -DECLARE_HYPERCALL_BUFFER (uint8_t, local); +DECLARE_HYPERCALL_BUFFER (uint8_t, cpumap_local); +DECLARE_HYPERCALL_BUFFER (uint8_t, ecpumap_local);int ret =-1 ;int cpusize; cpusize =xc_get_cpumap_size (xch); -if (!cpusize) +if ( !cpusize )
I know IanJ will have something to say about non-snuggly braces here and below. :-)
-George
Re: [PATCH v3 10/14] libxc: get and set soft and hard affinity
Quoted 63 lines · George Dunlap
Quoted 15 lines · Dario Faggioli
by using the new flag introduced in the parameters of the DOMCTL_{get,set}_vcpuaffinity hypercall.
This happens by adding a new parameter (flags) to
xc_vcpu_setaffinity()andxc_vcpu_getaffinity(), so that the caller can decide to set either the soft or hard affinity, or even both.In case of setting both hard and soft, they are set to the same cpumap.
xc_get_setaffinity()also takes another new param, for reporting back to the caller what the actual affinity the scheduler uses will be after a successful call.
In case of asking to get both hard and soft, what the caller gets is the intersection between them.Quoted 3 lines
In-tree callers are also fixed to cope with the new interface.
Signed-off-by Dario Faggioli <[email protected]>Acked-by George Dunlap <[email protected]>But...
Quoted 39 lines
---
Changes from v2:
* better cleanup logic in_vcpu_setaffinity()(regarding xc_hypercall_buffer_{alloc,free}()), as suggested during review;
* make it more evident thatDOMCTL_setvcpuaffinityhas an out parameter, by callingecpumap_out, and improving the comment wrt that;
* change the interface and have xc_vcpu_[sg]etaffinity() so that they take the new parameters (flags andecpumap_out) and fix the in tree callers.--- tools/libxc/xc_domain.c | 47 +++++++++++++++++++++-------------- tools/libxc/xenctrl.h | 44 ++++++++++++++++++++++++++++++++- tools/libxl/libxl.c | 7 ++++- tools/ocaml/libs/xc/xenctrl_stubs.c | 8 ++++-- tools/python/xen/lowlevel/xc/xc.c | 6 +++- 5 files changed, 86 insertions(+), 26 deletions(-)tools/libxc/xc_domain.c +5
-2@@ -192,44 +192,52 @@ int xc_domain_node_getaffinity(xc_interface *xch,int xc_vcpu_setaffinity (xc_interface *xch,uint32_t domid,int vcpu, -xc_cpumap_t cpumap) +xc_cpumap_t cpumap, +uint32_t flags, +xc_cpumap_t ecpumap_out) {DECLARE_DOMCTL ; -DECLARE_HYPERCALL_BUFFER (uint8_t, local); +DECLARE_HYPERCALL_BUFFER (uint8_t, cpumap_local); +DECLARE_HYPERCALL_BUFFER (uint8_t, ecpumap_local);int ret =-1 ;int cpusize;
Quoted 6 lines
tools/libxc/xc_domain.c int xc_domain_node_getaffinity(xc_interface *xch, · line 206
Quoted 3 lines
tools/libxc/xc_domain.c +1
-1cpusize =xc_get_cpumap_size (xch); -if (!cpusize) +if ( !cpusize )I know IanJ will have something to say about non-snuggly braces here and below. :-)
The spaces are legit in libxc I think, it uses Xen coding style. It's libxl which differs...
Ian.
Re: [PATCH v3 10/14] libxc: get and set soft and hard affinity
Quoted 71 lines · Ian Campbell
Quoted 63 lines · George Dunlap
Quoted 15 lines · Dario Faggioli
by using the new flag introduced in the parameters of the DOMCTL_{get,set}_vcpuaffinity hypercall.
This happens by adding a new parameter (flags) to
xc_vcpu_setaffinity()andxc_vcpu_getaffinity(), so that the caller can decide to set either the soft or hard affinity, or even both.In case of setting both hard and soft, they are set to the same cpumap.
xc_get_setaffinity()also takes another new param, for reporting back to the caller what the actual affinity the scheduler uses will be after a successful call.
In case of asking to get both hard and soft, what the caller gets is the intersection between them.Quoted 3 lines
In-tree callers are also fixed to cope with the new interface.
Signed-off-by Dario Faggioli <[email protected]>Acked-by George Dunlap <[email protected]>But...
Quoted 39 lines
---
Changes from v2:
* better cleanup logic in_vcpu_setaffinity()(regarding xc_hypercall_buffer_{alloc,free}()), as suggested during review;
* make it more evident thatDOMCTL_setvcpuaffinityhas an out parameter, by callingecpumap_out, and improving the comment wrt that;
* change the interface and have xc_vcpu_[sg]etaffinity() so that they take the new parameters (flags andecpumap_out) and fix the in tree callers.--- tools/libxc/xc_domain.c | 47 +++++++++++++++++++++-------------- tools/libxc/xenctrl.h | 44 ++++++++++++++++++++++++++++++++- tools/libxl/libxl.c | 7 ++++- tools/ocaml/libs/xc/xenctrl_stubs.c | 8 ++++-- tools/python/xen/lowlevel/xc/xc.c | 6 +++- 5 files changed, 86 insertions(+), 26 deletions(-)tools/libxc/xc_domain.c +5
-2@@ -192,44 +192,52 @@ int xc_domain_node_getaffinity(xc_interface *xch,int xc_vcpu_setaffinity (xc_interface *xch,uint32_t domid,int vcpu, -xc_cpumap_t cpumap) +xc_cpumap_t cpumap, +uint32_t flags, +xc_cpumap_t ecpumap_out) {DECLARE_DOMCTL ; -DECLARE_HYPERCALL_BUFFER (uint8_t, local); +DECLARE_HYPERCALL_BUFFER (uint8_t, cpumap_local); +DECLARE_HYPERCALL_BUFFER (uint8_t, ecpumap_local);int ret =-1 ;int cpusize;Quoted 6 lines
tools/libxc/xc_domain.c int xc_domain_node_getaffinity(xc_interface *xch, · line 206
Quoted 3 lines
tools/libxc/xc_domain.c +1
-1cpusize =xc_get_cpumap_size (xch); -if (!cpusize) +if ( !cpusize )I know IanJ will have something to say about non-snuggly braces here and below. :-)
Quoted 2 lines
The spaces are legit in libxc I think, it uses Xen coding style. It's libxl which differs...
OK -- I just happened to see snuggly braces elsewhere in the file when I took a quick glance around. It has my Ack either way.
-George
Re: [PATCH v3 10/14] libxc: get and set soft and hard affinity
In reply to Dario FaggioliQuoted 1 line · Dario Faggioli
Signed-off-by Dario Faggioli <[email protected]>
There are a few preexisting issues with the setaffinity function, but this just duplicates them into the new cpumap, so I don't see any point in holding up the series for them. Perhaps you could put them on your todo list?
Quoted 17 lines
tools/libxc/xc_domain.c +5
-2@@ -192,44 +192,52 @@ int xc_domain_node_getaffinity(xc_interface *xch,int xc_vcpu_setaffinity (xc_interface *xch,uint32_t domid,int vcpu, -xc_cpumap_t cpumap) +xc_cpumap_t cpumap, +uint32_t flags, +xc_cpumap_t ecpumap_out) {DECLARE_DOMCTL ; -DECLARE_HYPERCALL_BUFFER (uint8_t, local); +DECLARE_HYPERCALL_BUFFER (uint8_t, cpumap_local); +DECLARE_HYPERCALL_BUFFER (uint8_t, ecpumap_local);
tools/libxc/xc_domain.c int xc_domain_node_getaffinity(xc_interface *xch, · line 209
Quoted 10 lines
tools/libxc/xc_domain.c +2
-2int ret =-1 ;int cpusize; cpusize =xc_get_cpumap_size (xch); -if (!cpusize) +if ( !cpusize ) {PERROR ("Could not get number of cpus" ); - goto out; +return -1 ;;
Double ";;"?
Quoted 15 lines
tools/libxc/xc_domain.c +4
-3} - local =xc_hypercall_buffer_alloc (xch, local, cpusize); -if ( local ==NULL ) + cpumap_local =xc_hypercall_buffer_alloc (xch, cpumap_local, cpusize); + ecpumap_local =xc_hypercall_buffer_alloc (xch, ecpumap_local, cpusize); +if ( cpumap_local ==NULL || cpumap_local ==NULL ) { -PERROR ("Could not allocate memory for setvcpuaffinity domctl hypercall" ); +PERROR ("Could not allocate hcall buffers for DOMCTL_setvcpuaffinity" ); goto out; } domctl.cmd = XEN_DOMCTL_setvcpuaffinity; domctl.domain = (domid_t )domid;
tools/libxc/xc_domain.c int xc_domain_node_getaffinity(xc_interface *xch, · line 225
Quoted 10 lines
tools/libxc/xc_domain.c +2
-6domctl.u.vcpuaffinity.vcpu = vcpu; -/* Soft affinity is there, but not used anywhere for now, so... */ - domctl.u.vcpuaffinity.flags =XEN_VCPUAFFINITY_HARD ; - -memcpy (local, cpumap, cpusize); - -set_xen_guest_handle (domctl.u.vcpuaffinity.cpumap.bitmap, local); + domctl.u.vcpuaffinity.flags = flags; +memcpy (cpumap_local, cpumap, cpusize);
This risks running of the end of the supplies cpumap, if it is smaller than cpusize.
But more importantly why is this not using the hypercall buffer bounce mechanism?
tools/libxc/xc_domain.c int xc_domain_node_getaffinity(xc_interface *xch, · line 236
Quoted 12 lines
tools/libxc/xc_domain.c +7
-1+set_xen_guest_handle (domctl.u.vcpuaffinity.cpumap.bitmap, cpumap_local); domctl.u.vcpuaffinity.cpumap.nr_bits = cpusize *8 ; +set_xen_guest_handle (domctl.u.vcpuaffinity.eff_cpumap.bitmap, + ecpumap_local); + domctl.u.vcpuaffinity.eff_cpumap.nr_bits = cpusize *8 ; + ret =do_domctl (xch, &domctl); -xc_hypercall_buffer_free (xch, local); +if ( ecpumap_out !=NULL ) +memcpy (ecpumap_out, ecpumap_local, cpusize);
Likewise this risks overrunning ecpumap_out, doesn't it?
Quoted 6 lines
tools/libxc/xc_domain.c +2
-0out: +xc_hypercall_buffer_free (xch, cpumap_local); +xc_hypercall_buffer_free (xch, ecpumap_local);return ret; }
Re: [PATCH v3 10/14] libxc: get and set soft and hard affinity
Quoted 6 lines · Ian Campbell
Quoted 1 line · Dario Faggioli
Signed-off-by Dario Faggioli <[email protected]>Acked-by Ian Campbell <[email protected]>
Cool.
Quoted 5 lines
There are a few preexisting issues with the setaffinity function, but this just duplicates them into the new cpumap, so I don't see any point in holding up the series for them. Perhaps you could put them on your todo list?
I certainly can.
Quoted 20 lines
Quoted 20 lines
tools/libxc/xc_domain.c +5
-2@@ -192,44 +192,52 @@ int xc_domain_node_getaffinity(xc_interface *xch,int xc_vcpu_setaffinity (xc_interface *xch,uint32_t domid,int vcpu, -xc_cpumap_t cpumap) +xc_cpumap_t cpumap, +uint32_t flags, +xc_cpumap_t ecpumap_out) {DECLARE_DOMCTL ; -DECLARE_HYPERCALL_BUFFER (uint8_t, local); +DECLARE_HYPERCALL_BUFFER (uint8_t, cpumap_local); +DECLARE_HYPERCALL_BUFFER (uint8_t, ecpumap_local);int ret =-1 ;int cpusize;
Quoted 10 lines
tools/libxc/xc_domain.c int xc_domain_node_getaffinity(xc_interface *xch, · line 209
Quoted 7 lines
tools/libxc/xc_domain.c +2
-2cpusize =xc_get_cpumap_size (xch); -if (!cpusize) +if ( !cpusize ) {PERROR ("Could not get number of cpus" ); - goto out; +return -1 ;;Double ";;"?
Ouch... I'll have to respin this series (and will do that shortly), so I'll have a chance to fix this.
Quoted 24 lines
Quoted 24 lines
tools/libxc/xc_domain.c +5
-9} - local =xc_hypercall_buffer_alloc (xch, local, cpusize); -if ( local ==NULL ) + cpumap_local =xc_hypercall_buffer_alloc (xch, cpumap_local, cpusize); + ecpumap_local =xc_hypercall_buffer_alloc (xch, ecpumap_local, cpusize); +if ( cpumap_local ==NULL || cpumap_local ==NULL ) { -PERROR ("Could not allocate memory for setvcpuaffinity domctl hypercall" ); +PERROR ("Could not allocate hcall buffers for DOMCTL_setvcpuaffinity" ); goto out; } domctl.cmd = XEN_DOMCTL_setvcpuaffinity; domctl.domain = (domid_t )domid; domctl.u.vcpuaffinity.vcpu = vcpu; -/* Soft affinity is there, but not used anywhere for now, so... */ - domctl.u.vcpuaffinity.flags =XEN_VCPUAFFINITY_HARD ; - -memcpy (local, cpumap, cpusize); - -set_xen_guest_handle (domctl.u.vcpuaffinity.cpumap.bitmap, local); + domctl.u.vcpuaffinity.flags = flags;
Quoted 5 lines
tools/libxc/xc_domain.c int xc_domain_node_getaffinity(xc_interface *xch, · line 225
Quoted 1 line
tools/libxc/xc_domain.c +1
-0+memcpy (cpumap_local, cpumap, cpusize);This risks running of the end of the supplies cpumap, if it is smaller than cpusize.
I see. Added to my todo list. :-)
Quoted 3 lines
But more importantly why is this not using the hypercall buffer bounce mechanism?
I happen to have investigated that (with the aim of doing the switch).
So, AFAICT, declaring a bounce buffer requires the size of it to be known at declaration time, is that correct?
OTOH, looks like plain hypercall buffer is not interested in that until you get to xc_buffer_alloc() it.
In this case, I don't have the size of the buffer until I get to call xc_get_cpumap_size(), and that's why I gave up turning this (and the new one I'm introducing) into bouncing buffers.
If I'm missing/misunderstanding something, and it's actually possible to do so (how?), I'd be glad to.
Thanks and Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
PATCH v3 11/14 libxl: get and set soft affinity
In reply to Dario FaggioliMake space for two new cpumap-s, one in vcpu_info (for getting soft affinity) and build_info (for setting it). Provide two new API calls:
* libxl_set_vcpuaffinity2, taking a cpumap and setting either hard, soft or both affinity to it, depending on 'flags';
* libxl_set_vcpuaffinity3, taking two cpumap, one for hard and one for soft affinity.
The bheavior of the existing libxl_set_vcpuaffinity is left unchanged, i.e., it only set hard affinity.
Getting soft affinity happens indirectly, via `xl vcpu-list' (as it is already for hard affinity).
The new calls include logic to check whether the affinity which will be used by Xen to schedule the vCPU(s) does actually match with the cpumap provided. In fact, we want to allow every possible combination of hard and soft affinities to be set, but we warn the user upon particularly weird combinations (e.g., hard and soft being disjoint sets of pCPUs).
Also, this is the first change breaking the libxl ABI, so it bumps the MAJOR.
---
Changes from v2:
* interface completely redesigned, as discussed during review.
--- tools/libxl/Makefile | 2 - tools/libxl/libxl.c | 131 +++++++++++++++++++++++++++++++++++++++++++ tools/libxl/libxl.h | 30 ++++++++++ tools/libxl/libxl_create.c | 6 ++ tools/libxl/libxl_types.idl | 4 + tools/libxl/libxl_utils.h | 15 +++++ 6 files changed, 186 insertions(+), 2 deletions(-)
tools/libxl/Makefile +1 -1
@@ -5,7 +5,7 @@ XEN_ROOT = $(CURDIR)/../.. include $(XEN_ROOT)/tools/Rules.mk -MAJOR = 4.3 +MAJOR = 4.4 MINOR = 0 XLUMAJOR = 4.3
tools/libxl/libxl.c +131 -0
149 lines not on this page · raw message
tools/libxl/libxl.h +30 -0
@@ -82,6 +82,20 @@#define LIBXL_HAVE_DOMAIN_NODEAFFINITY 1/* +* LIBXL_HAVE_VCPUINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_vcpuinfo, +* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_VCPUINFO_SOFTAFFINITY 1 + +/* +* LIBXL_HAVE_BUILDINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_domain_build_info, +* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_BUILDINFO_SOFTAFFINITY 1 + +/* * LIBXL_HAVE_BUILDINFO_HVM_VENDOR_DEVICE indicates that the * libxl_vendor_device field is present in the hvm sections of * libxl_domain_build_info. This field tells libxl which
@@ -973,6 +987,22 @@ int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, libxl_bitmap *cpumap);int libxl_set_vcpuaffinity_all (libxl_ctx *ctx,uint32_t domid,unsigned int max_vcpus,libxl_bitmap *cpumap); +int libxl_set_vcpuaffinity2 (libxl_ctx *ctx,uint32_t domid,uint32_t vcpuid, +const libxl_bitmap *cpumap,int flags); +int libxl_set_vcpuaffinity_all2 (libxl_ctx *ctx,uint32_t domid, +unsigned int max_vcpus, +const libxl_bitmap *cpumap,int flags); +int libxl_set_vcpuaffinity3 (libxl_ctx *ctx,uint32_t domid,uint32_t vcpuid, +const libxl_bitmap *cpumap_hard, +const libxl_bitmap *cpumap_soft); +int libxl_set_vcpuaffinity_all3 (libxl_ctx *ctx,uint32_t domid, +unsigned int max_vcpus, +const libxl_bitmap *cpumap_hard, +const libxl_bitmap *cpumap_soft); +/* Flags, consistent with domctl.h */ +#define LIBXL_VCPUAFFINITY_HARD 1 +#define LIBXL_VCPUAFFINITY_SOFT 2 +int libxl_domain_set_nodeaffinity (libxl_ctx *ctx,uint32_t domid,libxl_bitmap *nodemap); int libxl_domain_get_nodeaffinity(libxl_ctx *ctx, uint32_t domid,
tools/libxl/libxl_create.c +6 -0
@@ -192,6 +192,12 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,libxl_bitmap_set_any (&b_info->cpumap); } +if (!b_info->cpumap_soft.size) { +if (libxl_cpu_bitmap_alloc (CTX , &b_info->cpumap_soft,0 )) +return ERROR_FAIL ; +libxl_bitmap_set_any (&b_info->cpumap_soft); + } +libxl_defbool_setdefault (&b_info->numa_placement, true);if (!b_info->nodemap.size) {
tools/libxl/libxl_types.idl +3 -1
@@ -297,6 +297,7 @@ libxl_domain_build_info = Struct("domain_build_info",[ ("max_vcpus", integer), ("avail_vcpus", libxl_bitmap), ("cpumap", libxl_bitmap), + ("cpumap_soft", libxl_bitmap), ("nodemap", libxl_bitmap), ("numa_placement", libxl_defbool), ("tsc_mode", libxl_tsc_mode),
@@ -509,7 +510,8 @@ libxl_vcpuinfo = Struct("vcpuinfo", [ ("blocked", bool), ("running", bool), ("vcpu_time", uint64), # total vcpu time ran (ns) - ("cpumap", libxl_bitmap), # current cpu's affinities + ("cpumap", libxl_bitmap), # current hard cpu affinity + ("cpumap_soft", libxl_bitmap), # current soft cpu affinity ], dir=DIR_OUT) libxl_physinfo = Struct("physinfo", [
tools/libxl/libxl_utils.h +15 -0
@@ -98,6 +98,21 @@ static inline int libxl_bitmap_cpu_valid(libxl_bitmap *bitmap, int bit)#define libxl_for_each_set_bit (v, m) for (v = 0; v < (m).size * 8; v++) \ if (libxl_bitmap_test(&(m), v)) +static inline int libxl_bitmap_equal (const libxl_bitmap *ba, +const libxl_bitmap *bb, +int nr_bits) +{ +int i; + +/* Only check nr_bits (all bits if <= 0) */ + nr_bits = nr_bits <=0 ? ba->size *8 : nr_bits; +for (i =0 ; i < nr_bits; i++) { +if (libxl_bitmap_test (ba, i) !=libxl_bitmap_test (bb, i)) +return 0 ; + } +return 1 ; +} +int libxl_cpu_bitmap_alloc (libxl_ctx *ctx,libxl_bitmap *cpumap,int max_cpus);
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 22 lines · Dario Faggioli
Make space for two new cpumap-s, one in
vcpu_info(for getting soft affinity) andbuild_info(for setting it). Provide two new API calls:*
libxl_set_vcpuaffinity2, taking a cpumap and setting eitherhard, soft or both affinity to it, depending on 'flags';*
libxl_set_vcpuaffinity3, taking two cpumap, one for hard and one for soft affinity.The bheavior of the existing
libxl_set_vcpuaffinityis left unchanged, i.e., it only set hard affinity.Getting soft affinity happens indirectly, via `xl vcpu-list' (as it is already for hard affinity).
The new calls include logic to check whether the affinity which will be used by Xen to schedule the vCPU(s) does actually match with the cpumap provided. In fact, we want to allow every possible combination of hard and soft affinities to be set, but we warn the user upon particularly weird combinations (e.g., hard and soft being disjoint sets of pCPUs).
Quoted 4 lines
Also, this is the first change breaking the libxl ABI, so it bumps the MAJOR.
Signed-off-by Dario Faggioli <[email protected]>
The interface is fine with me (I would probably just have 2 and not 3, but I'm OK with both). Just a few minor comments:
tools/libxl/libxl.h int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, · line 994
Quoted 9 lines
tools/libxl/libxl.h +5
-0@@ -973,6 +987,22 @@ int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, libxl_bitmap *cpumap);int libxl_set_vcpuaffinity_all (libxl_ctx *ctx,uint32_t domid,unsigned int max_vcpus,libxl_bitmap *cpumap); +int libxl_set_vcpuaffinity2 (libxl_ctx *ctx,uint32_t domid,uint32_t vcpuid, +const libxl_bitmap *cpumap,int flags); +int libxl_set_vcpuaffinity_all2 (libxl_ctx *ctx,uint32_t domid, +unsigned int max_vcpus, +const libxl_bitmap *cpumap,int flags);
Should we have a bit more documentation about the behavior of "flags" somewhere?
Quoted 6 lines
tools/libxl/libxl_utils.h +0
-0@@ -98,6 +98,21 @@ static inline int libxl_bitmap_cpu_valid(libxl_bitmap *bitmap, int bit)#define libxl_for_each_set_bit (v, m) for (v = 0; v < (m).size * 8; v++) \
tools/libxl/libxl_utils.h static inline int libxl_bitmap_cpu_valid(libxl_bitmap *bitmap, int bit) · line 108
Quoted 10 lines
tools/libxl/libxl_utils.h +8
-0if (libxl_bitmap_test (&(m), v)) +static inline int libxl_bitmap_equal(const libxl_bitmap *ba, +const libxl_bitmap *bb, +int nr_bits) +{ +int i; + +/* Only check nr_bits (all bits if <= 0) */ + nr_bits = nr_bits <=0 ? ba->size *8 : nr_bits;
The conditional should really have parenthesis around it, I'm pretty sure; and the spacing is inconsistent.
-George
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 23 lines · George Dunlap
Quoted 22 lines · Dario Faggioli
Make space for two new cpumap-s, one in
vcpu_info(for getting soft affinity) andbuild_info(for setting it). Provide two new API calls:*
libxl_set_vcpuaffinity2, taking a cpumap and setting eitherhard, soft or both affinity to it, depending on 'flags';*
libxl_set_vcpuaffinity3, taking two cpumap, one for hard and one for soft affinity.The bheavior of the existing
libxl_set_vcpuaffinityis left unchanged, i.e., it only set hard affinity.Getting soft affinity happens indirectly, via `xl vcpu-list' (as it is already for hard affinity).
The new calls include logic to check whether the affinity which will be used by Xen to schedule the vCPU(s) does actually match with the cpumap provided. In fact, we want to allow every possible combination of hard and soft affinities to be set, but we warn the user upon particularly weird combinations (e.g., hard and soft being disjoint sets of pCPUs).
Quoted 8 lines
Quoted 4 lines
Also, this is the first change breaking the libxl ABI, so it bumps the MAJOR.
Signed-off-by Dario Faggioli <[email protected]>The interface is fine with me (I would probably just have 2 and not 3, but I'm OK with both). Just a few minor comments:
the '3' variant (tries to) accomplish what IanJ explicitly asked: having a way to set both hard and soft affinity at the same time, and each with its own value, and only checking for consistency at the very end.
I also wasn't sure whether that would have been actually useful but, I have to admit, it turned out it is, as it can be seen in the following patches, when the interface is used to (re)implement both the existing and the new xl commands and command variants.
Let's see what IanJ thinks, I guess. :-)
Quoted 4 lines
Quoted 4 lines
tools/libxl/libxl.h +0
-0@@ -973,6 +987,22 @@ int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, libxl_bitmap *cpumap);int libxl_set_vcpuaffinity_all (libxl_ctx *ctx,uint32_t domid,unsigned int max_vcpus,libxl_bitmap *cpumap);
Quoted 9 lines
tools/libxl/libxl.h int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, · line 994
Quoted 5 lines
tools/libxl/libxl.h +5
-0+int libxl_set_vcpuaffinity2 (libxl_ctx *ctx,uint32_t domid,uint32_t vcpuid, +const libxl_bitmap *cpumap,int flags); +int libxl_set_vcpuaffinity_all2 (libxl_ctx *ctx,uint32_t domid, +unsigned int max_vcpus, +const libxl_bitmap *cpumap,int flags);Should we have a bit more documentation about the behavior of "flags" somewhere?
Fair enough. I can respin with that added.
Quoted 8 lines
Quoted 8 lines
tools/libxl/libxl_utils.h +0
-0@@ -98,6 +98,21 @@ static inline int libxl_bitmap_cpu_valid(libxl_bitmap *bitmap, int bit)#define libxl_for_each_set_bit (v, m) for (v = 0; v < (m).size * 8; v++) \ if (libxl_bitmap_test(&(m), v))
Quoted 12 lines
tools/libxl/libxl_utils.h static inline int libxl_bitmap_cpu_valid(libxl_bitmap *bitmap, int bit) · line 108
Quoted 8 lines
tools/libxl/libxl_utils.h +8
-0+static inline int libxl_bitmap_equal (const libxl_bitmap *ba, +const libxl_bitmap *bb, +int nr_bits) +{ +int i; + +/* Only check nr_bits (all bits if <= 0) */ + nr_bits = nr_bits <=0 ? ba->size *8 : nr_bits;The conditional should really have parenthesis around it, I'm pretty sure; and the spacing is inconsistent.
Right. Will do.
Thanks and Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 10 lines · Dario Faggioli
Quoted 9 lines · George Dunlap
Quoted 8 lines · Dario Faggioli
Make space for two new cpumap-s, one in
vcpu_info(for getting soft affinity) andbuild_info(for setting it). Provide two new API calls:*
libxl_set_vcpuaffinity2, taking a cpumap and setting eitherhard, soft or both affinity to it, depending on 'flags';*
libxl_set_vcpuaffinity3, taking two cpumap, one for hard and one for soft affinity.
I must confess that in the end I really dislike these foo, fooN, fooM style functions. Can we not use LIBXL_APIVERSION here to allow us to uprev the API?
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
The bheavior of the existing
libxl_set_vcpuaffinityis left unchanged, i.e., it only set hard affinity.Getting soft affinity happens indirectly, via `xl vcpu-list' (as it is already for hard affinity).
The new calls include logic to check whether the affinity which will be used by Xen to schedule the vCPU(s) does actually match with the cpumap provided. In fact, we want to allow every possible combination of hard and soft affinities to be set, but we warn the user upon particularly weird combinations (e.g., hard and soft being disjoint sets of pCPUs).
Also, this is the first change breaking the libxl ABI, so it bumps the MAJOR.
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
Signed-off-by Dario Faggioli <[email protected]>The interface is fine with me (I would probably just have 2 and not 3, but I'm OK with both). Just a few minor comments:
the '3' variant (tries to) accomplish what IanJ explicitly asked: having a way to set both hard and soft affinity at the same time, and each with its own value, and only checking for consistency at the very end.
Can this not be accomplished by a single function which accepts one or zero of the bitmasks being NULL?
Quoted 4 lines
I also wasn't sure whether that would have been actually useful but, I have to admit, it turned out it is, as it can be seen in the following patches, when the interface is used to (re)implement both the existing and the new xl commands and command variants.
So did ...2 turn out not to be useful? Lets not provide both in that case.
Quoted 3 lines
Let's see what IanJ thinks, I guess. :-)
Ian.C.
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 7 lines · Ian Campbell
Quoted 6 lines · Dario Faggioli
Quoted 5 lines · George Dunlap
Quoted 4 lines · Dario Faggioli
Make space for two new cpumap-s, one in
vcpu_info(for getting soft affinity) andbuild_info(for setting it). Provide two new API calls:
Quoted 9 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
*
libxl_set_vcpuaffinity2, taking a cpumap and setting eitherhard, soft or both affinity to it, depending on 'flags';*
libxl_set_vcpuaffinity3, taking two cpumap, one for hard and one for soft affinity.I must confess that in the end I really dislike these foo, fooN, fooM style functions. Can we not use
LIBXL_APIVERSIONhere to allow us to uprev the API?
We probably can. Situation is as follows:
- George wanted something like what libxl_set_vcpuaffinity2 does
- IanJ wanted something like what libxl_set_vcpuaffinity3 does
- After having introduced them, I actually find uses for both of them, and hence I kept them
As per the mechanism used to amend the current API, I don't have a real preference. Both me and George asked (in a previous thread) what mechanism we should use, but we did not get much feedback at that time (not complain, just summing up what has happened).
Right now, I think I just need for someone authoritative enough to express his preference. You certainly qualify as such, but, if possible, I'd like to see what the other Ian thinks too, as he's been quite deeply involved in reviewing this interface.
So, IanJ, any thoughts?
Quoted 7 lines
Quoted 3 lines
the '3' variant (tries to) accomplish what IanJ explicitly asked: having a way to set both hard and soft affinity at the same time, and each with its own value, and only checking for consistency at the very end.
Can this not be accomplished by a single function which accepts one or zero of the bitmasks being NULL?
I'll see whether that's true, but yes, I think I can do that.
Quoted 8 lines
Quoted 4 lines
I also wasn't sure whether that would have been actually useful but, I have to admit, it turned out it is, as it can be seen in the following patches, when the interface is used to (re)implement both the existing and the new xl commands and command variants.
So did ...2 turn out not to be useful? Lets not provide both in that case.
It (unfortunately) did. :-/
Thanks and Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 4 lines · Dario Faggioli
As per the mechanism used to amend the current API, I don't have a real preference. Both me and George asked (in a previous thread) what mechanism we should use, but we did not get much feedback at that time (not complain, just summing up what has happened).
Yes, sorry about that.
Quoted 4 lines
Right now, I think I just need for someone authoritative enough to express his preference. You certainly qualify as such, but, if possible, I'd like to see what the other Ian thinks too, as he's been quite deeply involved in reviewing this interface.
I think the major argument in favour of the LIBXL_API_VERSION based approach is that this is how we have dealt with all the previous such changes. Having a mixture of this and fooN interfaces seems to me to be worse that either option by itself.
Quoted 8 lines
Quoted 7 lines
Quoted 3 lines
the '3' variant (tries to) accomplish what IanJ explicitly asked: having a way to set both hard and soft affinity at the same time, and each with its own value, and only checking for consistency at the very end.
Can this not be accomplished by a single function which accepts one or zero of the bitmasks being NULL?
I'll see whether that's true, but yes, I think I can do that.
Thanks,
Ian.
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 7 lines · Ian Campbell
Quoted 4 lines · Dario Faggioli
As per the mechanism used to amend the current API, I don't have a real preference. Both me and George asked (in a previous thread) what mechanism we should use, but we did not get much feedback at that time (not complain, just summing up what has happened).
Yes, sorry about that.
Quoted 8 lines
Quoted 4 lines
Right now, I think I just need for someone authoritative enough to express his preference. You certainly qualify as such, but, if possible, I'd like to see what the other Ian thinks too, as he's been quite deeply involved in reviewing this interface.
I think the major argument in favour of the
LIBXL_API_VERSIONbased approach is that this is how we have dealt with all the previous such changes. Having a mixture of this and fooN interfaces seems to me to be worse that either option by itself.
Just to be clear -- if we bump the API number, then we have to do some #ifdef-ery to allow programs compiled against the old API to compile, right?
-George
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 12 lines · George Dunlap
Quoted 11 lines · Ian Campbell
Quoted 4 lines · Dario Faggioli
As per the mechanism used to amend the current API, I don't have a real preference. Both me and George asked (in a previous thread) what mechanism we should use, but we did not get much feedback at that time (not complain, just summing up what has happened).
Yes, sorry about that.
Quoted 4 lines
Right now, I think I just need for someone authoritative enough to express his preference. You certainly qualify as such, but, if possible, I'd like to see what the other Ian thinks too, as he's been quite deeply involved in reviewing this interface.
Quoted 7 lines
Quoted 4 lines
I think the major argument in favour of the
LIBXL_API_VERSIONbased approach is that this is how we have dealt with all the previous such changes. Having a mixture of this and fooN interfaces seems to me to be worse that either option by itself.Just to be clear -- if we bump the API number, then we have to do some #ifdef-ery to allow programs compiled against the old API to compile, right?
Yes.
I expect that the libxl_domain_create_restore machinery is the template which would be desired here.
This does not remove the need for a LIBXL_HAVE_FOO either -- they are somewhat orthogonal. (In practice at least libvirt prefers the LIBXL_HAVE mechanism)
Ian.
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Ian Campbell writes ("Re: [PATCH v3 11/14] libxl: get and set soft affinity"):
Quoted 12 lines · George Dunlap
Quoted 2 lines
Just to be clear -- if we bump the API number, then we have to do some #ifdef-ery to allow programs compiled against the old API to compile, right?
Yes.
I expect that the
libxl_domain_create_restoremachinery is the template which would be desired here.This does not remove the need for a
LIBXL_HAVE_FOOeither -- they are somewhat orthogonal. (In practice at least libvirt prefers theLIBXL_HAVEmechanism)
For the record, I don't object to this approach, if that's what George and Ian C prefer. I agree that the profusion of variants is ugly.
Ian.
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 11 lines · Ian Jackson
Ian Campbell writes ("Re: [PATCH v3 11/14] libxl: get and set soft affinity"):
Quoted 6 lines
I expect that the
libxl_domain_create_restoremachinery is the template which would be desired here.This does not remove the need for a
LIBXL_HAVE_FOOeither -- they are somewhat orthogonal. (In practice at least libvirt prefers theLIBXL_HAVEmechanism)For the record, I don't object to this approach, if that's what George and Ian C prefer. I agree that the profusion of variants is ugly.
Fine then. Going for it.
Thanks and Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v3 11/14] libxl: get and set soft affinity
In reply to Dario FaggioliQuoted 35 lines · Dario Faggioli
Quoted 23 lines · George Dunlap
Quoted 22 lines · Dario Faggioli
Make space for two new cpumap-s, one in
vcpu_info(for getting soft affinity) andbuild_info(for setting it). Provide two new API calls:*
libxl_set_vcpuaffinity2, taking a cpumap and setting eitherhard, soft or both affinity to it, depending on 'flags';*
libxl_set_vcpuaffinity3, taking two cpumap, one for hard and one for soft affinity.The bheavior of the existing
libxl_set_vcpuaffinityis left unchanged, i.e., it only set hard affinity.Getting soft affinity happens indirectly, via `xl vcpu-list' (as it is already for hard affinity).
The new calls include logic to check whether the affinity which will be used by Xen to schedule the vCPU(s) does actually match with the cpumap provided. In fact, we want to allow every possible combination of hard and soft affinities to be set, but we warn the user upon particularly weird combinations (e.g., hard and soft being disjoint sets of pCPUs).
Quoted 7 lines
Quoted 4 lines
Also, this is the first change breaking the libxl ABI, so it bumps the MAJOR.
Signed-off-by Dario Faggioli <[email protected]>The interface is fine with me (I would probably just have 2 and not 3, but I'm OK with both). Just a few minor comments:
the '3' variant (tries to) accomplish what IanJ explicitly asked: having a way to set both hard and soft affinity at the same time, and each with its own value, and only checking for consistency at the very end.
Quoted 6 lines
I also wasn't sure whether that would have been actually useful but, I have to admit, it turned out it is, as it can be seen in the following patches, when the interface is used to (re)implement both the existing and the new xl commands and command variants.
Let's see what IanJ thinks, I guess. :-)
BTW, I wasn't complaining -- I know IanJ wanted it the second way; I was just re-registering my preference. :-)
-George
Re: [PATCH v3 11/14] libxl: get and set soft affinity
In reply to Dario FaggioliQuoted 79 lines · Dario Faggioli
Make space for two new cpumap-s, one in
vcpu_info(for getting soft affinity) andbuild_info(for setting it). Provide two new API calls:*
libxl_set_vcpuaffinity2, taking a cpumap and setting either hard, soft or both affinity to it, depending on 'flags';
*libxl_set_vcpuaffinity3, taking two cpumap, one for hard and one for soft affinity.The bheavior of the existing
libxl_set_vcpuaffinityis left unchanged, i.e., it only set hard affinity.Getting soft affinity happens indirectly, via `xl vcpu-list' (as it is already for hard affinity).
The new calls include logic to check whether the affinity which will be used by Xen to schedule the vCPU(s) does actually match with the cpumap provided. In fact, we want to allow every possible combination of hard and soft affinities to be set, but we warn the user upon particularly weird combinations (e.g., hard and soft being disjoint sets of pCPUs).
Also, this is the first change breaking the libxl ABI, so it bumps the MAJOR.
Signed-off-by Dario Faggioli <[email protected]>---
Changes from v2:
* interface completely redesigned, as discussed during review.--- tools/libxl/Makefile | 2 - tools/libxl/libxl.c | 131 +++++++++++++++++++++++++++++++++++++++++++ tools/libxl/libxl.h | 30 ++++++++++ tools/libxl/libxl_create.c | 6 ++ tools/libxl/libxl_types.idl | 4 + tools/libxl/libxl_utils.h | 15 +++++ 6 files changed, 186 insertions(+), 2 deletions(-)tools/libxl/Makefile +1
-1@@ -5,7 +5,7 @@ XEN_ROOT = $(CURDIR)/../.. include $(XEN_ROOT)/tools/Rules.mk -MAJOR = 4.3 +MAJOR = 4.4 MINOR = 0 XLUMAJOR = 4.3tools/libxl/libxl.c +8
-0@@ -4204,6 +4204,8 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid,for (*nb_vcpu =0 ; *nb_vcpu <= domaininfo.max_vcpu_id; ++*nb_vcpu, ++ptr) {if (libxl_cpu_bitmap_alloc (ctx, &ptr->cpumap,0 ))return NULL ; +if (libxl_cpu_bitmap_alloc (ctx, &ptr->cpumap_soft,0 )) +return NULL ;if (xc_vcpu_getinfo (ctx->xch, domid, *nb_vcpu, &vcpuinfo) ==-1 ) {LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR ,"getting vcpu info" );return NULL ;@@ -4214,6 +4216,12 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid,LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR ,"getting vcpu affinity" );return NULL ; } +if (xc_vcpu_getaffinity (ctx->xch, domid, *nb_vcpu, +XEN_VCPUAFFINITY_SOFT , + ptr->cpumap_soft.map) ==-1 ) { +LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR ,"getting vcpu affinity" ); +return NULL ; + } ptr->vcpuid = *nb_vcpu; ptr->cpu = vcpuinfo.cpu; ptr->online = !!vcpuinfo.online;
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4262
Quoted 5 lines
tools/libxl/libxl.c +2
-0@@ -4250,6 +4258,129 @@ int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid,return rc; } +int libxl_set_vcpuaffinity2 (libxl_ctx *ctx,uint32_t domid,uint32_t vcpuid, +const libxl_bitmap *cpumap,int flags)
I think if we are going to duplicate hte API in this way then we should still combine the implementation, either with an internal private helper or by making the old API a wrapper around the new one.
The internals of ...2 and ...3 should be shared as far as possible too.
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4270
Quoted 8 lines
tools/libxl/libxl.c +8
-0+{ +libxl_cputopology *topology; +libxl_bitmap ecpumap; +int nr_cpus =0 , rc; + + topology =libxl_get_cpu_topology (ctx, &nr_cpus); +if (!topology) { +LIBXL__LOG (ctx,LIBXL__LOG_ERROR ,"failed to retrieve CPU topology" );
It's not consistent within the file but I think for new functions we should use the LOG macro variants.
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4273
Quoted 3 lines
tools/libxl/libxl.c +3
-0+return ERROR_FAIL ; + } +libxl_cputopology_list_free (topology, nr_cpus);
Why are you retrieving this only to immediately throw it away?
Quoted 9 lines
tools/libxl/libxl.c +9
-0+ + rc =libxl_cpu_bitmap_alloc (ctx, &ecpumap,0 ); +if (rc) +return rc; + +if (xc_vcpu_setaffinity (ctx->xch, domid, vcpuid, cpumap->map, + flags, ecpumap.map)) { +LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR ,"setting vcpu affinity" ); + rc =ERROR_FAIL ;
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4292
Quoted 10 lines
tools/libxl/libxl.c +10
-0+ goto out; + } + +if (!libxl_bitmap_equal (cpumap, &ecpumap, nr_cpus)) +LIBXL__LOG (ctx,LIBXL__LOG_DEBUG , +"New affinity for vcpu %d contains unreachable cpus" , + vcpuid); +if (libxl_bitmap_is_empty (&ecpumap)) +LIBXL__LOG (ctx,LIBXL__LOG_WARNING , + "New affinity for vcpu %d has only unreachabel cpus. "
"unreachable"
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4320
Quoted 12 lines
tools/libxl/libxl.c +11
-0+"Only hard affinity will be considered for scheduling" , + vcpuid); + + rc =0 ; + out: +libxl_bitmap_dispose (&ecpumap); +return 0 ; +} +int libxl_set_vcpuaffinity3 (libxl_ctx *ctx,uint32_t domid,uint32_t vcpuid, +const libxl_bitmap *cpumap_hard, +const libxl_bitmap *cpumap_soft)
Insert the same comments as ...2, because AFAICT it is mostly the same function.
Quoted 10 lines
tools/libxl/libxl.h +2
-0@@ -82,6 +82,20 @@#define LIBXL_HAVE_DOMAIN_NODEAFFINITY 1/* +* LIBXL_HAVE_VCPUINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_vcpuinfo,
tools/libxl/libxl.h line 96
Quoted 10 lines
tools/libxl/libxl.h +10
-0+* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_VCPUINFO_SOFTAFFINITY 1 + +/* +* LIBXL_HAVE_BUILDINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_domain_build_info, +* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_BUILDINFO_SOFTAFFINITY 1
Given that they arrive can we just use HAVE_SOFTRAFFINITY?
Quoted 14 lines
tools/libxl/libxl.h +7
-0+ +/* * LIBXL_HAVE_BUILDINFO_HVM_VENDOR_DEVICE indicates that the * libxl_vendor_device field is present in the hvm sections of * libxl_domain_build_info. This field tells libxl which @@ -973,6 +987,22 @@ int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, libxl_bitmap *cpumap);int libxl_set_vcpuaffinity_all (libxl_ctx *ctx,uint32_t domid,unsigned int max_vcpus,libxl_bitmap *cpumap); +int libxl_set_vcpuaffinity2 (libxl_ctx *ctx,uint32_t domid,uint32_t vcpuid, +const libxl_bitmap *cpumap,int flags); +int libxl_set_vcpuaffinity_all2 (libxl_ctx *ctx,uint32_t domid, +unsigned int max_vcpus, +const libxl_bitmap *cpumap,int flags);
tools/libxl/libxl.h int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, · line 1004
Quoted 10 lines
tools/libxl/libxl.h +10
-0+int libxl_set_vcpuaffinity3 (libxl_ctx *ctx,uint32_t domid,uint32_t vcpuid, +const libxl_bitmap *cpumap_hard, +const libxl_bitmap *cpumap_soft); +int libxl_set_vcpuaffinity_all3 (libxl_ctx *ctx,uint32_t domid, +unsigned int max_vcpus, +const libxl_bitmap *cpumap_hard, +const libxl_bitmap *cpumap_soft); +/* Flags, consistent with domctl.h */ +#define LIBXL_VCPUAFFINITY_HARD 1 +#define LIBXL_VCPUAFFINITY_SOFT 2
Can these be an enum in the idl?
Quoted 5 lines
tools/libxl/libxl.h +1
-0+int libxl_domain_set_nodeaffinity (libxl_ctx *ctx,uint32_t domid,libxl_bitmap *nodemap); int libxl_domain_get_nodeaffinity(libxl_ctx *ctx, uint32_t domid,tools/libxl/libxl_create.c +0
-0
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 11 lines · Ian Campbell
Review
Quoted 4 lines
Signed-off-by Dario Faggioli <[email protected]>(quoted diff) +2
-0+int libxl_set_vcpuaffinity2(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, + const libxl_bitmap *cpumap, int flags)I think if we are going to duplicate hte API in this way then we should still combine the implementation, either with an internal private helper or by making the old API a wrapper around the new one.
The internals of ...2 and ...3 should be shared as far as possible too.
Ok, this can be done, I think.
Quoted 12 lines
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4270
Quoted 8 lines
tools/libxl/libxl.c +8
-0+{ +libxl_cputopology *topology; +libxl_bitmap ecpumap; +int nr_cpus =0 , rc; + + topology =libxl_get_cpu_topology (ctx, &nr_cpus); +if (!topology) { +LIBXL__LOG (ctx,LIBXL__LOG_ERROR ,"failed to retrieve CPU topology" );It's not consistent within the file but I think for new functions we should use the LOG macro variants.
Right, but don't I need a gc to use it? Should I "make up" one just for the purpose of using LOG/LOGE?
Quoted 6 lines
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4273
Quoted 3 lines
tools/libxl/libxl.c +3
-0+return ERROR_FAIL ; + } +libxl_cputopology_list_free (topology, nr_cpus);Why are you retrieving this only to immediately throw it away?
Because I need nr_cpus. :-)
Quoted 7 lines
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4320
Quoted 3 lines
tools/libxl/libxl.c +3
-0+int libxl_set_vcpuaffinity3 (libxl_ctx *ctx,uint32_t domid,uint32_t vcpuid, +const libxl_bitmap *cpumap_hard, +const libxl_bitmap *cpumap_soft)Insert the same comments as ...2, because AFAICT it is mostly the same function.
I will.
Quoted 7 lines
Quoted 7 lines
tools/libxl/libxl.h +0
-0@@ -82,6 +82,20 @@#define LIBXL_HAVE_DOMAIN_NODEAFFINITY 1
Quoted 16 lines
tools/libxl/libxl.h line 96
Quoted 13 lines
tools/libxl/libxl.h +12
-0/* +* LIBXL_HAVE_VCPUINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_vcpuinfo, +* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_VCPUINFO_SOFTAFFINITY 1 + +/* +* LIBXL_HAVE_BUILDINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_domain_build_info, +* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_BUILDINFO_SOFTAFFINITY 1Given that they arrive can we just use
HAVE_SOFTRAFFINITY?
You mean just introducing one #define? Sure... For some reason I assumed that every new field should come with it's own symbol. But if it's fine to have one, I'm all for it. :-)
Quoted 6 lines
tools/libxl/libxl.h int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, · line 1004
Quoted 3 lines
tools/libxl/libxl.h +3
-0+/* Flags, consistent with domctl.h */ +#define LIBXL_VCPUAFFINITY_HARD 1 +#define LIBXL_VCPUAFFINITY_SOFT 2Can these be an enum in the idl?
I think yes.
I did actually check and, of all the enum-s in the IDL, none are used as flags, they're rather used as "single values". OTOH, the only actual flags I found (I think it was LIBXL_SUSPEND_DEBUG, LIBXL_SUSPEND_LIVE) were defined like I did myself above... That's why I went for it.
But again, if you're fine with these being enum, I will make them so.
Thanks and Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 12 lines · Dario Faggioli
Quoted 12 lines
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4270
Quoted 8 lines
tools/libxl/libxl.c +8
-0+{ +libxl_cputopology *topology; +libxl_bitmap ecpumap; +int nr_cpus =0 , rc; + + topology =libxl_get_cpu_topology (ctx, &nr_cpus); +if (!topology) { +LIBXL__LOG (ctx,LIBXL__LOG_ERROR ,"failed to retrieve CPU topology" );It's not consistent within the file but I think for new functions we should use the LOG macro variants.
Quoted 2 lines
Right, but don't I need a gc to use it? Should I "make up" one just for the purpose of using LOG/LOGE?
I think a call to GC_INIT/GC_FREE should be cheap enough.
Quoted 7 lines
Quoted 6 lines
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4273
Quoted 3 lines
tools/libxl/libxl.c +3
-0+return ERROR_FAIL ; + } +libxl_cputopology_list_free (topology, nr_cpus);Why are you retrieving this only to immediately throw it away?
Because I need
nr_cpus. :-)
Surely this is not the recommended way to get nr_cpus!
libxl_get_cpu_topology() itself calls libxl_get_max_cpus() which seems like the obvious candidate.
Quoted 23 lines
Quoted 7 lines
Quoted 7 lines
tools/libxl/libxl.h +0
-0@@ -82,6 +82,20 @@#define LIBXL_HAVE_DOMAIN_NODEAFFINITY 1Quoted 16 lines
tools/libxl/libxl.h line 96
Quoted 13 lines
tools/libxl/libxl.h +12
-0/* +* LIBXL_HAVE_VCPUINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_vcpuinfo, +* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_VCPUINFO_SOFTAFFINITY 1 + +/* +* LIBXL_HAVE_BUILDINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_domain_build_info, +* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_BUILDINFO_SOFTAFFINITY 1Given that they arrive can we just use
HAVE_SOFTRAFFINITY?
Quoted 3 lines
You mean just introducing one #define? Sure... For some reason I assumed that every new field should come with it's own symbol. But if it's fine to have one, I'm all for it. :-)
I think it's ok.
Quoted 7 lines
Quoted 7 lines
tools/libxl/libxl.h int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, · line 1004
Quoted 4 lines
tools/libxl/libxl.h +3
-0+/* Flags, consistent with domctl.h */ +#define LIBXL_VCPUAFFINITY_HARD 1 +#define LIBXL_VCPUAFFINITY_SOFT 2Can these be an enum in the idl?
Quoted 6 lines
I think yes.
I did actually check and, of all the enum-s in the IDL, none are used as flags, they're rather used as "single values". OTOH, the only actual flags I found (I think it was
LIBXL_SUSPEND_DEBUG,LIBXL_SUSPEND_LIVE) were defined like I did myself above... That's why I went for it.
I have a feeling they predate the IDL, or at least the Enumeration support. It's true that we don't have any other bit fields in enums though. I can't see the harm, it's probably not worth introducing a new IDL type for them.
Quoted 6 lines
But again, if you're fine with these being enum, I will make them so.
Thanks and Regards,
Dario
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 62 lines · Ian Campbell
Quoted 11 lines · Dario Faggioli
Quoted 11 lines
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4270
Quoted 8 lines
tools/libxl/libxl.c +8
-0+{ +libxl_cputopology *topology; +libxl_bitmap ecpumap; +int nr_cpus =0 , rc; + + topology =libxl_get_cpu_topology (ctx, &nr_cpus); +if (!topology) { +LIBXL__LOG (ctx,LIBXL__LOG_ERROR ,"failed to retrieve CPU topology" );It's not consistent within the file but I think for new functions we should use the LOG macro variants.
Quoted 2 lines
Right, but don't I need a gc to use it? Should I "make up" one just for the purpose of using LOG/LOGE?
I think a call to GC_INIT/GC_FREE should be cheap enough.
Quoted 6 lines
Quoted 5 lines
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4273
Quoted 3 lines
tools/libxl/libxl.c +3
-0+return ERROR_FAIL ; + } +libxl_cputopology_list_free (topology, nr_cpus);Why are you retrieving this only to immediately throw it away?
Because I need
nr_cpus. :-)Surely this is not the recommended way to get
nr_cpus!
libxl_get_cpu_topology()itself callslibxl_get_max_cpus()which seems like the obvious candidate.Quoted 22 lines
Quoted 7 lines
Quoted 7 lines
tools/libxl/libxl.h +0
-0@@ -82,6 +82,20 @@#define LIBXL_HAVE_DOMAIN_NODEAFFINITY 1Quoted 15 lines
tools/libxl/libxl.h line 96
Quoted 13 lines
tools/libxl/libxl.h +12
-0/* +* LIBXL_HAVE_VCPUINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_vcpuinfo, +* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_VCPUINFO_SOFTAFFINITY 1 + +/* +* LIBXL_HAVE_BUILDINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_domain_build_info, +* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_BUILDINFO_SOFTAFFINITY 1Given that they arrive can we just use
HAVE_SOFTRAFFINITY?Quoted 3 lines
You mean just introducing one #define? Sure... For some reason I assumed that every new field should come with it's own symbol. But if it's fine to have one, I'm all for it. :-)
I think it's ok.
Quoted 7 lines
Quoted 5 lines
tools/libxl/libxl.h int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, · line 1004
Quoted 3 lines
tools/libxl/libxl.h +3
-0+/* Flags, consistent with domctl.h */ +#define LIBXL_VCPUAFFINITY_HARD 1 +#define LIBXL_VCPUAFFINITY_SOFT 2Can these be an enum in the idl?
I think yes.
Quoted 8 lines
Quoted 4 lines
I did actually check and, of all the enum-s in the IDL, none are used as flags, they're rather used as "single values". OTOH, the only actual flags I found (I think it was
LIBXL_SUSPEND_DEBUG,LIBXL_SUSPEND_LIVE) were defined like I did myself above... That's why I went for it.I have a feeling they predate the IDL, or at least the Enumeration support. It's true that we don't have any other bit fields in enums though. I can't see the harm, it's probably not worth introducing a new IDL type for them.
Since these are bits, not numbers, I don't think an enum is the right construct. Or, the enum values should be the *bit numbers*, and the flags should be (1<<[bit_humber]).
-George
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 67 lines · George Dunlap
Quoted 66 lines · Ian Campbell
Quoted 11 lines · Dario Faggioli
Quoted 11 lines
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4270
Quoted 8 lines
tools/libxl/libxl.c +8
-0+{ +libxl_cputopology *topology; +libxl_bitmap ecpumap; +int nr_cpus =0 , rc; + + topology =libxl_get_cpu_topology (ctx, &nr_cpus); +if (!topology) { +LIBXL__LOG (ctx,LIBXL__LOG_ERROR ,"failed to retrieve CPU topology" );It's not consistent within the file but I think for new functions we should use the LOG macro variants.
Quoted 2 lines
Right, but don't I need a gc to use it? Should I "make up" one just for the purpose of using LOG/LOGE?
I think a call to GC_INIT/GC_FREE should be cheap enough.
Quoted 6 lines
Quoted 5 lines
tools/libxl/libxl.c int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, · line 4273
Quoted 3 lines
tools/libxl/libxl.c +3
-0+return ERROR_FAIL ; + } +libxl_cputopology_list_free (topology, nr_cpus);Why are you retrieving this only to immediately throw it away?
Because I need
nr_cpus. :-)Surely this is not the recommended way to get
nr_cpus!
libxl_get_cpu_topology()itself callslibxl_get_max_cpus()which seems like the obvious candidate.Quoted 22 lines
Quoted 7 lines
Quoted 7 lines
tools/libxl/libxl.h +0
-0@@ -82,6 +82,20 @@#define LIBXL_HAVE_DOMAIN_NODEAFFINITY 1Quoted 15 lines
tools/libxl/libxl.h line 96
Quoted 13 lines
tools/libxl/libxl.h +12
-0/* +* LIBXL_HAVE_VCPUINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_vcpuinfo, +* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_VCPUINFO_SOFTAFFINITY 1 + +/* +* LIBXL_HAVE_BUILDINFO_SOFTAFFINITY indicates that a 'cpumap_soft' +* field (of libxl_bitmap type) is present in libxl_domain_build_info, +* containing the soft affinity for the vcpu. +*/ +#define LIBXL_HAVE_BUILDINFO_SOFTAFFINITY 1Given that they arrive can we just use
HAVE_SOFTRAFFINITY?Quoted 3 lines
You mean just introducing one #define? Sure... For some reason I assumed that every new field should come with it's own symbol. But if it's fine to have one, I'm all for it. :-)
I think it's ok.
Quoted 11 lines
Quoted 5 lines
tools/libxl/libxl.h int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, · line 1004
Quoted 3 lines
tools/libxl/libxl.h +3
-0+/* Flags, consistent with domctl.h */ +#define LIBXL_VCPUAFFINITY_HARD 1 +#define LIBXL_VCPUAFFINITY_SOFT 2Can these be an enum in the idl?
I think yes.
I did actually check and, of all the enum-s in the IDL, none are used as flags, they're rather used as "single values". OTOH, the only actual flags I found (I think it was
LIBXL_SUSPEND_DEBUG,LIBXL_SUSPEND_LIVE) were defined like I did myself above... That's why I went for it.
Quoted 8 lines
Quoted 4 lines
I have a feeling they predate the IDL, or at least the Enumeration support. It's true that we don't have any other bit fields in enums though. I can't see the harm, it's probably not worth introducing a new IDL type for them.
Since these are bits, not numbers, I don't think an enum is the right construct. Or, the enum values should be the *bit numbers*, and the flags should be (1<<[bit_humber]).
That would need a new IDL type to express. In which case lets just leave the raw #defines, unless anyone else has a strong opinion.
Ian.
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 11 lines · Ian Campbell
Quoted 10 lines · George Dunlap
Quoted 8 lines · Ian Campbell
Quoted 4 lines
I did actually check and, of all the enum-s in the IDL, none are used as flags, they're rather used as "single values". OTOH, the only actual flags I found (I think it was
LIBXL_SUSPEND_DEBUG,LIBXL_SUSPEND_LIVE) were defined like I did myself above... That's why I went for it.I have a feeling they predate the IDL, or at least the Enumeration support. It's true that we don't have any other bit fields in enums though. I can't see the harm, it's probably not worth introducing a new IDL type for them.
Quoted 7 lines
Quoted 3 lines
Since these are bits, not numbers, I don't think an enum is the right construct. Or, the enum values should be the *bit numbers*, and the flags should be (1<<[bit_humber]).
That would need a new IDL type to express. In which case lets just leave the raw #defines, unless anyone else has a strong opinion.
That would probably the best option, at least for now. Of course, I can add "introduce a new IDL type for bitfields" to my TODO list, and send a followup patch for 4.5.
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 14 lines · Dario Faggioli
Quoted 13 lines · Ian Campbell
Quoted 12 lines · George Dunlap
Quoted 8 lines · Ian Campbell
Quoted 4 lines
I did actually check and, of all the enum-s in the IDL, none are used as flags, they're rather used as "single values". OTOH, the only actual flags I found (I think it was
LIBXL_SUSPEND_DEBUG,LIBXL_SUSPEND_LIVE) were defined like I did myself above... That's why I went for it.I have a feeling they predate the IDL, or at least the Enumeration support. It's true that we don't have any other bit fields in enums though. I can't see the harm, it's probably not worth introducing a new IDL type for them.
Since these are bits, not numbers, I don't think an enum is the right construct. Or, the enum values should be the *bit numbers*, and the flags should be (1<<[bit_humber]).
Quoted 6 lines
Quoted 3 lines
That would need a new IDL type to express. In which case lets just leave the raw #defines, unless anyone else has a strong opinion.
That would probably the best option, at least for now. Of course, I can add "introduce a new IDL type for bitfields" to my TODO list, and send a followup patch for 4.5.
But if we end up doing as IanC suggests -- having a new function which accepts two pointers, either of which can be NULL -- then the need for these OR-able flags goes away, doesn't it?
-George
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 9 lines · George Dunlap
Quoted 3 lines · Dario Faggioli
That would probably the best option, at least for now. Of course, I can add "introduce a new IDL type for bitfields" to my TODO list, and send a followup patch for 4.5.
But if we end up doing as IanC suggests -- having a new function which accepts two pointers, either of which can be NULL -- then the need for these OR-able flags goes away, doesn't it?
Good point, it indeed does. I just became even more a fan of that solution then. :-D
Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v3 11/14] libxl: get and set soft affinity
In reply to Ian CampbellQuoted 6 lines · Ian Campbell
Quoted 2 lines · Dario Faggioli
Right, but don't I need a gc to use it? Should I "make up" one just for the purpose of using LOG/LOGE?
I think a call to GC_INIT/GC_FREE should be cheap enough.
Fine then.
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 3 lines
tools/libxl/libxl.c +3
-0+return ERROR_FAIL ; + } +libxl_cputopology_list_free (topology, nr_cpus);
Quoted 9 lines
Quoted 3 lines
Quoted 2 lines
Why are you retrieving this only to immediately throw it away?
Because I need
nr_cpus. :-)Surely this is not the recommended way to get
nr_cpus!
libxl_get_cpu_topology()itself callslibxl_get_max_cpus()which seems like the obvious candidate.
Well, it does indeed, but then it (most likely) returns something different from what libxl_get_max_cpus() says.
I fact, what it does is use the result of such call to size the arrays needed for calling xc_topologyinfo. Then, it takes what the call to xc_topologyinfo() returns in tinfo.max_cpu_index and returns that (increased by one, as that's the index rather than the number) to the caller.
I think the difference is libxl_get_max_cpus() returns the maximum possible number of supported cpus, while libxl_get_cputopology() --thanks to the fact that it goes through xc_topologyinfo(), not (only) xc_get_max_cpus(), like libxl_get_max_cpus() does-- returns the actual number of cpus.
What I need is the latter, and I'm looking again, but I'm again not finding anything easier (and, I agree, less ugly) than this to get it. I can go through libxl_get_physinfo(), rather than through _topologyinfo(), but the result is not going to be that different.
I'll keep looking but, in case I really don't fine anything, do you want me to:
- stick with this, at least for now;
- introduce a new libxl (and probably libxc too) interface for this
?
And I'm asking with this patch series in mind... I mean, I of course can add to my TODO list to do the latter, but do you think it's a prerequisite for accepting this patch?
Just let me know.
Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 33 lines · Dario Faggioli
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 3 lines
tools/libxl/libxl.c +3
-0+return ERROR_FAIL ; + } +libxl_cputopology_list_free (topology, nr_cpus);Quoted 9 lines
Quoted 3 lines
Quoted 2 lines
Why are you retrieving this only to immediately throw it away?
Because I need
nr_cpus. :-)Surely this is not the recommended way to get
nr_cpus!
libxl_get_cpu_topology()itself callslibxl_get_max_cpus()which seems like the obvious candidate.Well, it does indeed, but then it (most likely) returns something different from what
libxl_get_max_cpus()says.I fact, what it does is use the result of such call to size the arrays needed for calling
xc_topologyinfo. Then, it takes what the call toxc_topologyinfo()returns in tinfo.max_cpu_index and returns that (increased by one, as that's the index rather than the number) to the caller.I think the difference is
libxl_get_max_cpus()returns the maximum possible number of supported cpus, whilelibxl_get_cputopology()--thanks to the fact that it goes throughxc_topologyinfo(), not (only)xc_get_max_cpus(), likelibxl_get_max_cpus()does-- returns the actual number of cpus.What I need is the latter, and I'm looking again, but I'm again not finding anything easier (and, I agree, less ugly) than this to get it. I can go through
libxl_get_physinfo(), rather than through_topologyinfo(), but the result is not going to be that different.
Quoted 4 lines
I'll keep looking but, in case I really don't fine anything, do you want me to:
- stick with this, at least for now;
- introduce a new libxl (and probably libxc too) interface for this
I don't understand why libxl_get_max_cpus, which is certainly at least as big as you need, isn't sufficient here. Especially since in the same function you call libxl_cpu_bitmap_alloc(...,..., 0) which uses libxl_get_max_cpus.
You then use this with "libxl_bitmap_equal(cpumap, &ecpumap, nr_cpus)" where surely the sizes of cpumap and ecpumap could be used and/or are what actually matter? (and shouldn't you be checking that the sizes meet some constraint relative to each other?)
Quoted 11 lines
And I'm asking with this patch series in mind... I mean, I of course can add to my TODO list to do the latter, but do you think it's a prerequisite for accepting this patch?
Just let me know.
Regards,
Dario
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 11 lines · Ian Campbell
Quoted 4 lines · Dario Faggioli
I'll keep looking but, in case I really don't fine anything, do you want me to:
- stick with this, at least for now;
- introduce a new libxl (and probably libxc too) interface for thisI don't understand why
libxl_get_max_cpus, which is certainly at least as big as you need, isn't sufficient here. Especially since in the same function you calllibxl_cpu_bitmap_alloc(...,..., 0)which useslibxl_get_max_cpus.
As a matter of fact, it's _too_ big!
The point here is that, whenever the caller gives me a cpumap that comes from him specifying "all" in the config file, this cpumap is, for instance, on my system, and unsigned int full of 1-s. If you manage to (pretty) print it, that would look like "0-63".
After going down to Xen and then back from there, i.e., what happens to ecpumap, the "all" from above has become, again on my system, where I have 16 cpus, something like "0-15". That is, looking at the bits in the actual uint, the first 16 of them to 1, the other to 0.
Well, what I want is to be able to _not_ warn the user in this case, since he asked for all the cpus, and that's what he's getting, but for doing that I need to be able to restrict the comparison that is happening in libxl_bitmap_equal() to *only* the actual number of cpus, not the theoretically supported one.
Quoted 5 lines
You then use this with "
libxl_bitmap_equal(cpumap, &ecpumap, nr_cpus)" where surely the sizes of cpumap and ecpumap could be used and/or are what actually matter? (and shouldn't you be checking that the sizes meet some constraint relative to each other?)
Fair enough. It's very unlikely, but yes, since the interface allows to define bitmaps of different sizes, I should probably check that. Good point actually, but unrelated to and unhelpful to solve my issue.
Thanks and Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 19 lines · Dario Faggioli
Quoted 11 lines · Ian Campbell
Quoted 4 lines · Dario Faggioli
I'll keep looking but, in case I really don't fine anything, do you want me to:
- stick with this, at least for now;
- introduce a new libxl (and probably libxc too) interface for thisI don't understand why
libxl_get_max_cpus, which is certainly at least as big as you need, isn't sufficient here. Especially since in the same function you calllibxl_cpu_bitmap_alloc(...,..., 0)which useslibxl_get_max_cpus.As a matter of fact, it's _too_ big!
The point here is that, whenever the caller gives me a cpumap that comes from him specifying "all" in the config file, this cpumap is, for instance, on my system, and unsigned int full of 1-s. If you manage to (pretty) print it, that would look like "0-63".
Quoted 4 lines
After going down to Xen and then back from there, i.e., what happens to ecpumap, the "all" from above has become, again on my system, where I have 16 cpus, something like "0-15". That is, looking at the bits in the actual uint, the first 16 of them to 1, the other to 0.
And the returned bitmap doesn't have a size == 16? That's not very helpful I suppose.
It seems like it should be quite quick to wire up xc_get_nr_cpus based on xc_get_max_cpus and use that.
Is there not a race condition here somewhere -- what happens if a CPU is on/offlined during all this?
Ian.
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 10 lines · Ian Campbell
Quoted 4 lines · Dario Faggioli
After going down to Xen and then back from there, i.e., what happens to ecpumap, the "all" from above has become, again on my system, where I have 16 cpus, something like "0-15". That is, looking at the bits in the actual uint, the first 16 of them to 1, the other to 0.
And the returned bitmap doesn't have a size == 16? That's not very helpful I suppose.
Where? I mean what size are you talking about? In libxl, it is libxl itself that allocates the bitmap and decides, at allocation time (with the third parameter of libxl_cpu_bitmap_alloc()) how many bits I want there, and nothing changes that. So, after having allocated a cpumap 64 bits big, there is no way it can tell that only 16 are worth.
I can allocate the cpumap more precisely but, for one, that would still require figuring out the actual number of pcpus. Also, that would work for 16, but for any other value that is not multiple of sizeof(uint8_t), I'd have to face the same problem.
Quoted 3 lines
It seems like it should be quite quick to wire up
xc_get_nr_cpusbased onxc_get_max_cpusand use that.
No it's not. On it.
Quoted 3 lines
Is there not a race condition here somewhere -- what happens if a CPU is on/offlined during all this?
Again, I'm not getting. What's the window where you're worried about races, if on/offlining is involved? What do you refer to with "during all this" ?
Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 17 lines · Dario Faggioli
Quoted 10 lines · Ian Campbell
Quoted 4 lines · Dario Faggioli
After going down to Xen and then back from there, i.e., what happens to ecpumap, the "all" from above has become, again on my system, where I have 16 cpus, something like "0-15". That is, looking at the bits in the actual uint, the first 16 of them to 1, the other to 0.
And the returned bitmap doesn't have a size == 16? That's not very helpful I suppose.
Where? I mean what size are you talking about? In libxl, it is libxl itself that allocates the bitmap and decides, at allocation time (with the third parameter of
libxl_cpu_bitmap_alloc()) how many bits I want there, and nothing changes that. So, after having allocated a cpumap 64 bits big, there is no way it can tell that only 16 are worth.
Quoted 4 lines
I can allocate the cpumap more precisely but, for one, that would still require figuring out the actual number of pcpus. Also, that would work for 16, but for any other value that is not multiple of
sizeof(uint8_t), I'd have to face the same problem.
Oh, OK. I figured max_cpu would be stashed there somewhere.
Quoted 4 lines
Quoted 3 lines
It seems like it should be quite quick to wire up
xc_get_nr_cpusbased onxc_get_max_cpusand use that.No it's not. On it.
Great.
Quoted 6 lines
Quoted 3 lines
Is there not a race condition here somewhere -- what happens if a CPU is on/offlined during all this?
Again, I'm not getting. What's the window where you're worried about races, if on/offlining is involved? What do you refer to with "during all this" ?
Between getting the maximum cpu number and checking the results of a pin call. What happens if a CPU went away such that you think when checking that there is 16 cpus (based on old information) but when the pin hypercall was made there were only 15. Or conversely if a CPU was plugged in.
Also, does this check fail if the cpumask is sparse? Is that something which can happen e.g. unplugging CPU#8 in a 16 CPU system?
Ian.
Re: [PATCH v3 11/14] libxl: get and set soft affinity
Quoted 11 lines · Ian Campbell
Quoted 3 lines · Dario Faggioli
Again, I'm not getting. What's the window where you're worried about races, if on/offlining is involved? What do you refer to with "during all this" ?
Between getting the maximum cpu number and checking the results of a pin call. What happens if a CPU went away such that you think when checking that there is 16 cpus (based on old information) but when the pin hypercall was made there were only 15. Or conversely if a CPU was plugged in.
Well, for the sake of this patch, all that we risk is printing a spurious warning or missing one.
Anyway, I see what you mean now, and I guess I can try to mitigate it, by moving the check for the number of cpus after the affinity setting call. That would at least make it more likely for the information about the number of cpus to be consistent with the result of the call, but won't eliminate the possibility of races.
In fact, I don't think I can't avoid that with 100% probability, as there is no way to get both the result of the affinity setting call and the number of cpus in an atomic way, and I don't think it's worth introducing one for the sake of this...
Quoted 3 lines
Also, does this check fail if the cpumask is sparse? Is that something which can happen e.g. unplugging CPU#8 in a 16 CPU system?
Well, in that case I guess it'd be fine to print the warning. I mean, if the user wanted affinity to cpu#8 and that went away, it's a good to tell him he's not getting (exactly) what he asked, isn't it?
Regards,
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
PATCH v3 12/14 xl: enable getting and setting soft
In reply to Dario FaggioliGetting happens via `xl vcpu-list', which now looks like this:
# xl vcpu-list -s Name ID VCPU CPU State Time(s) Hard Affinity / Soft Affinity Domain-0 0 0 11 -b- 5.4 8-15 / all Domain-0 0 1 11 -b- 1.0 8-15 / all Domain-0 0 14 13 -b- 1.4 8-15 / all Domain-0 0 15 8 -b- 1.6 8-15 / all vm-test 3 0 4 -b- 2.5 0-12 / 0-7 vm-test 3 1 0 -b- 3.2 0-12 / 0-7
Setting happens by adding a '-s'/'--soft' switch to `xl vcpu-pin'.
xl manual page is updated accordingly.
---
Changes from v2:
* this patch folds what in v2 were patches 13 and 14;
* `xl vcpu-pin' always shows both had and soft affinity, without the need of passing '-s'.
--- docs/man/xl.pod.1 | 24 +++++++++++++++++++- tools/libxl/xl_cmdimpl.c | 54 +++++++++++++++++++++++---------------------- tools/libxl/xl_cmdtable.c | 3 ++- 3 files changed, 53 insertions(+), 28 deletions(-)
docs/man/xl.pod.1 +23 -1
@@ -619,7 +619,7 @@ after B<vcpu-set>, go to B<SEE ALSO> section for information. Lists VCPU information for a specific domain. If no domain is specified, VCPU information for all domains will be provided. -=item B<vcpu-pin> I<domain-id> I<vcpu> I<cpus> +=item B<vcpu-pin> [I<OPTIONS>] I<domain-id> I<vcpu> I<cpus> Pins the VCPU to only run on the specific CPUs. The keyword B<all> can be used to apply the I<cpus> list to all VCPUs in the
@@ -630,6 +630,28 @@ different run state is appropriate. Pinning can be used to restrict this, by ensuring certain VCPUs can only run on certain physical CPUs. +B<OPTIONS> + +=over 4 + +=item B<-s>, B<--soft> + +The same as above, but affect I<soft affinity> rather than pinning +(also called I<hard affinity>). + +Normally, VCPUs just wander among the CPUs where it is allowed to +run (either all the CPUs or the ones to which it is pinned, as said +for B<vcpu-list>). Soft affinity offer a mean to specify one or more +I<preferred> CPUs. Basically, among the ones where it can run, the +VCPU the VCPU will greately prefer to execute on one of these CPUs, +whenever that is possible. + +Notice that, in order for soft affinity to actually work, it needs +special support in the scheduler. Right now, only credit1 provides +that. + +=back + =item B<vm-list> Prints information about guests. This list excludes information about
tools/libxl/xl_cmdimpl.c +28 -26
99 lines not on this page · raw message
tools/libxl/xl_cmdtable.c +2 -1
@@ -213,7 +213,8 @@ struct cmd_spec cmd_table[] = { {"vcpu-pin" , &main_vcpupin,1 ,1 ,"Set which CPUs a VCPU can use" , -"<Domain> <VCPU|all> <CPUs|all>" , +"[option] <Domain> <VCPU|all> <CPUs|all>" , +"-s, --soft Deal with soft affinity" , }, { "vcpu-set", &main_vcpuset, 0, 1,
Re: [PATCH v3 12/14] xl: enable getting and setting soft
Quoted 5 lines · Dario Faggioli
Getting happens via `xl vcpu-list', which now looks like this:
# xl vcpu-list -s Name ID VCPU CPU State Time(s) Hard Affinity / Soft Affinity Domain-0 0 0 11 -b- 5.4 8-15 / all
Since the / is never likely to align, how about "CPU Affinity (Hard/Soft)" as the title line?
Quoted 41 lines
Domain-0 0 1 11 -b- 1.0 8-15 / all Domain-0 0 14 13 -b- 1.4 8-15 / all Domain-0 0 15 8 -b- 1.6 8-15 / all vm-test 3 0 4 -b- 2.5 0-12 / 0-7 vm-test 3 1 0 -b- 3.2 0-12 / 0-7Setting happens by adding a '-s'/'--soft' switch to `xl vcpu-pin'.
xl manual page is updated accordingly.
Signed-off-by Dario Faggioli <[email protected]>---
Changes from v2:
* this patch folds what in v2 were patches 13 and 14;
* `xl vcpu-pin' always shows both had and soft affinity, without the need of passing '-s'.--- docs/man/xl.pod.1 | 24 +++++++++++++++++++- tools/libxl/xl_cmdimpl.c | 54 +++++++++++++++++++++++---------------------- tools/libxl/xl_cmdtable.c | 3 ++- 3 files changed, 53 insertions(+), 28 deletions(-)docs/man/xl.pod.1 +3
-1@@ -619,7 +619,7 @@ after B<vcpu-set>, go to B<SEE ALSO> section for information. Lists VCPU information for a specific domain. If no domain is specified, VCPU information for all domains will be provided. -=item B<vcpu-pin> I<domain-id> I<vcpu> I<cpus> +=item B<vcpu-pin> [I<OPTIONS>] I<domain-id> I<vcpu> I<cpus> Pins the VCPU to only run on the specific CPUs. The keyword B<all> can be used to apply the I<cpus> list to all VCPUs in the@@ -630,6 +630,28 @@ different run state is appropriate. Pinning can be used to restrict this, by ensuring certain VCPUs can only run on certain physical CPUs. +B<OPTIONS> +
docs/man/xl.pod.1 different run state is appropriate. Pinning can be used to restrict · line 644
Quoted 10 lines
docs/man/xl.pod.1 +10
-0+=over 4 + +=item B<-s>, B<--soft> + +The same as above, but affect I<soft affinity> rather than pinning +(also called I<hard affinity>). + +Normally, VCPUs just wander among the CPUs where it is allowed to +run (either all the CPUs or the ones to which it is pinned, as said +for B<vcpu-list>). Soft affinity offer a mean to specify one or more
I think "offers a means" is correct. Or perhaps "affinities offer a means".
docs/man/xl.pod.1 different run state is appropriate. Pinning can be used to restrict · line 646
Quoted 2 lines
docs/man/xl.pod.1 +2
-0+I<preferred> CPUs. Basically, among the ones where it can run, the +VCPU the VCPU will greately prefer to execute on one of these CPUs,
"greatly"
tools/libxl/xl_cmdtable.c struct cmd_spec cmd_table[] = { · line 217
Quoted 11 lines
tools/libxl/xl_cmdtable.c +2
-1@@ -213,7 +213,8 @@ struct cmd_spec cmd_table[] = { {"vcpu-pin" , &main_vcpupin,1 ,1 ,"Set which CPUs a VCPU can use" , - "<Domain> <VCPU|all> <CPUs|all>", +"[option] <Domain> <VCPU|all> <CPUs|all>" , + "-s, --soft Deal with soft affinity",
"Set soft affinity" ?
Quoted 4 lines
tools/libxl/xl_cmdtable.c +0
-0}, {"vcpu-set" , &main_vcpuset, 0, 1,
Re: [PATCH v3 12/14] xl: enable getting and setting soft
Quoted 10 lines · Ian Campbell
Quoted 5 lines · Dario Faggioli
Getting happens via `xl vcpu-list', which now looks like this:
# xl vcpu-list -s Name ID VCPU CPU State Time(s) Hard Affinity / Soft Affinity Domain-0 0 0 11 -b- 5.4 8-15 / allSince the / is never likely to align, how about "CPU Affinity (Hard/Soft)" as the title line?
Ok (to this and to all you say below).
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
PATCH v3 13/14 xl: enable for specifying node-affinity in the config file
In reply to Dario Faggioliin a similar way to how it is possible to specify vcpu-affinity.
---
Changes from v2:
* use the new libxl API. Although the implementation changed only a little bit, I removed IanJ's Acked-by, although I am here saying that he did provided it, as requested.
--- docs/man/xl.cfg.pod.5 | 27 ++++++++++++++-- tools/libxl/libxl_dom.c | 3 +- tools/libxl/xl_cmdimpl.c | 79 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 103 insertions(+), 6 deletions(-)
docs/man/xl.cfg.pod.5 +24 -3
@@ -144,19 +144,40 @@ run on cpu #3 of the host. =back If this option is not specified, no vcpu to cpu pinning is established, -and the vcpus of the guest can run on all the cpus of the host. +and the vcpus of the guest can run on all the cpus of the host. If this +option is specified, the intersection of the vcpu pinning mask, provided +here, and the soft affinity mask, provided via B<cpus\_soft=> (if any), +is utilized to compute the domain node-affinity, for driving memory +allocations. If we are on a NUMA machine (i.e., if the host has more than one NUMA node) and this option is not specified, libxl automatically tries to place the guest on the least possible number of nodes. That, however, will not affect vcpu pinning, so the guest will still be able to run on -all the cpus, it will just prefer the ones from the node it has been -placed on. A heuristic approach is used for choosing the best node (or +all the cpus. A heuristic approach is used for choosing the best node (or set of nodes), with the goals of maximizing performance for the guest and, at the same time, achieving efficient utilization of host cpus and memory. See F<docs/misc/xl-numa-placement.markdown> for more details. +=item B<cpus_soft="CPU-LIST"> + +Exactly as B<cpus=>, but specifies soft affinity, rather than pinning +(also called hard affinity). Starting from Xen 4.4, and if the credit +scheduler is used, this means the vcpus of the domain prefers to run +these pcpus. Default is either all pcpus or xl (via libxl) guesses +(depending on what other options are present). + +A C<CPU-LIST> is specified exactly as above, for B<cpus=>. + +If this option is not specified, the vcpus of the guest will not have +any preference regarding on what cpu to run, and the scheduler will +treat all the cpus where a vcpu can execute (if B<cpus=> is specified), +or all the host cpus (if not), the same. If this option is specified, +the intersection of the soft affinity mask, provided here, and the vcpu +pinning, provided via B<cpus=> (if any), is utilized to compute the +domain node-affinity, for driving memory allocations. + =back =head3 CPU Scheduling
tools/libxl/libxl_dom.c +2 -1
@@ -236,7 +236,8 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,return rc; }libxl_domain_set_nodeaffinity (ctx, domid, &info->nodemap); -libxl_set_vcpuaffinity_all (ctx, domid, info->max_vcpus, &info->cpumap); +libxl_set_vcpuaffinity_all3 (ctx, domid, info->max_vcpus, &info->cpumap, + &info->cpumap_soft);xc_domain_setmaxmem (ctx->xch, domid, info->target_memkb +LIBXL_MAXMEM_CONSTANT ); xs_domid =xs_read (ctx->xsh,XBT_NULL ,"/tool/xenstored/domid" ,NULL );
tools/libxl/xl_cmdimpl.c +77 -2
104 lines not on this page · raw message
Re: [PATCH v3 13/14] xl: enable for specifying node-affinity in the config file
Quoted 35 lines · Dario Faggioli
in a similar way to how it is possible to specify vcpu-affinity.
Signed-off-by Dario Faggioli <[email protected]>---
Changes from v2:
* use the new libxl API. Although the implementation changed only a little bit, I removed IanJ's Acked-by, although I am here saying that he did provided it, as requested.--- docs/man/xl.cfg.pod.5 | 27 ++++++++++++++-- tools/libxl/libxl_dom.c | 3 +- tools/libxl/xl_cmdimpl.c | 79 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 103 insertions(+), 6 deletions(-)docs/man/xl.cfg.pod.5 +5
-3@@ -144,19 +144,40 @@ run on cpu #3 of the host. =back If this option is not specified, no vcpu to cpu pinning is established, -and the vcpus of the guest can run on all the cpus of the host. +and the vcpus of the guest can run on all the cpus of the host. If this +option is specified, the intersection of the vcpu pinning mask, provided +here, and the soft affinity mask, provided via B<cpus\_soft=> (if any), +is utilized to compute the domain node-affinity, for driving memory +allocations. If we are on a NUMA machine (i.e., if the host has more than one NUMA node) and this option is not specified, libxl automatically tries to place the guest on the least possible number of nodes. That, however, will not affect vcpu pinning, so the guest will still be able to run on -all the cpus, it will just prefer the ones from the node it has been -placed on. A heuristic approach is used for choosing the best node (or
docs/man/xl.cfg.pod.5 run on cpu #3 of the host. · line 166
Quoted 10 lines
docs/man/xl.cfg.pod.5 +5
-0+all the cpus. A heuristic approach is used for choosing the best node (or set of nodes), with the goals of maximizing performance for the guest and, at the same time, achieving efficient utilization of host cpus and memory. See F<docs/misc/xl-numa-placement.markdown> for more details. +=item B<cpus_soft="CPU-LIST"> + +Exactly as B<cpus=>, but specifies soft affinity, rather than pinning +(also called hard affinity). Starting from Xen 4.4, and if the credit
I don't think we need to reference particular versions in what is effectively the manpage which comes with that version.
docs/man/xl.cfg.pod.5 run on cpu #3 of the host. · line 169
Quoted 3 lines
docs/man/xl.cfg.pod.5 +3
-0+scheduler is used, this means the vcpus of the domain prefers to run +these pcpus. Default is either all pcpus or xl (via libxl) guesses +(depending on what other options are present).
No need to mention libxl here. TBH I would either document what the other options which affect the guess are or not mention it at all, as it stands the sentence doesn't tell me anything very useful.
Quoted 54 lines
docs/man/xl.cfg.pod.5 +11
-0+ +A C<CPU-LIST> is specified exactly as above, for B<cpus=>. + +If this option is not specified, the vcpus of the guest will not have +any preference regarding on what cpu to run, and the scheduler will +treat all the cpus where a vcpu can execute (if B<cpus=> is specified), +or all the host cpus (if not), the same. If this option is specified, +the intersection of the soft affinity mask, provided here, and the vcpu +pinning, provided via B<cpus=> (if any), is utilized to compute the +domain node-affinity, for driving memory allocations. + =back =head3 CPU Schedulingtools/libxl/libxl_dom.c +2
-1@@ -236,7 +236,8 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,return rc; }libxl_domain_set_nodeaffinity (ctx, domid, &info->nodemap); -libxl_set_vcpuaffinity_all (ctx, domid, info->max_vcpus, &info->cpumap); +libxl_set_vcpuaffinity_all3 (ctx, domid, info->max_vcpus, &info->cpumap, + &info->cpumap_soft);xc_domain_setmaxmem (ctx->xch, domid, info->target_memkb +LIBXL_MAXMEM_CONSTANT ); xs_domid =xs_read (ctx->xsh,XBT_NULL ,"/tool/xenstored/domid" ,NULL );tools/libxl/xl_cmdimpl.c +4
-2@@ -76,8 +76,9 @@ xlchild children[child_max];static const char *common_domname;static int fd_lock =-1 ; -/* Stash for specific vcpu to pcpu mappping */ +/* Stash for specific vcpu to pcpu hard and soft mappping */ static int *vcpu_to_pcpu; +static int *vcpu_to_pcpu_soft;static const char savefileheader_magic[32 ]="Xen saved domain, xl format\n \0 \r" ;@@ -647,7 +648,8 @@ static void parse_config_data(const char *config_source,const char *buf;long l;XLU_Config *config; -XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms; +XLU_ConfigList *cpus, *cpus_soft, *vbds, *nics, *pcis; +XLU_ConfigList *cvfbs, *cpuids, *vtpms;XLU_ConfigList *ioports, *irqs, *iomem;int num_ioports, num_irqs, num_iomem;int pci_power_mgmt =0 ;
tools/libxl/xl_cmdimpl.c static void parse_config_data(const char *config_source, · line 829
Quoted 4 lines
tools/libxl/xl_cmdimpl.c +1
-0@@ -824,6 +826,50 @@ static void parse_config_data(const char *config_source,libxl_defbool_set (&b_info->numa_placement, false); } +if (!xlu_cfg_get_list (config,"cpus_soft" , &cpus_soft,0 ,1 )) {
How much of this block duplicates the parsing of the pinning field? Can it be refactored?
tools/libxl/xl_cmdimpl.c static void parse_config_data(const char *config_source, · line 837
Quoted 8 lines
tools/libxl/xl_cmdimpl.c +8
-0+int n_cpus =0 ; + +if (libxl_node_bitmap_alloc (ctx, &b_info->cpumap_soft,0 )) { +fprintf (stderr,"Unable to allocate cpumap_soft\n" ); +exit (1 ); + } + +/* As above, use a temporary storage for the single affinities */
"use temporary storage..." (the "a" is redundant/sounds wierd)
Quoted 39 lines
tools/libxl/xl_cmdimpl.c +35
-0+ vcpu_to_pcpu_soft =xmalloc (sizeof (int ) * b_info->max_vcpus); +memset (vcpu_to_pcpu_soft,-1 ,sizeof (int ) * b_info->max_vcpus); + +libxl_bitmap_set_none (&b_info->cpumap_soft); +while ((buf =xlu_cfg_get_listitem (cpus_soft, n_cpus)) !=NULL ) { + i =atoi (buf); +if (!libxl_bitmap_cpu_valid (&b_info->cpumap_soft, i)) { +fprintf (stderr,"cpu %d illegal\n" , i); +exit (1 ); + } +libxl_bitmap_set (&b_info->cpumap_soft, i); +if (n_cpus < b_info->max_vcpus) + vcpu_to_pcpu_soft[n_cpus] = i; + n_cpus++; + } + +/* We have a soft affinity map, disable automatic placement */ +libxl_defbool_set (&b_info->numa_placement, false); + } +else if (!xlu_cfg_get_string (config,"cpus_soft" , &buf,0 )) { +char *buf2 =strdup (buf); + +if (libxl_node_bitmap_alloc (ctx, &b_info->cpumap_soft,0 )) { +fprintf (stderr,"Unable to allocate cpumap_soft\n" ); +exit (1 ); + } + +libxl_bitmap_set_none (&b_info->cpumap_soft); +if (vcpupin_parse (buf2, &b_info->cpumap_soft)) +exit (1 ); +free (buf2); + +libxl_defbool_set (&b_info->numa_placement, false); + } +if (!xlu_cfg_get_long (config,"memory" , &l,0 )) { b_info->max_memkb = l *1024 ; b_info->target_memkb = b_info->max_memkb;
tools/libxl/xl_cmdimpl.c start: · line 2232
Quoted 4 lines
tools/libxl/xl_cmdimpl.c +1
-0@@ -2183,6 +2229,35 @@ start:free (vcpu_to_pcpu); vcpu_to_pcpu =NULL ; } +/* And do the same for single vcpu to soft-affinity mapping */
Another option to refactor common code then?
PATCH v3 14/14 libxl: automatic NUMA placement affects soft affinity
In reply to Dario FaggiolivCPU soft affinity and NUMA-aware scheduling does not have to be related. However, soft affinity is how NUMA-aware scheduling is actually implemented, and therefore, by default, the results of automatic NUMA placement (at VM creation time) are also used to set the soft affinity of all the vCPUs of the domain.
Of course, this only happens if automatic NUMA placement is enabled and actually takes place (for instance, if the user does not specify any hard and soft affiniy in the xl config file).
This also takes care of the vice-versa, i.e., don't trigger automatic placement if the config file specifies either an hard (the check for which was already there) or a soft (the check for which is introduced by this commit) affinity.
--- docs/man/xl.cfg.pod.5 | 21 +++++++++++---------- docs/misc/xl-numa-placement.markdown | 16 ++++++++++++++-- tools/libxl/libxl_dom.c | 20 ++++++++++++++++++-- 3 files changed, 43 insertions(+), 14 deletions(-)
docs/man/xl.cfg.pod.5 +11 -10
@@ -150,16 +150,6 @@ here, and the soft affinity mask, provided via B<cpus\_soft=> (if any), is utilized to compute the domain node-affinity, for driving memory allocations. -If we are on a NUMA machine (i.e., if the host has more than one NUMA -node) and this option is not specified, libxl automatically tries to -place the guest on the least possible number of nodes. That, however, -will not affect vcpu pinning, so the guest will still be able to run on -all the cpus. A heuristic approach is used for choosing the best node (or -set of nodes), with the goals of maximizing performance for the guest -and, at the same time, achieving efficient utilization of host cpus -and memory. See F<docs/misc/xl-numa-placement.markdown> for more -details. - =item B<cpus_soft="CPU-LIST"> Exactly as B<cpus=>, but specifies soft affinity, rather than pinning
@@ -178,6 +168,17 @@ the intersection of the soft affinity mask, provided here, and the vcpu pinning, provided via B<cpus=> (if any), is utilized to compute the domain node-affinity, for driving memory allocations. +If this option is not specified (and B<cpus=> is not specified either), +libxl automatically tries to place the guest on the least possible +number of nodes. A heuristic approach is used for choosing the best +node (or set of nodes), with the goal of maximizing performance for +the guest and, at the same time, achieving efficient utilization of +host cpus and memory. In that case, the soft affinity of all the vcpus +of the domain will be set to the pcpus belonging to the NUMA nodes +chosen during placement. + +For more details, see F<docs/misc/xl-numa-placement.markdown>. + =back =head3 CPU Scheduling
docs/misc/xl-numa-placement.markdown +14 -2
@@ -126,10 +126,22 @@ or Xen won't be able to guarantee the locality for their memory accesses. That, of course, also mean the vCPUs of the domain will only be able to execute on those same pCPUs. +Starting from 4.4, is is also possible to specify a "cpus\_soft=" option +in the xl config file. This, independently from whether or not "cpus=" is +specified too, affect the NUMA placement in a way very similar to what +is described above. In fact, the hypervisor will build up the node-affinity +of the VM basing right on it or, if both pinning (via "cpus=") and soft +affinity (via "cpus\_soft=") are present, basing on their intersection. + +Besides that, "cpus\_soft=" also means, of course, that the vCPUs of the +domain will prefer to execute on, among the pCPUs where they can run, +those particular pCPUs. + + ### Placing the guest automatically ### -If no "cpus=" option is specified in the config file, libxl tries -to figure out on its own on which node(s) the domain could fit best. +If neither "cpus=" nor "cpus\_soft=" are present in the config file, libxl +tries to figure out on its own on which node(s) the domain could fit best. If it finds one (some), the domain's node affinity get set to there, and both memory allocations and NUMA aware scheduling (for the credit scheduler and starting from Xen 4.3) will comply with it. Starting from
tools/libxl/libxl_dom.c +18 -2
@@ -222,18 +222,34 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,* some weird error manifests) the subsequent call to * libxl_domain_set_nodeaffinity() will do the actual placement, * whatever that turns out to be. +* +* As far as scheduling is concerned, we achieve NUMA-aware scheduling +* by having the results of placement affect the soft affinity of all +* the vcpus of the domain. Of course, we want that iff placement is +* enabled and actually happens, so we only change info->cpumap_soft to +* reflect the placement result if that is the case */ if (libxl_defbool_val (info->numa_placement)) { -if (!libxl_bitmap_is_full (&info->cpumap)) { +/* We require both hard and soft affinity not to be set */ +if (!libxl_bitmap_is_full (&info->cpumap) || + !libxl_bitmap_is_full (&info->cpumap_soft)) {LOG (ERROR ,"Can run NUMA placement only if no vcpu " -"affinity is specified" ); +"(hard or soft) affinity is specified" );return ERROR_INVAL ; } rc =numa_place_domain (gc, domid, info);if (rc)return rc; + +/* +* We change the soft affinity in domain_build_info here, of course +* after converting the result of placement from nodes to cpus. the +* following call to libxl_set_vcpuaffinity_all_soft() will do the +* actual updating of the domain's vcpus' soft affinity. +*/ +libxl_nodemap_to_cpumap (ctx, &info->nodemap, &info->cpumap_soft); }libxl_domain_set_nodeaffinity (ctx, domid, &info->nodemap); libxl_set_vcpuaffinity_all3(ctx, domid, info->max_vcpus, &info->cpumap,
Re: [PATCH v3 14/14] libxl: automatic NUMA placement affects soft affinity
docs/misc/xl-numa-placement.markdown or Xen won't be able to guarantee the locality for their memory accesses. · line 129
Quoted 9 lines · Dario Faggioli
docs/misc/xl-numa-placement.markdown +1
-0@@ -126,10 +126,22 @@ or Xen won't be able to guarantee the locality for their memory accesses. That, of course, also mean the vCPUs of the domain will only be able to execute on those same pCPUs. +Starting from 4.4, is is also possible to specify a "cpus\_soft=" option
s/Starting from 4.4, /It/
docs/misc/xl-numa-placement.markdown or Xen won't be able to guarantee the locality for their memory accesses. · line 131
Quoted 2 lines
docs/misc/xl-numa-placement.markdown +2
-0+in the xl config file. This, independently from whether or not "cpus=" is +specified too, affect the NUMA placement in a way very similar to what
"affects".
docs/misc/xl-numa-placement.markdown or Xen won't be able to guarantee the locality for their memory accesses. · line 133
Quoted 2 lines
docs/misc/xl-numa-placement.markdown +2
-0+is described above. In fact, the hypervisor will build up the node-affinity +of the VM basing right on it or, if both pinning (via "cpus=") and soft
"basing right on it" -- what does that mean?
docs/misc/xl-numa-placement.markdown or Xen won't be able to guarantee the locality for their memory accesses. · line 134
Quoted 1 line
docs/misc/xl-numa-placement.markdown +1
-0+affinity (via "cpus\_soft=") are present, basing on their intersection.
"based on"
docs/misc/xl-numa-placement.markdown or Xen won't be able to guarantee the locality for their memory accesses. · line 136
Quoted 2 lines
docs/misc/xl-numa-placement.markdown +2
-0+ +Besides that, "cpus\_soft=" also means, of course, that the vCPUs of the
s/Besides that, //
s/, of course, //
You aren't being graded against a target word limit you know ;-)
docs/misc/xl-numa-placement.markdown or Xen won't be able to guarantee the locality for their memory accesses. · line 138
Quoted 2 lines
docs/misc/xl-numa-placement.markdown +2
-0+domain will prefer to execute on, among the pCPUs where they can run, +those particular pCPUs.
Isn't "among the pCPUs where they can run" here somewhat redundant too?
Ian.
Re: [PATCH v3 14/14] libxl: automatic NUMA placement affects soft affinity
Quoted 10 lines · Ian Campbell
docs/misc/xl-numa-placement.markdown or Xen won't be able to guarantee the locality for their memory accesses. · line 136
Quoted 2 lines · Dario Faggioli
docs/misc/xl-numa-placement.markdown +2
-0+ +Besides that, "cpus\_soft=" also means, of course, that the vCPUs of thes/Besides that, //
s/, of course, //You aren't being graded against a target word limit you know ;-)
Or so you assume... Are you sure? Have you read my contract? :-P :-P
Anyway, thanks, will fix everything as you suggest.
Dario
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Quoted 2 lines · Dario Faggioli
Implement vcpu soft affinity for credit1
Well, of course this ("Implement vcpu soft affinity for credit1") was the real subject, which I put one line below where I should have, when editing the cover letter. :-/
Sorry for that.
Signature · 4 lines
<<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://about.me/dario.faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Quoted 25 lines · Dario Faggioli
Implement vcpu soft affinity for credit1
Hello everyone,
Take 3 for his series.
Very briefly, what it does is allowing each vcpu to have:
- an hard affinity, which they already do, and we usually call pinning. Thisis the list of pcpus where a vcpu is allowed to run;- a soft affinity, which this series introduces. This is the list of pcpus where a vcpu *prefers* to run.
Once that is done, per-vcpu NUMA-aware scheduling is easily implemented on top of that, just by instructing libxl to issue the proper call to setup the soft affinity of the domain's vcpus to be equal to its node-affinity.
Wrt v2 review[*] I have addressed all the comments (see individual changelogs). In particular, I have completely redesigned the libxl interface. It now allows both the following usage patterns:
1. changing either soft affinity only or hard affinity only or both of them to the same value, and getting DEBUG or WARN output if that results in an inconsistent state;
2. changing both hard and soft affinity, each one to its own value, and getting DEBUG or WARN output only if the *final* state is inconsistent.
Quoted 6 lines
The series is also available here:
git://xenbits.xen.org/people/dariof/xen.gitnuma/per-vcpu-affinity-v3Thanks and Regards,
Dario
Release-wise, I think this is probably not a blocker, but it is a very cool feature. From a scheduler standpoint, it should be fairly low risk -- it is primarily simplifying a mechanism that was introduced in 4.3. Bugs in the library code should be fairly easy to catch, and fairly low impact if they are found.
The primary thing to be concerned about is the interface; whether we have had enough time to consider the new interfaces before committing to support them. But they're fairly straightforward.
Since we're only a day past the freezing point, and (I think) almost ready to be checked in, I'm inclined to give this a freeze exception.
Any other thoughts?
-George
Quoted 7 lines
Quoted 1 line
Quoted 1 line · George Dunlap
Release-wise, I think this is probably not a blocker, but it is a very cool feature. From a scheduler standpoint, it should be fairly low risk -- it is primarily simplifying a mechanism that was introduced in 4.3. Bugs in the library code should be fairly easy to catch, and fairly low impact if they are found.
Quoted 8 lines
The primary thing to be concerned about is the interface; whether we have had enough time to consider the new interfaces before committing to support them. But they're fairly straightforward.
Since we're only a day past the freezing point, and (I think) almost ready to be checked in, I'm inclined to give this a freeze exception.
Any other thoughts?
I agree (with the caveat that I haven't gone through patches 8 and 9 yet).
Jan