get rid of the SEDF
v4 cover get rid of the SEDF
This should be it.
Patch 1 is still, as in v3, the only one in need of attention.
Series available here too:
git://xenbits.xen.org/people/dariof/xen.git rel/sched/nosedf-v4
Thanks and Regards,
Dario
---
Dario Faggioli (7):
libxl: get rid of the SEDF scheduler
tools: python: get rid of the SEDF scheduler bindings
libxc: get rid of the SEDF scheduler
xen: get rid of the SEDF scheduler
xen: kill sched_sedf.c
xl: get rid of the SEDF scheduler
docs: get rid of the SEDF scheduler
docs/INDEX | 1 docs/man/xl.cfg.pod.5 | 24 docs/man/xl.pod.1 | 42 - docs/man/xlcpupool.cfg.pod.5 | 4 docs/misc/sedf_scheduler_mini-HOWTO.txt | 44 - docs/misc/xen-command-line.markdown | 2 tools/examples/cpupool | 2 tools/libxc/Makefile | 1 tools/libxc/include/xenctrl.h | 12 tools/libxc/xc_sedf.c | 78 -- tools/libxl/libxl.c | 73 - tools/libxl/libxl_create.c | 61 - tools/libxl/libxl_types.idl | 8 tools/libxl/xl.h | 1 tools/libxl/xl_cmdimpl.c | 139 --- tools/libxl/xl_cmdtable.c | 16 tools/python/xen/lowlevel/xc/xc.c | 70 - xen/common/Makefile | 1 xen/common/sched_sedf.c | 1557 ------------------------------- xen/common/schedule.c | 1 xen/include/public/domctl.h | 9 xen/include/public/trace.h | 2 xen/include/xen/sched-if.h | 1 23 files changed, 16 insertions(+), 2133 deletions(-) delete mode 100644 docs/misc/sedf_scheduler_mini-HOWTO.txt delete mode 100644 tools/libxc/xc_sedf.c delete mode 100644 xen/common/sched_sedf.c
--
<<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 v4 1/7 libxl: get rid of the SEDF scheduler
only the interface is left in place, for backward compile-time compatibility, but every attempt to use it would throw an error.
---
Cc: George Dunlap <[email protected]>
Cc: Ian Jackson <[email protected]>
Cc: Stefano Stabellini <[email protected]>
Cc: Ian Campbell <[email protected]>
Cc: Wei Liu <[email protected]>
Changes from v3:
- drop George's Rev-by: which should not be there since v2;
- better grouping of fields in libxl_domain_sched_params, as suggested during review;
- improved comment for ERROR_FEATURE_REMOVED, as suggested during review.
Changes from v2:
- introduce and use ERROR_FEATURE_REMOVED, as requested during review;
- mark the SEDF only parameter as deprecated in libxl_types.idl, as requested during review.
--- tools/libxl/libxl.c | 73 ++----------------------------------------- tools/libxl/libxl_create.c | 61 ------------------------------------ tools/libxl/libxl_types.idl | 8 ++++- 3 files changed, 11 insertions(+), 131 deletions(-)
tools/libxl/libxl.c +4 -69
@@ -5728,73 +5728,6 @@ static int sched_credit2_domain_set(libxl__gc *gc, uint32_t domid,return 0 ; } -static int sched_sedf_domain_get (libxl__gc *gc,uint32_t domid, -libxl_domain_sched_params *scinfo) -{ -uint64_t period; -uint64_t slice; -uint64_t latency; -uint16_t extratime; -uint16_t weight; -int rc; - - rc =xc_sedf_domain_get (CTX ->xch, domid, &period, &slice, &latency, - &extratime, &weight); -if (rc !=0 ) { -LOGE (ERROR ,"getting domain sched sedf" ); -return ERROR_FAIL ; - } - -libxl_domain_sched_params_init (scinfo); - scinfo->sched =LIBXL_SCHEDULER_SEDF ; - scinfo->period = period /1000000 ; - scinfo->slice = slice /1000000 ; - scinfo->latency = latency /1000000 ; - scinfo->extratime = extratime; - scinfo->weight = weight; - -return 0 ; -} - -static int sched_sedf_domain_set (libxl__gc *gc,uint32_t domid, -const libxl_domain_sched_params *scinfo) -{ -uint64_t period; -uint64_t slice; -uint64_t latency; -uint16_t extratime; -uint16_t weight; - -int ret; - - ret =xc_sedf_domain_get (CTX ->xch, domid, &period, &slice, &latency, - &extratime, &weight); -if (ret !=0 ) { -LOGE (ERROR ,"getting domain sched sedf" ); -return ERROR_FAIL ; - } - -if (scinfo->period !=LIBXL_DOMAIN_SCHED_PARAM_PERIOD_DEFAULT ) - period = (uint64_t )scinfo->period *1000000 ; -if (scinfo->slice !=LIBXL_DOMAIN_SCHED_PARAM_SLICE_DEFAULT ) - slice = (uint64_t )scinfo->slice *1000000 ; -if (scinfo->latency !=LIBXL_DOMAIN_SCHED_PARAM_LATENCY_DEFAULT ) - latency = (uint64_t )scinfo->latency *1000000 ; -if (scinfo->extratime !=LIBXL_DOMAIN_SCHED_PARAM_EXTRATIME_DEFAULT ) - extratime = scinfo->extratime; -if (scinfo->weight !=LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT ) - weight = scinfo->weight; - - ret =xc_sedf_domain_set (CTX ->xch, domid, period, slice, latency, - extratime, weight); -if ( ret <0 ) { -LOGE (ERROR ,"setting domain sched sedf" ); -return ERROR_FAIL ; - } - -return 0 ; -} -static int sched_rtds_domain_get (libxl__gc *gc,uint32_t domid,libxl_domain_sched_params *scinfo) {
@@ -5873,7 +5806,8 @@ int libxl_domain_sched_params_set(libxl_ctx *ctx, uint32_t domid,switch (sched) {case LIBXL_SCHEDULER_SEDF : - ret=sched_sedf_domain_set (gc, domid, scinfo); +LOG (ERROR ,"SEDF scheduler no longer available" ); + ret=ERROR_FEATURE_REMOVED ;break ;case LIBXL_SCHEDULER_CREDIT : ret=sched_credit_domain_set (gc, domid, scinfo);
@@ -5909,7 +5843,8 @@ int libxl_domain_sched_params_get(libxl_ctx *ctx, uint32_t domid,switch (scinfo->sched) {case LIBXL_SCHEDULER_SEDF : - ret=sched_sedf_domain_get (gc, domid, scinfo); +LOG (ERROR ,"SEDF scheduler no longer available" ); + ret=ERROR_FEATURE_REMOVED ;break ;case LIBXL_SCHEDULER_CREDIT : ret=sched_credit_domain_get (gc, domid, scinfo);
tools/libxl/libxl_create.c +0 -61
73 lines not on this page · raw message
tools/libxl/libxl_types.idl +7 -1
@@ -68,6 +68,7 @@ libxl_error = Enumeration("error", [ (-22, "ABORTED"), (-23, "NOTFOUND"), (-24, "DOMAIN_DESTROYED"), # Target domain ceased to exist during op + (-25, "FEATURE_REMOVED"), # For functionality that has been removed ], value_namespace = "") libxl_domain_type = Enumeration("domain_type", [
@@ -356,10 +357,15 @@ libxl_domain_sched_params = Struct("domain_sched_params",[ ("weight", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT'}), ("cap", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_CAP_DEFAULT'}), ("period", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_PERIOD_DEFAULT'}), + ("budget", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_BUDGET_DEFAULT'}), + + # The following three parameters ('slice', 'latency' and 'extratime') are deprecated, + # and will have no effect if used, since the SEDF scheduler has been removed. + # Note that 'period' was an SDF parameter too, but it is still effective as it is + # now used (together with 'budget') by the RTDS scheduler. ("slice", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_SLICE_DEFAULT'}), ("latency", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_LATENCY_DEFAULT'}), ("extratime", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_EXTRATIME_DEFAULT'}), - ("budget", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_BUDGET_DEFAULT'}), ]) libxl_vnode_info = Struct("vnode_info", [
Re: [PATCH v4 1/7] libxl: get rid of the SEDF scheduler
Quoted 9 lines · Dario Faggioli
only the interface is left in place, for backward compile-time compatibility, but every attempt to use it would throw an error.
Signed-off-by Dario Faggioli <[email protected]>---
Cc: George Dunlap <[email protected]>
Cc: Ian Jackson <[email protected]>
Cc: Stefano Stabellini <[email protected]>
Quoted 232 lines
Cc Wei Liu <[email protected]>Changes from v3:
- drop George's Rev-by: which should not be there since v2;
- better grouping of fields inlibxl_domain_sched_params, as suggested during review;
- improved comment forERROR_FEATURE_REMOVED, as suggested during review.Changes from v2:
- introduce and useERROR_FEATURE_REMOVED, as requested during review;
- mark the SEDF only parameter as deprecated in libxl_types.idl, as requested during review.--- tools/libxl/libxl.c | 73 ++----------------------------------------- tools/libxl/libxl_create.c | 61 ------------------------------------ tools/libxl/libxl_types.idl | 8 ++++- 3 files changed, 11 insertions(+), 131 deletions(-)tools/libxl/libxl.c +4
-69@@ -5728,73 +5728,6 @@ static int sched_credit2_domain_set(libxl__gc *gc, uint32_t domid,return 0 ; } -static int sched_sedf_domain_get (libxl__gc *gc,uint32_t domid, -libxl_domain_sched_params *scinfo) -{ -uint64_t period; -uint64_t slice; -uint64_t latency; -uint16_t extratime; -uint16_t weight; -int rc; - - rc =xc_sedf_domain_get (CTX ->xch, domid, &period, &slice, &latency, - &extratime, &weight); -if (rc !=0 ) { -LOGE (ERROR ,"getting domain sched sedf" ); -return ERROR_FAIL ; - } - -libxl_domain_sched_params_init (scinfo); - scinfo->sched =LIBXL_SCHEDULER_SEDF ; - scinfo->period = period /1000000 ; - scinfo->slice = slice /1000000 ; - scinfo->latency = latency /1000000 ; - scinfo->extratime = extratime; - scinfo->weight = weight; - -return 0 ; -} - -static int sched_sedf_domain_set (libxl__gc *gc,uint32_t domid, -const libxl_domain_sched_params *scinfo) -{ -uint64_t period; -uint64_t slice; -uint64_t latency; -uint16_t extratime; -uint16_t weight; - -int ret; - - ret =xc_sedf_domain_get (CTX ->xch, domid, &period, &slice, &latency, - &extratime, &weight); -if (ret !=0 ) { -LOGE (ERROR ,"getting domain sched sedf" ); -return ERROR_FAIL ; - } - -if (scinfo->period !=LIBXL_DOMAIN_SCHED_PARAM_PERIOD_DEFAULT ) - period = (uint64_t )scinfo->period *1000000 ; -if (scinfo->slice !=LIBXL_DOMAIN_SCHED_PARAM_SLICE_DEFAULT ) - slice = (uint64_t )scinfo->slice *1000000 ; -if (scinfo->latency !=LIBXL_DOMAIN_SCHED_PARAM_LATENCY_DEFAULT ) - latency = (uint64_t )scinfo->latency *1000000 ; -if (scinfo->extratime !=LIBXL_DOMAIN_SCHED_PARAM_EXTRATIME_DEFAULT ) - extratime = scinfo->extratime; -if (scinfo->weight !=LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT ) - weight = scinfo->weight; - - ret =xc_sedf_domain_set (CTX ->xch, domid, period, slice, latency, - extratime, weight); -if ( ret <0 ) { -LOGE (ERROR ,"setting domain sched sedf" ); -return ERROR_FAIL ; - } - -return 0 ; -} -static int sched_rtds_domain_get (libxl__gc *gc,uint32_t domid,libxl_domain_sched_params *scinfo) {@@ -5873,7 +5806,8 @@ int libxl_domain_sched_params_set(libxl_ctx *ctx, uint32_t domid,switch (sched) {case LIBXL_SCHEDULER_SEDF : - ret=sched_sedf_domain_set (gc, domid, scinfo); +LOG (ERROR ,"SEDF scheduler no longer available" ); + ret=ERROR_FEATURE_REMOVED ;break ;case LIBXL_SCHEDULER_CREDIT : ret=sched_credit_domain_set (gc, domid, scinfo);@@ -5909,7 +5843,8 @@ int libxl_domain_sched_params_get(libxl_ctx *ctx, uint32_t domid,switch (scinfo->sched) {case LIBXL_SCHEDULER_SEDF : - ret=sched_sedf_domain_get (gc, domid, scinfo); +LOG (ERROR ,"SEDF scheduler no longer available" ); + ret=ERROR_FEATURE_REMOVED ;break ;case LIBXL_SCHEDULER_CREDIT : ret=sched_credit_domain_get (gc, domid, scinfo);tools/libxl/libxl_create.c +0
-61@@ -50,61 +50,6 @@ int libxl__domain_create_info_setdefault(libxl__gc *gc,return 0 ; } -static int sched_params_valid (libxl__gc *gc, -uint32_t domid,libxl_domain_sched_params *scp) -{ -int has_weight = scp->weight !=LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT ; -int has_period = scp->period !=LIBXL_DOMAIN_SCHED_PARAM_PERIOD_DEFAULT ; -int has_slice = scp->slice !=LIBXL_DOMAIN_SCHED_PARAM_SLICE_DEFAULT ; -int has_extratime = - scp->extratime !=LIBXL_DOMAIN_SCHED_PARAM_EXTRATIME_DEFAULT ; - -/* The sedf scheduler needs some more consistency checking */ -if (libxl__domain_scheduler (gc, domid) ==LIBXL_SCHEDULER_SEDF ) { -if (has_weight && (has_period || has_slice)) -return 0 ; -/* If you want a real-time domain, with its own period and -* slice, please, do provide both! */ -if (has_period != has_slice) -return 0 ; - -/* -* Idea is, if we specify a weight, then both period and -* slice has to be zero. OTOH, if we do specify a period and -* slice, it is weight that should be zeroed. See -* docs/misc/sedf_scheduler_mini-HOWTO.txt for more details -* on the meaningful combinations and their meanings. -*/ -if (has_weight) { - scp->slice =0 ; - scp->period =0 ; - } -else if (!has_period) { -/* No weight nor slice/period means best effort. Parameters needs -* some mangling in order to properly ask for that, though. */ - -/* -* Providing no weight does not make any sense if we do not allow -* the domain to run in extra time. On the other hand, if we have -* extra time, weight will be ignored (and zeroed) by Xen, but it -* can't be zero here, or the call for setting the scheduling -* parameters will fail. So, avoid the latter by setting a random -* weight (namely, 1), as it will be ignored anyway. -*/ - -/* We can setup a proper best effort domain (extra time only) -* iff we either already have or are asking for some extra time. */ - scp->weight = has_extratime ? scp->extratime :1 ; - scp->period =0 ; - }else { -/* Real-time domain: will get slice CPU time over every period */ - scp->weight =0 ; - } - } - -return 1 ; -} -int libxl__domain_build_info_setdefault (libxl__gc *gc,libxl_domain_build_info *b_info) {@@ -888,12 +833,6 @@ static void initiate_domain_create(libxl__egc *egc, ret =libxl__domain_build_info_setdefault (gc, &d_config->b_info);if (ret) goto error_out; -if (!sched_params_valid (gc, domid, &d_config->b_info.sched_params)) { -LOG (ERROR ,"Invalid scheduling parameters\n" ); - ret =ERROR_INVAL ; - goto error_out; - } -for (i =0 ; i < d_config->num_disks; i++) { ret =libxl__device_disk_setdefault (gc, &d_config->disks[i]);if (ret) goto error_out;tools/libxl/libxl_types.idl +7
-1@@ -68,6 +68,7 @@ libxl_error = Enumeration("error", [ (-22, "ABORTED"), (-23, "NOTFOUND"), (-24, "DOMAIN_DESTROYED"), # Target domain ceased to exist during op + (-25, "FEATURE_REMOVED"), # For functionality that has been removed ], value_namespace = "") libxl_domain_type = Enumeration("domain_type", [@@ -356,10 +357,15 @@ libxl_domain_sched_params = Struct("domain_sched_params",[ ("weight", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT'}), ("cap", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_CAP_DEFAULT'}), ("period", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_PERIOD_DEFAULT'}), + ("budget", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_BUDGET_DEFAULT'}), + + # The following three parameters ('slice', 'latency' and 'extratime') are deprecated, + # and will have no effect if used, since the SEDF scheduler has been removed. + # Note that 'period' was an SDF parameter too, but it is still effective as it is + # now used (together with 'budget') by the RTDS scheduler. ("slice", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_SLICE_DEFAULT'}), ("latency", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_LATENCY_DEFAULT'}), ("extratime", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_EXTRATIME_DEFAULT'}), - ("budget", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_BUDGET_DEFAULT'}), ]) libxl_vnode_info = Struct("vnode_info", [_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Re: [PATCH v4 1/7] libxl: get rid of the SEDF scheduler
In reply to Dario FaggioliQuoted 11 lines · Dario Faggioli
only the interface is left in place, for backward compile-time compatibility, but every attempt to use it would throw an error.
Signed-off-by Dario Faggioli <[email protected]>---
Cc: George Dunlap <[email protected]>
Cc: Ian Jackson <[email protected]>
Cc: Stefano Stabellini <[email protected]>
Cc: Ian Campbell <[email protected]>
Cc: Wei Liu <[email protected]>
Quoted 226 lines
Changes from v3:
- drop George's Rev-by: which should not be there since v2;
- better grouping of fields inlibxl_domain_sched_params, as suggested during review;
- improved comment forERROR_FEATURE_REMOVED, as suggested during review.Changes from v2:
- introduce and useERROR_FEATURE_REMOVED, as requested during review;
- mark the SEDF only parameter as deprecated in libxl_types.idl, as requested during review.--- tools/libxl/libxl.c | 73 ++----------------------------------------- tools/libxl/libxl_create.c | 61 ------------------------------------ tools/libxl/libxl_types.idl | 8 ++++- 3 files changed, 11 insertions(+), 131 deletions(-)tools/libxl/libxl.c +4
-69@@ -5728,73 +5728,6 @@ static int sched_credit2_domain_set(libxl__gc *gc, uint32_t domid,return 0 ; } -static int sched_sedf_domain_get (libxl__gc *gc,uint32_t domid, -libxl_domain_sched_params *scinfo) -{ -uint64_t period; -uint64_t slice; -uint64_t latency; -uint16_t extratime; -uint16_t weight; -int rc; - - rc =xc_sedf_domain_get (CTX ->xch, domid, &period, &slice, &latency, - &extratime, &weight); -if (rc !=0 ) { -LOGE (ERROR ,"getting domain sched sedf" ); -return ERROR_FAIL ; - } - -libxl_domain_sched_params_init (scinfo); - scinfo->sched =LIBXL_SCHEDULER_SEDF ; - scinfo->period = period /1000000 ; - scinfo->slice = slice /1000000 ; - scinfo->latency = latency /1000000 ; - scinfo->extratime = extratime; - scinfo->weight = weight; - -return 0 ; -} - -static int sched_sedf_domain_set (libxl__gc *gc,uint32_t domid, -const libxl_domain_sched_params *scinfo) -{ -uint64_t period; -uint64_t slice; -uint64_t latency; -uint16_t extratime; -uint16_t weight; - -int ret; - - ret =xc_sedf_domain_get (CTX ->xch, domid, &period, &slice, &latency, - &extratime, &weight); -if (ret !=0 ) { -LOGE (ERROR ,"getting domain sched sedf" ); -return ERROR_FAIL ; - } - -if (scinfo->period !=LIBXL_DOMAIN_SCHED_PARAM_PERIOD_DEFAULT ) - period = (uint64_t )scinfo->period *1000000 ; -if (scinfo->slice !=LIBXL_DOMAIN_SCHED_PARAM_SLICE_DEFAULT ) - slice = (uint64_t )scinfo->slice *1000000 ; -if (scinfo->latency !=LIBXL_DOMAIN_SCHED_PARAM_LATENCY_DEFAULT ) - latency = (uint64_t )scinfo->latency *1000000 ; -if (scinfo->extratime !=LIBXL_DOMAIN_SCHED_PARAM_EXTRATIME_DEFAULT ) - extratime = scinfo->extratime; -if (scinfo->weight !=LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT ) - weight = scinfo->weight; - - ret =xc_sedf_domain_set (CTX ->xch, domid, period, slice, latency, - extratime, weight); -if ( ret <0 ) { -LOGE (ERROR ,"setting domain sched sedf" ); -return ERROR_FAIL ; - } - -return 0 ; -} -static int sched_rtds_domain_get (libxl__gc *gc,uint32_t domid,libxl_domain_sched_params *scinfo) {@@ -5873,7 +5806,8 @@ int libxl_domain_sched_params_set(libxl_ctx *ctx, uint32_t domid,switch (sched) {case LIBXL_SCHEDULER_SEDF : - ret=sched_sedf_domain_set (gc, domid, scinfo); +LOG (ERROR ,"SEDF scheduler no longer available" ); + ret=ERROR_FEATURE_REMOVED ;break ;case LIBXL_SCHEDULER_CREDIT : ret=sched_credit_domain_set (gc, domid, scinfo);@@ -5909,7 +5843,8 @@ int libxl_domain_sched_params_get(libxl_ctx *ctx, uint32_t domid,switch (scinfo->sched) {case LIBXL_SCHEDULER_SEDF : - ret=sched_sedf_domain_get (gc, domid, scinfo); +LOG (ERROR ,"SEDF scheduler no longer available" ); + ret=ERROR_FEATURE_REMOVED ;break ;case LIBXL_SCHEDULER_CREDIT : ret=sched_credit_domain_get (gc, domid, scinfo);tools/libxl/libxl_create.c +0
-61@@ -50,61 +50,6 @@ int libxl__domain_create_info_setdefault(libxl__gc *gc,return 0 ; } -static int sched_params_valid (libxl__gc *gc, -uint32_t domid,libxl_domain_sched_params *scp) -{ -int has_weight = scp->weight !=LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT ; -int has_period = scp->period !=LIBXL_DOMAIN_SCHED_PARAM_PERIOD_DEFAULT ; -int has_slice = scp->slice !=LIBXL_DOMAIN_SCHED_PARAM_SLICE_DEFAULT ; -int has_extratime = - scp->extratime !=LIBXL_DOMAIN_SCHED_PARAM_EXTRATIME_DEFAULT ; - -/* The sedf scheduler needs some more consistency checking */ -if (libxl__domain_scheduler (gc, domid) ==LIBXL_SCHEDULER_SEDF ) { -if (has_weight && (has_period || has_slice)) -return 0 ; -/* If you want a real-time domain, with its own period and -* slice, please, do provide both! */ -if (has_period != has_slice) -return 0 ; - -/* -* Idea is, if we specify a weight, then both period and -* slice has to be zero. OTOH, if we do specify a period and -* slice, it is weight that should be zeroed. See -* docs/misc/sedf_scheduler_mini-HOWTO.txt for more details -* on the meaningful combinations and their meanings. -*/ -if (has_weight) { - scp->slice =0 ; - scp->period =0 ; - } -else if (!has_period) { -/* No weight nor slice/period means best effort. Parameters needs -* some mangling in order to properly ask for that, though. */ - -/* -* Providing no weight does not make any sense if we do not allow -* the domain to run in extra time. On the other hand, if we have -* extra time, weight will be ignored (and zeroed) by Xen, but it -* can't be zero here, or the call for setting the scheduling -* parameters will fail. So, avoid the latter by setting a random -* weight (namely, 1), as it will be ignored anyway. -*/ - -/* We can setup a proper best effort domain (extra time only) -* iff we either already have or are asking for some extra time. */ - scp->weight = has_extratime ? scp->extratime :1 ; - scp->period =0 ; - }else { -/* Real-time domain: will get slice CPU time over every period */ - scp->weight =0 ; - } - } - -return 1 ; -} -int libxl__domain_build_info_setdefault (libxl__gc *gc,libxl_domain_build_info *b_info) {@@ -888,12 +833,6 @@ static void initiate_domain_create(libxl__egc *egc, ret =libxl__domain_build_info_setdefault (gc, &d_config->b_info);if (ret) goto error_out; -if (!sched_params_valid (gc, domid, &d_config->b_info.sched_params)) { -LOG (ERROR ,"Invalid scheduling parameters\n" ); - ret =ERROR_INVAL ; - goto error_out; - } -for (i =0 ; i < d_config->num_disks; i++) { ret =libxl__device_disk_setdefault (gc, &d_config->disks[i]);if (ret) goto error_out;tools/libxl/libxl_types.idl +7
-1@@ -68,6 +68,7 @@ libxl_error = Enumeration("error", [ (-22, "ABORTED"), (-23, "NOTFOUND"), (-24, "DOMAIN_DESTROYED"), # Target domain ceased to exist during op + (-25, "FEATURE_REMOVED"), # For functionality that has been removed ], value_namespace = "") libxl_domain_type = Enumeration("domain_type", [@@ -356,10 +357,15 @@ libxl_domain_sched_params = Struct("domain_sched_params",[ ("weight", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_WEIGHT_DEFAULT'}), ("cap", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_CAP_DEFAULT'}), ("period", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_PERIOD_DEFAULT'}), + ("budget", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_BUDGET_DEFAULT'}), + + # The following three parameters ('slice', 'latency' and 'extratime') are deprecated, + # and will have no effect if used, since the SEDF scheduler has been removed. + # Note that 'period' was an SDF parameter too, but it is still effective as it is + # now used (together with 'budget') by the RTDS scheduler. ("slice", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_SLICE_DEFAULT'}), ("latency", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_LATENCY_DEFAULT'}), ("extratime", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_EXTRATIME_DEFAULT'}), - ("budget", integer, {'init_val': 'LIBXL_DOMAIN_SCHED_PARAM_BUDGET_DEFAULT'}), ]) libxl_vnode_info = Struct("vnode_info", [
Re: [PATCH v4 1/7] libxl: get rid of the SEDF scheduler
Quoted 13 lines · George Dunlap
Quoted 11 lines · Dario Faggioli
only the interface is left in place, for backward compile-time compatibility, but every attempt to use it would throw an error.
Signed-off-by Dario Faggioli <[email protected]>---
Cc: George Dunlap <[email protected]>
Cc: Ian Jackson <[email protected]>
Cc: Stefano Stabellini <[email protected]>
Cc: Ian Campbell <[email protected]>
Cc: Wei Liu <[email protected]>
Quoted 1 line
Acked-by George Dunlap <[email protected]>
Applied the whole series, thanks.
PATCH v4 2/7 tools: python: get rid of the SEDF scheduler bindings
In reply to Dario Faggiolias it is going away from libxc, so these won't build any longer.
---
Cc: Ian Jackson <[email protected]>
Cc: Stefano Stabellini <[email protected]>
Cc: Wei Liu <[email protected]>
--- tools/python/xen/lowlevel/xc/xc.c | 70 ------------------------------------- 1 file changed, 70 deletions(-)
tools/python/xen/lowlevel/xc/xc.c +0 -70
@@ -1433,51 +1433,6 @@ static PyObject *pyxc_xeninfo(XcObject *self) "cc_compile_date", xen_cc.compile_date); } - -static PyObject *pyxc_sedf_domain_set (XcObject *self, -PyObject *args, -PyObject *kwds) -{ -uint32_t domid; -uint64_t period, slice, latency; -uint16_t extratime, weight; -static char *kwd_list[] = {"domid" ,"period" ,"slice" , -"latency" ,"extratime" ,"weight" ,NULL }; - -if ( !PyArg_ParseTupleAndKeywords (args, kwds,"iLLLhh" , kwd_list, - &domid, &period, &slice, - &latency, &extratime, &weight) ) -return NULL ; -if (xc_sedf_domain_set (self->xc_handle, domid, period, - slice, latency, extratime,weight) !=0 ) -return pyxc_error_to_exception (self->xc_handle); - -Py_INCREF (zero); -return zero; -} - -static PyObject *pyxc_sedf_domain_get (XcObject *self,PyObject *args) -{ -uint32_t domid; -uint64_t period, slice,latency; -uint16_t weight, extratime; - -if (!PyArg_ParseTuple (args,"i" , &domid)) -return NULL ; - -if (xc_sedf_domain_get (self->xc_handle, domid, &period, - &slice,&latency,&extratime,&weight)) -return pyxc_error_to_exception (self->xc_handle); - -return Py_BuildValue ("{s:i,s:L,s:L,s:L,s:i,s:i}" , -"domid" , domid, -"period" , period, -"slice" , slice, -"latency" , latency, -"extratime" , extratime, -"weight" , weight); -} -static PyObject *pyxc_shadow_control (PyObject *self,PyObject *args,PyObject *kwds)
@@ -2490,30 +2445,6 @@ static PyMethodDef pyxc_methods[] = {"Get the current scheduler type in use.\n" "Returns: [int] sched_id.\n" }, - { "sedf_domain_set", - (PyCFunction )pyxc_sedf_domain_set, -METH_KEYWORDS ,"\n" -"Set the scheduling parameters for a domain when running with Atropos.\n" -" dom [int]: domain to set\n" -" period [long]: domain's scheduling period\n" -" slice [long]: domain's slice per period\n" -" latency [long]: domain's wakeup latency hint\n" -" extratime [int]: domain aware of extratime?\n" - "Returns: [int] 0 on success; -1 on error.\n" }, - - { "sedf_domain_get", - (PyCFunction )pyxc_sedf_domain_get, -METH_VARARGS ,"\n" -"Get the current scheduling parameters for a domain when running with\n" -"the Atropos scheduler." -" dom [int]: domain to query\n" -"Returns: [dict]\n" -" domain [int]: domain ID\n" -" period [long]: scheduler period\n" -" slice [long]: CPU reservation per period\n" -" latency [long]: domain's wakeup latency hint\n" - " extratime [int]: domain aware of extratime?\n"}, - { "sched_credit_domain_set", (PyCFunction )pyxc_sched_credit_domain_set,METH_KEYWORDS ,"\n"
@@ -3033,7 +2964,6 @@ PyMODINIT_FUNC initxc(void)PyModule_AddObject (m,"Error" , xc_error_obj);/* Expose some libxc constants to Python */ -PyModule_AddIntConstant (m,"XEN_SCHEDULER_SEDF" ,XEN_SCHEDULER_SEDF );PyModule_AddIntConstant (m,"XEN_SCHEDULER_CREDIT" ,XEN_SCHEDULER_CREDIT );PyModule_AddIntConstant (m,"XEN_SCHEDULER_CREDIT2" ,XEN_SCHEDULER_CREDIT2 );
PATCH v4 3/7 libxc: get rid of the SEDF scheduler
In reply to Dario Faggioli---
Cc: Ian Jackson <[email protected]>
Cc: Stefano Stabellini <[email protected]>
Cc: Wei Liu <[email protected]>
--- tools/libxc/Makefile | 1 - tools/libxc/include/xenctrl.h | 12 ------ tools/libxc/xc_sedf.c | 78 ----------------------------------------- 3 files changed, 91 deletions(-) delete mode 100644 tools/libxc/xc_sedf.c
tools/libxc/Makefile +0 -1
@@ -21,7 +21,6 @@ CTRL_SRCS-y += xc_misc.c CTRL_SRCS-y += xc_flask.c CTRL_SRCS-y += xc_physdev.c CTRL_SRCS-y += xc_private.c -CTRL_SRCS-y += xc_sedf.c CTRL_SRCS-y += xc_csched.c CTRL_SRCS-y += xc_csched2.c CTRL_SRCS-y += xc_arinc653.c
tools/libxc/include/xenctrl.h +0 -12
@@ -875,18 +875,6 @@ int xc_shadow_control(xc_interface *xch,uint32_t mode, xc_shadow_op_stats_t *stats); -int xc_sedf_domain_set (xc_interface *xch, -uint32_t domid, -uint64_t period,uint64_t slice, -uint64_t latency,uint16_t extratime, -uint16_t weight); - -int xc_sedf_domain_get (xc_interface *xch, -uint32_t domid, -uint64_t * period,uint64_t *slice, -uint64_t *latency,uint16_t *extratime, -uint16_t *weight); -int xc_sched_credit_domain_set (xc_interface *xch,uint32_t domid,struct xen_domctl_sched_credit *sdom);
tools/libxc/xc_sedf.c deleted +0 -78
78 lines not on this page · raw message
PATCH v4 4/7 xen: get rid of the SEDF scheduler
In reply to Dario Faggiolimore specifically, of all the symbols and references to it.
---
Changes from v1:
- added markers for removed #defines, to help keep bits of the history, and reduce the likelyhood of accidental reuse, as requested during review.
--- docs/misc/xen-command-line.markdown | 2 +- xen/common/Makefile | 1 - xen/common/schedule.c | 1 - xen/include/public/domctl.h | 9 +-------- xen/include/public/trace.h | 2 +- xen/include/xen/sched-if.h | 1 - 6 files changed, 3 insertions(+), 13 deletions(-)
docs/misc/xen-command-line.markdown +1 -1
@@ -1217,7 +1217,7 @@ Map the HPET page as read only in Dom0. If disabled the page will be mapped with read and write permissions. ### sched -> `= credit | credit2 | sedf | arinc653` +> `= credit | credit2 | arinc653` > Default: `sched=credit`
xen/common/Makefile +0 -1
@@ -31,7 +31,6 @@ obj-y += rbtree.o obj-y += rcupdate.o obj-y += sched_credit.o obj-y += sched_credit2.o -obj-y += sched_sedf.o obj-y += sched_arinc653.o obj-y += sched_rt.o obj-y += schedule.o
xen/common/schedule.c +0 -1
@@ -65,7 +65,6 @@ DEFINE_PER_CPU(struct schedule_data, schedule_data); DEFINE_PER_CPU(struct scheduler *, scheduler);static const struct scheduler *schedulers[] = { - &sched_sedf_def, &sched_credit_def, &sched_credit2_def, &sched_arinc653_def,
xen/include/public/domctl.h +1 -8
@@ -324,7 +324,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t);/* XEN_DOMCTL_scheduler_op */ /* Scheduler types. */ -#define XEN_SCHEDULER_SEDF 4 +/* #define XEN_SCHEDULER_SEDF 4 (Removed) */ #define XEN_SCHEDULER_CREDIT 5#define XEN_SCHEDULER_CREDIT2 6#define XEN_SCHEDULER_ARINC653 7
@@ -337,13 +337,6 @@ struct xen_domctl_scheduler_op {uint32_t sched_id;/* XEN_SCHEDULER_* */ uint32_t cmd;/* XEN_DOMCTL_SCHEDOP_* */ union { -struct xen_domctl_sched_sedf { -uint64_aligned_t period; -uint64_aligned_t slice; -uint64_aligned_t latency; -uint32_t extratime; -uint32_t weight; - } sedf; struct xen_domctl_sched_credit { uint16_t weight; uint16_t cap;
xen/include/public/trace.h +1 -1
@@ -75,7 +75,7 @@/* Per-scheduler IDs, to identify scheduler specific events */ #define TRC_SCHED_CSCHED 0#define TRC_SCHED_CSCHED2 1 -#define TRC_SCHED_SEDF 2 +/* #define XEN_SCHEDULER_SEDF 2 (Removed) */ #define TRC_SCHED_ARINC653 3#define TRC_SCHED_RTDS 4
xen/include/xen/sched-if.h +0 -1
@@ -165,7 +165,6 @@ struct scheduler {void (*tick_resume) (const struct scheduler *,unsigned int ); }; -extern const struct scheduler sched_sedf_def;extern const struct scheduler sched_credit_def;extern const struct scheduler sched_credit2_def;extern const struct scheduler sched_arinc653_def;
PATCH v4 5/7 xen: kill sched_sedf.c
In reply to Dario Faggioli--- xen/common/sched_sedf.c | 1557 ----------------------------------------------- 1 file changed, 1557 deletions(-) delete mode 100644 xen/common/sched_sedf.c
xen/common/sched_sedf.c deleted +0 -1557
@@ -1,1557 +0,0 @@ -/****************************************************************************** -* Simple EDF scheduler for xen -* -* by Stephan Diestelhorst (C) 2004 Cambridge University -* based on code by Mark Williamson (C) 2004 Intel Research Cambridge -*/ - -#include <xen/lib.h> -#include <xen/sched.h> -#include <xen/sched-if.h> -#include <xen/timer.h> -#include <xen/softirq.h> -#include <xen/time.h> -#include <xen/errno.h> - -#ifndef NDEBUG -#define SEDF_STATS -#define CHECK (_p) \ - do { \ - if ( !(_p) ) \ - printk("Check '%s' failed, line %d, file %s\n", \ - #_p , __LINE__, __FILE__); \ - } while ( 0 ) -#else -#define CHECK (_p) ((void)0) -#endif - -#define EXTRA_NONE (0) -#define EXTRA_AWARE (1) -#define EXTRA_RUN_PEN (2) -#define EXTRA_RUN_UTIL (4) -#define EXTRA_WANT_PEN_Q (8) -#define EXTRA_PEN_Q (0) -#define EXTRA_UTIL_Q (1) -#define SEDF_ASLEEP (16) - -#define EXTRA_QUANTUM (MICROSECS(500)) -#define WEIGHT_PERIOD (MILLISECS(100)) -#define WEIGHT_SAFETY (MILLISECS(5)) - -#define PERIOD_MAX MILLISECS(10000)/* 10s */ -#define PERIOD_MIN (MICROSECS(10))/* 10us */ -#define SLICE_MIN (MICROSECS(5))/* 5us */ - -#define IMPLY (a, b) (!(a) || (b)) -#define EQ (a, b) ((!!(a)) == (!!(b))) - - -struct sedf_dom_info { -struct domain *domain; -}; - -struct sedf_priv_info { -/* lock for the whole pluggable scheduler, nests inside cpupool_lock */ -spinlock_t lock; -}; - -struct sedf_vcpu_info { -struct vcpu *vcpu; -struct list_head list; -struct list_head extralist[2 ]; - -/* Parameters for EDF */ -s_time_t period;/* = relative deadline */ -s_time_t slice;/* = worst case execution time */ - -/* Advaced Parameters */ - -/* Latency Scaling */ -s_time_t period_orig; -s_time_t slice_orig; -s_time_t latency; - -/* Status of domain */ -int status; -/* Weights for "Scheduling for beginners/ lazy/ etc." ;) */ -short weight; -short extraweight; -/* Bookkeeping */ -s_time_t deadl_abs; -s_time_t sched_start_abs; -s_time_t cputime; -/* Times the domain un-/blocked */ -s_time_t block_abs; -s_time_t unblock_abs; - -/* Scores for {util, block penalty}-weighted extratime distribution */ -int score[2 ]; -s_time_t short_block_lost_tot; - -/* Statistics */ -s_time_t extra_time_tot; - -#ifdef SEDF_STATS -s_time_t block_time_tot; -s_time_t penalty_time_tot; -int block_tot; -int short_block_tot; -int long_block_tot; -int pen_extra_blocks; -int pen_extra_slices; -#endif -}; - -struct sedf_cpu_info { -struct list_head runnableq; -struct list_head waitq; -struct list_head extraq[2 ]; -s_time_t current_slice_expires; -}; - -#define SEDF_PRIV (_ops) \ - ((struct sedf_priv_info *)((_ops)->sched_data)) -#define EDOM_INFO (d) ((struct sedf_vcpu_info *)((d)->sched_priv)) -#define CPU_INFO (cpu) \ - ((struct sedf_cpu_info *)per_cpu(schedule_data, cpu).sched_priv) -#define LIST (d) (&EDOM_INFO(d)->list) -#define EXTRALIST (d,i) (&(EDOM_INFO(d)->extralist[i])) -#define RUNQ (cpu) (&CPU_INFO(cpu)->runnableq) -#define WAITQ (cpu) (&CPU_INFO(cpu)->waitq) -#define EXTRAQ (cpu,i) (&(CPU_INFO(cpu)->extraq[i])) -#define IDLETASK (cpu) (idle_vcpu[cpu]) - -#define PERIOD_BEGIN (inf) ((inf)->deadl_abs - (inf)->period) - -#define DIV_UP (x,y) (((x) + (y) - 1) / y) - -#define extra_runs (inf) ((inf->status) & 6) -#define extra_get_cur_q (inf) (((inf->status & 6) >> 1)-1) -#define sedf_runnable (edom) (!(EDOM_INFO(edom)->status & SEDF_ASLEEP)) - - -static void sedf_dump_cpu_state (const struct scheduler *ops,int i); - -static inline int extraq_on (struct vcpu *d,int i) -{ -return ((EXTRALIST (d,i)->next !=NULL ) && - (EXTRALIST (d,i)->next !=EXTRALIST (d,i))); -} - -static inline void extraq_del (struct vcpu *d,int i) -{ -struct list_head *list =EXTRALIST (d,i); -ASSERT (extraq_on (d,i)); -list_del (list); - list->next =NULL ; -ASSERT (!extraq_on (d, i)); -} - -/* -* Adds a domain to the queue of processes which are aware of extra time. List -* is sorted by score, where a lower score means higher priority for an extra -* slice. It also updates the score, by simply subtracting a fixed value from -* each entry, in order to avoid overflow. The algorithm works by simply -* charging each domain that recieved extratime with an inverse of its weight. -*/ -static inline void extraq_add_sort_update (struct vcpu *d,int i,int sub) -{ -struct list_head *cur; -struct sedf_vcpu_info *curinf; - -ASSERT (!extraq_on (d,i)); - -/* -* Iterate through all elements to find our "hole" and on our way -* update all the other scores. -*/ - list_for_each ( cur, EXTRAQ(d->processor, i) ) - { - curinf = list_entry(cur,struct sedf_vcpu_info,extralist[i]); - curinf->score[i] -= sub; -if (EDOM_INFO (d)->score[i] < curinf->score[i] ) -break ; - } - -/* cur now contains the element, before which we'll enqueue */ -list_add (EXTRALIST (d,i),cur->prev); - -/* Continue updating the extraq */ -if ( (cur !=EXTRAQ (d->processor,i)) && sub ) - { -for ( cur = cur->next; cur !=EXTRAQ (d->processor,i); cur = cur->next ) - { - curinf = list_entry(cur,struct sedf_vcpu_info, extralist[i]); - curinf->score[i] -= sub; - } - } - -ASSERT (extraq_on (d,i)); -} -static inline void extraq_check (struct vcpu *d) -{ -if (extraq_on (d,EXTRA_UTIL_Q ) ) - { -if ( !(EDOM_INFO (d)->status &EXTRA_AWARE ) && - !extra_runs (EDOM_INFO (d)) ) -extraq_del (d,EXTRA_UTIL_Q ); - } -else - { -if ( (EDOM_INFO (d)->status &EXTRA_AWARE ) &&sedf_runnable (d) ) -extraq_add_sort_update (d,EXTRA_UTIL_Q ,0 ); - } -} - -static inline void extraq_check_add_unblocked (struct vcpu *d,int priority) -{ -struct sedf_vcpu_info *inf =EDOM_INFO (d); - -if ( inf->status &EXTRA_AWARE ) -/* Put on the weighted extraq without updating any scores */ -extraq_add_sort_update (d,EXTRA_UTIL_Q ,0 ); -} - -static inline int __task_on_queue (struct vcpu *d) -{ -return (((LIST (d))->next !=NULL ) && (LIST (d)->next !=LIST (d))); -} - -static inline void __del_from_queue (struct vcpu *d) -{ -struct list_head *list =LIST (d); -ASSERT (__task_on_queue (d)); -list_del (list); - list->next =NULL ; -ASSERT (!__task_on_queue (d)); -} - -typedef int (*list_comparer )(struct list_head * el1,struct list_head * el2); - -static inline void list_insert_sort ( -struct list_head *list,struct list_head *element,list_comparer comp) -{ -struct list_head *cur; - -/* Iterate through all elements to find our "hole" */ -list_for_each ( cur, list ) -if (comp (element, cur) <0 ) -break ; - -/* cur now contains the element, before which we'll enqueue */ -list_add (element, cur->prev); -} - -#define DOMAIN_COMPARER (name, field, comp1, comp2) \ -static int name##_comp(struct list_head* el1, struct list_head* el2) \ -{ \ - struct sedf_vcpu_info *d1, *d2; \ - d1 = list_entry(el1,struct sedf_vcpu_info, field); \ - d2 = list_entry(el2,struct sedf_vcpu_info, field); \ - if ( (comp1) == (comp2) ) \ - return 0; \ - if ( (comp1) < (comp2) ) \ - return -1; \ - else \ - return 1; \ -} - -/* -* Adds a domain to the queue of processes which wait for the beginning of the -* next period; this list is therefore sortet by this time, which is simply -* absol. deadline - period. -*/ -DOMAIN_COMPARER (waitq, list,PERIOD_BEGIN (d1),PERIOD_BEGIN (d2)); -static inline void __add_to_waitqueue_sort (struct vcpu *v) -{ -ASSERT (!__task_on_queue (v)); -list_insert_sort (WAITQ (v->processor),LIST (v), waitq_comp); -ASSERT (__task_on_queue (v)); -} - -/* -* Adds a domain to the queue of processes which have started their current -* period and are runnable (i.e. not blocked, dieing,...). The first element -* on this list is running on the processor, if the list is empty the idle -* task will run. As we are implementing EDF, this list is sorted by deadlines. -*/ -DOMAIN_COMPARER (runq, list, d1->deadl_abs, d2->deadl_abs); -static inline void __add_to_runqueue_sort (struct vcpu *v) -{ -list_insert_sort (RUNQ (v->processor),LIST (v), runq_comp); -} - - -static void sedf_insert_vcpu (const struct scheduler *ops,struct vcpu *v) -{ -if ( !is_idle_vcpu (v) ) - { -extraq_check (v); - } -else - { -EDOM_INFO (v)->deadl_abs =0 ; -EDOM_INFO (v)->status &= ~SEDF_ASLEEP ; - } -} - -static void *sedf_alloc_vdata (const struct scheduler *ops,struct vcpu *v,void *dd) -{ -struct sedf_vcpu_info *inf; - - inf = xzalloc(struct sedf_vcpu_info); -if ( inf ==NULL ) -return NULL ; - - inf->vcpu = v; - -/* Every VCPU gets an equal share of extratime by default */ - inf->deadl_abs =0 ; - inf->latency =0 ; - inf->status =EXTRA_AWARE |SEDF_ASLEEP ; - inf->extraweight =1 ; -/* Upon creation all domain are best-effort */ - inf->period =WEIGHT_PERIOD ; - inf->slice =0 ; - - inf->period_orig = inf->period; inf->slice_orig = inf->slice; -INIT_LIST_HEAD (&(inf->list)); -INIT_LIST_HEAD (&(inf->extralist[EXTRA_PEN_Q ])); -INIT_LIST_HEAD (&(inf->extralist[EXTRA_UTIL_Q ])); - -SCHED_STAT_CRANK (vcpu_init); - -return inf; -} - -static void * -sedf_alloc_pdata (const struct scheduler *ops,int cpu) -{ -struct sedf_cpu_info *spc; - - spc = xzalloc(struct sedf_cpu_info); -BUG_ON (spc ==NULL ); -INIT_LIST_HEAD (&spc->waitq); -INIT_LIST_HEAD (&spc->runnableq); -INIT_LIST_HEAD (&spc->extraq[EXTRA_PEN_Q ]); -INIT_LIST_HEAD (&spc->extraq[EXTRA_UTIL_Q ]); - -return (void *)spc; -} - -static void -sedf_free_pdata (const struct scheduler *ops,void *spc,int cpu) -{ -if ( spc ==NULL ) -return ; - -xfree (spc); -} - -static void sedf_free_vdata (const struct scheduler *ops,void *priv) -{ -xfree (priv); -} - -static void * -sedf_alloc_domdata (const struct scheduler *ops,struct domain *d) -{ - return xzalloc(struct sedf_dom_info); -} - -static int sedf_init_domain (const struct scheduler *ops,struct domain *d) -{ - d->sched_priv =sedf_alloc_domdata (ops, d); -if ( d->sched_priv ==NULL ) -return -ENOMEM ; - -return 0 ; -} - -static void sedf_free_domdata (const struct scheduler *ops,void *data) -{ -xfree (data); -} - -static void sedf_destroy_domain (const struct scheduler *ops,struct domain *d) -{ -sedf_free_domdata (ops, d->sched_priv); -} - -static int sedf_pick_cpu (const struct scheduler *ops,struct vcpu *v) -{ -cpumask_t online_affinity; -cpumask_t *online; - - online =cpupool_scheduler_cpumask (v->domain->cpupool); -cpumask_and (&online_affinity, v->cpu_hard_affinity, online); -return cpumask_cycle (v->vcpu_id %cpumask_weight (&online_affinity) -1 , - &online_affinity); -} - -/* -* Handles the rescheduling & bookkeeping of domains running in their -* guaranteed timeslice. -*/ -static void desched_edf_dom (s_time_t now,struct vcpu * d) -{ -struct sedf_vcpu_info * inf =EDOM_INFO (d); - -/* Current domain is running in real time mode */ -ASSERT (__task_on_queue (d)); - -/* Update the domain's cputime */ - inf->cputime += now - inf->sched_start_abs; - -/* Scheduling decisions which don't remove the running domain from -* the runq */ -if ( (inf->cputime < inf->slice) &&sedf_runnable (d) ) -return ; - -__del_from_queue (d); - -/* -* Manage bookkeeping (i.e. calculate next deadline, memorise -* overrun-time of slice) of finished domains. -*/ -if ( inf->cputime >= inf->slice ) - { - inf->cputime -= inf->slice; - -if ( inf->period < inf->period_orig ) - { -/* This domain runs in latency scaling or burst mode */ - inf->period *=2 ; - inf->slice *=2 ; -if ( (inf->period > inf->period_orig) || - (inf->slice > inf->slice_orig) ) - { -/* Reset slice and period */ - inf->period = inf->period_orig; - inf->slice = inf->slice_orig; - } - } - -/* Set next deadline */ - inf->deadl_abs += inf->period; - } - -/* Add a runnable domain to the waitqueue */ -if (sedf_runnable (d) ) - { -__add_to_waitqueue_sort (d); - } -else - { -/* We have a blocked realtime task -> remove it from exqs too */ -if (extraq_on (d,EXTRA_PEN_Q ) ) -extraq_del (d,EXTRA_PEN_Q ); -if (extraq_on (d,EXTRA_UTIL_Q ) ) -extraq_del (d,EXTRA_UTIL_Q ); - } - -ASSERT (EQ (sedf_runnable (d),__task_on_queue (d))); -ASSERT (IMPLY (extraq_on (d,EXTRA_UTIL_Q ) ||extraq_on (d,EXTRA_PEN_Q ), -sedf_runnable (d))); -} - - -/* Update all elements on the queues */ -static void update_queues ( -s_time_t now,struct list_head *runq,struct list_head *waitq) -{ -struct list_head *cur, *tmp; -struct sedf_vcpu_info *curinf; - -/* -* Check for the first elements of the waitqueue, whether their -* next period has already started. -*/ - list_for_each_safe ( cur, tmp, waitq ) - { - curinf = list_entry(cur, struct sedf_vcpu_info, list); -if (PERIOD_BEGIN (curinf) > now ) -break ; -__del_from_queue (curinf->vcpu); -__add_to_runqueue_sort (curinf->vcpu); - } - -/* Process the runq, find domains that are on the runq that shouldn't */ - list_for_each_safe ( cur, tmp, runq ) - { - curinf = list_entry(cur,struct sedf_vcpu_info,list); - -if (unlikely (curinf->slice ==0 ) ) - { -/* Ignore domains with empty slice */ -__del_from_queue (curinf->vcpu); - -/* Move them to their next period */ - curinf->deadl_abs += curinf->period; - -/* Ensure that the start of the next period is in the future */ -if (unlikely (PERIOD_BEGIN (curinf) < now) ) - curinf->deadl_abs += - (DIV_UP (now -PERIOD_BEGIN (curinf), - curinf->period)) * curinf->period; - -/* Put them back into the queue */ -__add_to_waitqueue_sort (curinf->vcpu); - } -else if (unlikely ((curinf->deadl_abs < now) || - (curinf->cputime > curinf->slice)) ) - { -/* -* We missed the deadline or the slice was already finished. -* Might hapen because of dom_adj. -*/ -printk ("\tDomain %i.%i exceeded it's deadline/" -"slice (%" PRIu64" / %" PRIu64") now: %" PRIu64 -" cputime: %" PRIu64"\n" , - curinf->vcpu->domain->domain_id, - curinf->vcpu->vcpu_id, - curinf->deadl_abs, curinf->slice, now, - curinf->cputime); -__del_from_queue (curinf->vcpu); - -/* Common case: we miss one period */ - curinf->deadl_abs += curinf->period; - -/* -* If we are still behind: modulo arithmetic, force deadline -* to be in future and aligned to period borders. -*/ -if (unlikely (curinf->deadl_abs < now) ) - curinf->deadl_abs += -DIV_UP (now - curinf->deadl_abs, - curinf->period) * curinf->period; -ASSERT (curinf->deadl_abs >= now); - -/* Give a fresh slice */ - curinf->cputime =0 ; -if (PERIOD_BEGIN (curinf) > now ) -__add_to_waitqueue_sort (curinf->vcpu); -else -__add_to_runqueue_sort (curinf->vcpu); - } -else -break ; - } -} - - -/* -* removes a domain from the head of the according extraQ and -* requeues it at a specified position: -* round-robin extratime: end of extraQ -* weighted ext.: insert in sorted list by score -* if the domain is blocked / has regained its short-block-loss -* time it is not put on any queue. -*/ -static void desched_extra_dom (s_time_t now,struct vcpu *d) -{ -struct sedf_vcpu_info *inf =EDOM_INFO (d); -int i =extra_get_cur_q (inf); -unsigned long oldscore; - -ASSERT (extraq_on (d, i)); - -/* Unset all running flags */ - inf->status &= ~(EXTRA_RUN_PEN |EXTRA_RUN_UTIL ); -/* Fresh slice for the next run */ - inf->cputime =0 ; -/* Accumulate total extratime */ - inf->extra_time_tot += now - inf->sched_start_abs; -/* Remove extradomain from head of the queue. */ -extraq_del (d, i); - -/* Update the score */ - oldscore = inf->score[i]; -if ( i ==EXTRA_PEN_Q ) - { -/* Domain was running in L0 extraq */ -/* reduce block lost, probably more sophistication here!*/ -/*inf->short_block_lost_tot -= EXTRA_QUANTUM;*/ - inf->short_block_lost_tot -= now - inf->sched_start_abs; -#if 0 -/* KAF: If we don't exit short-blocking state at this point -* domain0 can steal all CPU for up to 10 seconds before -* scheduling settles down (when competing against another -* CPU-bound domain). Doing this seems to make things behave -* nicely. Noone gets starved by default. -*/ - if ( inf->short_block_lost_tot <= 0 ) -#endif - { -/* We have (over-)compensated our block penalty */ - inf->short_block_lost_tot =0 ; -/* We don't want a place on the penalty queue anymore! */ - inf->status &= ~EXTRA_WANT_PEN_Q ; - goto check_extra_queues; - } - -/* -* We have to go again for another try in the block-extraq, -* the score is not used incremantally here, as this is -* already done by recalculating the block_lost -*/ - inf->score[EXTRA_PEN_Q ] = (inf->period <<10 ) / - inf->short_block_lost_tot; - oldscore =0 ; - } -else - { -/* -* Domain was running in L1 extraq => score is inverse of -* utilization and is used somewhat incremental! -*/ -if ( !inf->extraweight ) - { -/* NB: use fixed point arithmetic with 10 bits */ - inf->score[EXTRA_UTIL_Q ] = (inf->period <<10 ) / - inf->slice; - } -else - { -/* -* Conversion between realtime utilisation and extrawieght: -* full (ie 100%) utilization is equivalent to 128 extraweight -*/ - inf->score[EXTRA_UTIL_Q ] = (1 <<17 ) / inf->extraweight; - } - } - - check_extra_queues: -/* Adding a runnable domain to the right queue and removing blocked ones */ -if (sedf_runnable (d) ) - { -/* Add according to score: weighted round robin */ -if (((inf->status &EXTRA_AWARE ) && (i ==EXTRA_UTIL_Q )) || - ((inf->status &EXTRA_WANT_PEN_Q ) && (i ==EXTRA_PEN_Q ))) -extraq_add_sort_update (d, i, oldscore); - } -else - { -/* Remove this blocked domain from the waitq! */ -__del_from_queue (d); -/* Make sure that we remove a blocked domain from the other -* extraq too. */ -if ( i ==EXTRA_PEN_Q ) - { -if (extraq_on (d,EXTRA_UTIL_Q ) ) -extraq_del (d,EXTRA_UTIL_Q ); - } -else - { -if (extraq_on (d,EXTRA_PEN_Q ) ) -extraq_del (d,EXTRA_PEN_Q ); - } - } - -ASSERT (EQ (sedf_runnable (d),__task_on_queue (d))); -ASSERT (IMPLY (extraq_on (d,EXTRA_UTIL_Q ) ||extraq_on (d,EXTRA_PEN_Q ), -sedf_runnable (d))); -} - - -static struct task_slice sedf_do_extra_schedule ( -s_time_t now,s_time_t end_xt,struct list_head *extraq[],int cpu) -{ -struct task_slice ret = {0 }; -struct sedf_vcpu_info *runinf; -ASSERT (end_xt > now); - -/* Enough time left to use for extratime? */ -if ( end_xt - now <EXTRA_QUANTUM ) - goto return_idle; - -if ( !list_empty (extraq[EXTRA_PEN_Q ]) ) - { -/* -* We still have elements on the level 0 extraq -* => let those run first! -*/ - runinf =list_entry (extraq[EXTRA_PEN_Q ]->next, - struct sedf_vcpu_info, extralist[EXTRA_PEN_Q]); - runinf->status |=EXTRA_RUN_PEN ; - ret.task = runinf->vcpu; - ret.time =EXTRA_QUANTUM ; -#ifdef SEDF_STATS - runinf->pen_extra_slices++; -#endif - } -else - { -if ( !list_empty (extraq[EXTRA_UTIL_Q ]) ) - { -/* Use elements from the normal extraqueue */ - runinf =list_entry (extraq[EXTRA_UTIL_Q ]->next, - struct sedf_vcpu_info, - extralist[EXTRA_UTIL_Q ]); - runinf->status |=EXTRA_RUN_UTIL ; - ret.task = runinf->vcpu; - ret.time =EXTRA_QUANTUM ; - } -else - goto return_idle; - } - -ASSERT (ret.time >0 ); -ASSERT (sedf_runnable (ret.task)); -return ret; - - return_idle: - ret.task =IDLETASK (cpu); - ret.time = end_xt - now; -ASSERT (ret.time >0 ); -ASSERT (sedf_runnable (ret.task)); -return ret; -} - - -static int sedf_init (struct scheduler *ops) -{ -struct sedf_priv_info *prv; - - prv = xzalloc(struct sedf_priv_info); -if ( prv ==NULL ) -return -ENOMEM ; - - ops->sched_data = prv; -spin_lock_init (&prv->lock); - -return 0 ; -} - - -static void sedf_deinit (const struct scheduler *ops) -{ -struct sedf_priv_info *prv; - - prv =SEDF_PRIV (ops); -xfree (prv); -} - - -/* -* Main scheduling function -* Reasons for calling this function are: -* -timeslice for the current period used up -* -domain on waitqueue has started it's period -* -and various others ;) in general: determine which domain to run next -*/ -static struct task_slice sedf_do_schedule ( -const struct scheduler *ops,s_time_t now,bool_t tasklet_work_scheduled) -{ -int cpu =smp_processor_id (); -struct list_head *runq =RUNQ (cpu); -struct list_head *waitq =WAITQ (cpu); -struct sedf_vcpu_info *inf =EDOM_INFO (current); -struct list_head *extraq[] = { -EXTRAQ (cpu,EXTRA_PEN_Q ),EXTRAQ (cpu,EXTRA_UTIL_Q )}; -struct sedf_vcpu_info *runinf, *waitinf; -struct task_slice ret; - -SCHED_STAT_CRANK (schedule); - -/* Idle tasks don't need any of the following stuf */ -if (is_idle_vcpu (current) ) - goto check_waitq; - -/* -* Create local state of the status of the domain, in order to avoid -* inconsistent state during scheduling decisions, because data for -* vcpu_runnable is not protected by the scheduling lock! -*/ -if ( !vcpu_runnable (current) ) - inf->status |=SEDF_ASLEEP ; - -if ( inf->status &SEDF_ASLEEP ) - inf->block_abs = now; - -if (unlikely (extra_runs (inf)) ) - { -/* Special treatment of domains running in extra time */ -desched_extra_dom (now, current); - } -else - { -desched_edf_dom (now, current); - } - check_waitq: -update_queues (now, runq, waitq); - -/* -* Now simply pick the first domain from the runqueue, which has the -* earliest deadline, because the list is sorted -* -* Tasklet work (which runs in idle VCPU context) overrides all else. -*/ -if ( tasklet_work_scheduled || - (list_empty (runq) &&list_empty (waitq)) || -unlikely (!cpumask_test_cpu (cpu, -cpupool_online_cpumask (per_cpu (cpupool, cpu))) || -per_cpu (cpupool, cpu) ==NULL ) ) - { - ret.task =IDLETASK (cpu); - ret.time =SECONDS (1 ); - } -else if ( !list_empty (runq) ) - { - runinf = list_entry(runq->next,struct sedf_vcpu_info,list); - ret.task = runinf->vcpu; -if ( !list_empty (waitq) ) - { - waitinf =list_entry (waitq->next, - struct sedf_vcpu_info,list); -/* -* Rerun scheduler, when scheduled domain reaches it's -* end of slice or the first domain from the waitqueue -* gets ready. -*/ - ret.time =MIN (now + runinf->slice - runinf->cputime, -PERIOD_BEGIN (waitinf)) - now; - } -else - { - ret.time = runinf->slice - runinf->cputime; - } - } -else - { - waitinf = list_entry(waitq->next,struct sedf_vcpu_info, list); -/* -* We could not find any suitable domain -* => look for domains that are aware of extratime -*/ - ret =sedf_do_extra_schedule (now,PERIOD_BEGIN (waitinf), - extraq, cpu); - } - -/* -* TODO: Do something USEFUL when this happens and find out, why it -* still can happen!!! -*/ -if ( ret.time <0 ) - { -printk ("Ouch! We are seriously BEHIND schedule! %" PRIi64"\n" , - ret.time); - ret.time =EXTRA_QUANTUM ; - } - - ret.migrated =0 ; - -EDOM_INFO (ret.task)->sched_start_abs = now; -CHECK (ret.time >0 ); -ASSERT (sedf_runnable (ret.task)); -CPU_INFO (cpu)->current_slice_expires = now + ret.time; -return ret; -} - - -static void sedf_sleep (const struct scheduler *ops,struct vcpu *d) -{ -if (is_idle_vcpu (d) ) -return ; - -EDOM_INFO (d)->status |=SEDF_ASLEEP ; - -if (per_cpu (schedule_data, d->processor).curr == d ) - { -cpu_raise_softirq (d->processor,SCHEDULE_SOFTIRQ ); - } -else - { -if (__task_on_queue (d) ) -__del_from_queue (d); -if (extraq_on (d,EXTRA_UTIL_Q ) ) -extraq_del (d,EXTRA_UTIL_Q ); -if (extraq_on (d,EXTRA_PEN_Q ) ) -extraq_del (d,EXTRA_PEN_Q ); - } -} - - -/* -* This function wakes up a domain, i.e. moves them into the waitqueue -* things to mention are: admission control is taking place nowhere at -* the moment, so we can't be sure, whether it is safe to wake the domain -* up at all. Anyway, even if it is safe (total cpu usage <=100%) there are -* some considerations on when to allow the domain to wake up and have it's -* first deadline... -* I detected 3 cases, which could describe the possible behaviour of the -* scheduler, -* and I'll try to make them more clear: -* -* 1. Very conservative -* -when a blocked domain unblocks, it is allowed to start execution at -* the beginning of the next complete period -* (D..deadline, R..running, B..blocking/sleeping, U..unblocking/waking up -* -* DRRB_____D__U_____DRRRRR___D________ ... -* -* -this causes the domain to miss a period (and a deadlline) -* -doesn't disturb the schedule at all -* -deadlines keep occuring isochronous -* -* 2. Conservative Part 1: Short Unblocking -* -when a domain unblocks in the same period as it was blocked it -* unblocks and may consume the rest of it's original time-slice minus -* the time it was blocked -* (assume period=9, slice=5) -* -* DRB_UR___DRRRRR___D... -* -* -this also doesn't disturb scheduling, but might lead to the fact, that -* the domain can't finish it's workload in the period -* -in addition to that the domain can be treated prioritised when -* extratime is available -* -addition: experiments have shown that this may have a HUGE impact on -* performance of other domains, becaus it can lead to excessive context -* switches -* -* Part2: Long Unblocking -* Part 2a -* -it is obvious that such accounting of block time, applied when -* unblocking is happening in later periods, works fine aswell -* -the domain is treated as if it would have been running since the start -* of its new period -* -* DRB______D___UR___D... -* -* Part 2b -* -if one needs the full slice in the next period, it is necessary to -* treat the unblocking time as the start of the new period, i.e. move -* the deadline further back (later) -* -this doesn't disturb scheduling as well, because for EDF periods can -* be treated as minimal inter-release times and scheduling stays -* correct, when deadlines are kept relative to the time the process -* unblocks -* -* DRB______D___URRRR___D...<prev [Thread] next> -* (D) <- old deadline was here -* -problem: deadlines don't occur isochronous anymore -* Part 2c (Improved Atropos design) -* -when a domain unblocks it is given a very short period (=latency hint) -* and slice length scaled accordingly -* -both rise again to the original value (e.g. get doubled every period) -* -* 3. Unconservative (i.e. incorrect) -* -to boost the performance of I/O dependent domains it would be possible -* to put the domain into the runnable queue immediately, and let it run -* for the remainder of the slice of the current period -* (or even worse: allocate a new full slice for the domain) -* -either behaviour can lead to missed deadlines in other domains as -* opposed to approaches 1,2a,2b -*/ -static void unblock_short_extra_support ( -struct sedf_vcpu_info * inf,s_time_t now) -{ -/* -* This unblocking scheme tries to support the domain, by assigning it -* a priority in extratime distribution according to the loss of time -* in this slice due to blocking -*/ -s_time_t pen; - -/* No more realtime execution in this period! */ - inf->deadl_abs += inf->period; -if (likely (inf->block_abs) ) - { -/* Treat blocked time as consumed by the domain */ -/*inf->cputime += now - inf->block_abs;*/ -/* -* Penalty is time the domain would have -* had if it continued to run. -*/ - pen = (inf->slice - inf->cputime); -if ( pen <0 ) - pen =0 ; -/* Accumulate all penalties over the periods */ -/*inf->short_block_lost_tot += pen;*/ -/* Set penalty to the current value */ - inf->short_block_lost_tot = pen; -/* Not sure which one is better.. but seems to work well... */ - -if ( inf->short_block_lost_tot ) - { - inf->score[0 ] = (inf->period <<10 ) / - inf->short_block_lost_tot; -#ifdef SEDF_STATS - inf->pen_extra_blocks++; -#endif -if (extraq_on (inf->vcpu,EXTRA_PEN_Q ) ) -/* Remove domain for possible resorting! */ -extraq_del (inf->vcpu,EXTRA_PEN_Q ); -else -/* -* Remember that we want to be on the penalty q -* so that we can continue when we (un-)block -* in penalty-extratime -*/ - inf->status |=EXTRA_WANT_PEN_Q ; - -/* (re-)add domain to the penalty extraq */ -extraq_add_sort_update (inf->vcpu,EXTRA_PEN_Q ,0 ); - } - } - -/* Give it a fresh slice in the next period! */ - inf->cputime =0 ; -} - - -static void unblock_long_cons_b (struct sedf_vcpu_info * inf,s_time_t now) -{ -/* Conservative 2b */ - -/* Treat the unblocking time as a start of a new period */ - inf->deadl_abs = now + inf->period; - inf->cputime =0 ; -} - - -#define DOMAIN_EDF 1 -#define DOMAIN_EXTRA_PEN 2 -#define DOMAIN_EXTRA_UTIL 3 -#define DOMAIN_IDLE 4 -static inline int get_run_type (struct vcpu * d) -{ -struct sedf_vcpu_info * inf =EDOM_INFO (d); -if (is_idle_vcpu (d)) -return DOMAIN_IDLE ; -if (inf->status &EXTRA_RUN_PEN ) -return DOMAIN_EXTRA_PEN ; -if (inf->status &EXTRA_RUN_UTIL ) -return DOMAIN_EXTRA_UTIL ; -return DOMAIN_EDF ; -} - - -/* -* Compares two domains in the relation of whether the one is allowed to -* interrupt the others execution. -* It returns true (!=0) if a switch to the other domain is good. -* Current Priority scheme is as follows: -* EDF > L0 (penalty based) extra-time > -* L1 (utilization) extra-time > idle-domain -* In the same class priorities are assigned as following: -* EDF: early deadline > late deadline -* L0 extra-time: lower score > higher score -*/ -static inline int should_switch (struct vcpu *cur, -struct vcpu *other, -s_time_t now) -{ -struct sedf_vcpu_info *cur_inf, *other_inf; - cur_inf =EDOM_INFO (cur); - other_inf =EDOM_INFO (other); - -/* Check whether we need to make an earlier scheduling decision */ -if (PERIOD_BEGIN (other_inf) < -CPU_INFO (other->processor)->current_slice_expires ) -return 1 ; - -/* No timing-based switches need to be taken into account here */ -switch (get_run_type (cur) ) - { -case DOMAIN_EDF : -/* Do not interrupt a running EDF domain */ -return 0 ; -case DOMAIN_EXTRA_PEN : -/* Check whether we also want the L0 ex-q with lower score */ -return ((other_inf->status &EXTRA_WANT_PEN_Q ) && - (other_inf->score[EXTRA_PEN_Q ] < - cur_inf->score[EXTRA_PEN_Q ])); -case DOMAIN_EXTRA_UTIL : -/* Check whether we want the L0 extraq. Don't -* switch if both domains want L1 extraq. */ -return !!(other_inf->status &EXTRA_WANT_PEN_Q ); -case DOMAIN_IDLE : -return 1 ; - } - -return 1 ; -} - -static void sedf_wake (const struct scheduler *ops,struct vcpu *d) -{ -s_time_t now =NOW (); -struct sedf_vcpu_info * inf =EDOM_INFO (d); - -if (unlikely (is_idle_vcpu (d)) ) -return ; - -if (unlikely (__task_on_queue (d)) ) -return ; - -ASSERT (!sedf_runnable (d)); - inf->status &= ~SEDF_ASLEEP ; -ASSERT (!extraq_on (d,EXTRA_UTIL_Q )); -ASSERT (!extraq_on (d,EXTRA_PEN_Q )); - -if (unlikely (inf->deadl_abs ==0 ) ) - { -/* Initial setup of the deadline */ - inf->deadl_abs = now + inf->slice; - } - -#ifdef SEDF_STATS - inf->block_tot++; -#endif - -if (unlikely (now <PERIOD_BEGIN (inf)) ) - { -/* Unblocking in extra-time! */ -if ( inf->status &EXTRA_WANT_PEN_Q ) - { -/* -* We have a domain that wants compensation -* for block penalty and did just block in -* its compensation time. Give it another -* chance! -*/ -extraq_add_sort_update (d,EXTRA_PEN_Q ,0 ); - } -extraq_check_add_unblocked (d,0 ); - } -else - { -if ( now < inf->deadl_abs ) - { -/* Short blocking */ -#ifdef SEDF_STATS - inf->short_block_tot++; -#endif -unblock_short_extra_support (inf, now); - -extraq_check_add_unblocked (d,1 ); - } -else - { -/* Long unblocking */ -#ifdef SEDF_STATS - inf->long_block_tot++; -#endif -unblock_long_cons_b (inf, now); - -extraq_check_add_unblocked (d,1 ); - } - } - -if (PERIOD_BEGIN (inf) > now ) -__add_to_waitqueue_sort (d); -else -__add_to_runqueue_sort (d); - -#ifdef SEDF_STATS -/* Do some statistics here... */ -if ( inf->block_abs !=0 ) - { - inf->block_time_tot += now - inf->block_abs; - inf->penalty_time_tot += -PERIOD_BEGIN (inf) + inf->cputime - inf->block_abs; - } -#endif - -/* Sanity check: make sure each extra-aware domain IS on the util-q! */ -ASSERT (IMPLY (inf->status &EXTRA_AWARE ,extraq_on (d,EXTRA_UTIL_Q ))); -ASSERT (__task_on_queue (d)); -/* -* Check whether the awakened task needs to invoke the do_schedule -* routine. Try to avoid unnecessary runs but: -* Save approximation: Always switch to scheduler! -*/ -ASSERT (d->processor >=0 ); -ASSERT (d->processor < nr_cpu_ids); -ASSERT (per_cpu (schedule_data, d->processor).curr); - -if (should_switch (per_cpu (schedule_data, d->processor).curr, d, now) ) -cpu_raise_softirq (d->processor,SCHEDULE_SOFTIRQ ); -} - - -/* Print a lot of useful information about a domains in the system */ -static void sedf_dump_domain (struct vcpu *d) -{ -printk ("%i.%i has=%c " , d->domain->domain_id, d->vcpu_id, - d->is_running ?'T' :'F' ); -printk ("p=%" PRIu64" sl=%" PRIu64" ddl=%" PRIu64" w=%hu" -" sc=%i xtr(%s)=%" PRIu64" ew=%hu" , -EDOM_INFO (d)->period,EDOM_INFO (d)->slice,EDOM_INFO (d)->deadl_abs, -EDOM_INFO (d)->weight, -EDOM_INFO (d)->score[EXTRA_UTIL_Q ], - (EDOM_INFO (d)->status &EXTRA_AWARE ) ?"yes" :"no" , -EDOM_INFO (d)->extra_time_tot,EDOM_INFO (d)->extraweight); - -#ifdef SEDF_STATS -if (EDOM_INFO (d)->block_time_tot !=0 ) -printk (" pen=%" PRIu64"%%" , (EDOM_INFO (d)->penalty_time_tot *100 ) / -EDOM_INFO (d)->block_time_tot); -if (EDOM_INFO (d)->block_tot !=0 ) -printk ("\n blks=%u sh=%u (%u%%) (shex=%i " \ -"shexsl=%i) l=%u (%u%%) avg: b=%" PRIu64" p=%" PRIu64"" , -EDOM_INFO (d)->block_tot,EDOM_INFO (d)->short_block_tot, - (EDOM_INFO (d)->short_block_tot *100 ) /EDOM_INFO (d)->block_tot, -EDOM_INFO (d)->pen_extra_blocks, -EDOM_INFO (d)->pen_extra_slices, -EDOM_INFO (d)->long_block_tot, - (EDOM_INFO (d)->long_block_tot *100 ) /EDOM_INFO (d)->block_tot, - (EDOM_INFO (d)->block_time_tot) /EDOM_INFO (d)->block_tot, - (EDOM_INFO (d)->penalty_time_tot) /EDOM_INFO (d)->block_tot); -#endif -printk ("\n" ); -} - - -/* Dumps all domains on the specified cpu */ -static void sedf_dump_cpu_state (const struct scheduler *ops,int i) -{ -struct sedf_priv_info *prv =SEDF_PRIV (ops); -struct list_head *list, *queue, *tmp; -struct sedf_vcpu_info *d_inf; -struct domain *d; -struct vcpu *ed; -spinlock_t *lock; -unsigned long flags; -int loop =0 ; - -/* -* We need both locks, as: -* - we access domains' parameters, which are protected by the -* private scheduler lock; -* - we scan through the various queues, so we need the proper -* runqueue lock (i.e., the one for this pCPU). -*/ -spin_lock_irqsave (&prv->lock, flags); - lock =pcpu_schedule_lock (i); - -printk ("now=%" PRIu64"\n" ,NOW ()); - queue =RUNQ (i); -printk ("RUNQ rq %lx n: %lx, p: %lx\n" , (unsigned long )queue, - (unsigned long ) queue->next, (unsigned long ) queue->prev); - list_for_each_safe ( list, tmp, queue ) - { -printk ("%3d: " ,loop++); - d_inf = list_entry(list, struct sedf_vcpu_info, list); -sedf_dump_domain (d_inf->vcpu); - } - - queue =WAITQ (i); loop =0 ; -printk ("\nWAITQ rq %lx n: %lx, p: %lx\n" , (unsigned long )queue, - (unsigned long ) queue->next, (unsigned long ) queue->prev); - list_for_each_safe ( list, tmp, queue ) - { -printk ("%3d: " ,loop++); - d_inf = list_entry(list, struct sedf_vcpu_info, list); -sedf_dump_domain (d_inf->vcpu); - } - - queue =EXTRAQ (i,EXTRA_PEN_Q ); loop =0 ; -printk ("\nEXTRAQ (penalty) rq %lx n: %lx, p: %lx\n" , - (unsigned long )queue, (unsigned long ) queue->next, - (unsigned long ) queue->prev); - list_for_each_safe ( list, tmp, queue ) - { - d_inf = list_entry(list, struct sedf_vcpu_info, - extralist[EXTRA_PEN_Q ]); -printk ("%3d: " ,loop++); -sedf_dump_domain (d_inf->vcpu); - } - - queue =EXTRAQ (i,EXTRA_UTIL_Q ); loop =0 ; -printk ("\nEXTRAQ (utilization) rq %lx n: %lx, p: %lx\n" , - (unsigned long )queue, (unsigned long ) queue->next, - (unsigned long ) queue->prev); - list_for_each_safe ( list, tmp, queue ) - { - d_inf = list_entry(list, struct sedf_vcpu_info, - extralist[EXTRA_UTIL_Q ]); -printk ("%3d: " ,loop++); -sedf_dump_domain (d_inf->vcpu); - } - - loop =0 ; -printk ("\nnot on Q\n" ); - -rcu_read_lock (&domlist_read_lock); -for_each_domain ( d ) - { -if ( (d->cpupool ? d->cpupool->sched : &sched_sedf_def) != ops ) -continue ; -for_each_vcpu (d, ed) - { -if ( !__task_on_queue (ed) && (ed->processor == i) ) - { -printk ("%3d: " ,loop++); -sedf_dump_domain (ed); - } - } - } -rcu_read_unlock (&domlist_read_lock); - -pcpu_schedule_unlock (lock, i); -spin_unlock_irqrestore (&prv->lock, flags); -} - - -/* Adjusts periods and slices of the domains accordingly to their weights */ -static int sedf_adjust_weights (struct cpupool *c,int nr_cpus,int *sumw,s_time_t *sumt) -{ -struct vcpu *p; -struct domain *d; -unsigned int cpu; - -/* -* Sum across all weights. Notice that no runq locking is needed -* here: the caller holds sedf_priv_info.lock and we're not changing -* anything that is accessed during scheduling. -*/ -rcu_read_lock (&domlist_read_lock); -for_each_domain_in_cpupool ( d, c ) - { -for_each_vcpu ( d, p ) - { -if ( (cpu = p->processor) >= nr_cpus ) -continue ; - -if (EDOM_INFO (p)->weight ) - { - sumw[cpu] +=EDOM_INFO (p)->weight; - } -else - { -/* -* Don't modify domains who don't have a weight, but sum -* up the time they need, projected to a WEIGHT_PERIOD, -* so that this time is not given to the weight-driven -* domains -*/ - -/* Check for overflows */ -ASSERT ((WEIGHT_PERIOD <ULONG_MAX ) - && (EDOM_INFO (p)->slice_orig <ULONG_MAX )); - sumt[cpu] += - (WEIGHT_PERIOD *EDOM_INFO (p)->slice_orig) / -EDOM_INFO (p)->period_orig; - } - } - } -rcu_read_unlock (&domlist_read_lock); - -/* -* Adjust all slices (and periods) to the new weight. Unlike above, we -* need to take thr runq lock for the various VCPUs: we're modyfing -* slice and period which are referenced during scheduling. -*/ -rcu_read_lock (&domlist_read_lock); -for_each_domain_in_cpupool ( d, c ) - { - for_each_vcpu ( d, p ) - { -if ( (cpu = p->processor) >= nr_cpus ) -continue ; -if (EDOM_INFO (p)->weight ) - { -/* Interrupts already off */ -spinlock_t *lock =vcpu_schedule_lock (p); - -EDOM_INFO (p)->period_orig = -EDOM_INFO (p)->period =WEIGHT_PERIOD ; -EDOM_INFO (p)->slice_orig = -EDOM_INFO (p)->slice = - (EDOM_INFO (p)->weight * - (WEIGHT_PERIOD -WEIGHT_SAFETY - sumt[cpu])) / sumw[cpu]; - -vcpu_schedule_unlock (lock, p); - } - } - } -rcu_read_unlock (&domlist_read_lock); - -return 0 ; -} - - -/* Set or fetch domain scheduling parameters */ -static int sedf_adjust (const struct scheduler *ops,struct domain *p,struct xen_domctl_scheduler_op *op) -{ -struct sedf_priv_info *prv =SEDF_PRIV (ops); -unsigned long flags; -unsigned int nr_cpus =cpumask_last (&cpu_online_map) +1 ; -int *sumw =xzalloc_array (int, nr_cpus); -s_time_t *sumt =xzalloc_array (s_time_t, nr_cpus); -struct vcpu *v; -int rc =0 ; - -/* -* Serialize against the pluggable scheduler lock to protect from -* concurrent updates. We need to take the runq lock for the VCPUs -* as well, since we are touching extraweight, weight, slice and -* period. As in sched_credit2.c, runq locks nest inside the -* pluggable scheduler lock. -*/ -spin_lock_irqsave (&prv->lock, flags); - -if ( op->cmd == XEN_DOMCTL_SCHEDOP_putinfo ) - { -/* -* These are used in sedf_adjust_weights() but have to be allocated in -* this function, as we need to avoid nesting xmem_pool_alloc's lock -* within our prv->lock. -*/ -if ( !sumw || !sumt ) - { -/* Check for errors here, the _getinfo branch doesn't care */ - rc = -ENOMEM ; - goto out; - } - -/* Check for sane parameters */ -if ( !op->u.sedf.period && !op->u.sedf.weight ) - { - rc = -EINVAL ; - goto out; - } - -if ( op->u.sedf.weight ) - { -if ( (op->u.sedf.extratime &EXTRA_AWARE ) && - (!op->u.sedf.period) ) - { -/* Weight-driven domains with extratime only */ - for_each_vcpu ( p, v ) - { -/* (Here and everywhere in the following) IRQs are already off, -* hence vcpu_spin_lock() is the one. */ -spinlock_t *lock =vcpu_schedule_lock (v); - -EDOM_INFO (v)->extraweight = op->u.sedf.weight; -EDOM_INFO (v)->weight =0 ; -EDOM_INFO (v)->slice =0 ; -EDOM_INFO (v)->period =WEIGHT_PERIOD ; -vcpu_schedule_unlock (lock, v); - } - } -else - { -/* Weight-driven domains with real-time execution */ - for_each_vcpu ( p, v ) - { -spinlock_t *lock =vcpu_schedule_lock (v); - -EDOM_INFO (v)->weight = op->u.sedf.weight; -vcpu_schedule_unlock (lock, v); - } - } - } -else - { -/* -* Sanity checking: note that disabling extra weight requires -* that we set a non-zero slice. -*/ -if ( (op->u.sedf.period >PERIOD_MAX ) || - (op->u.sedf.period <PERIOD_MIN ) || - (op->u.sedf.slice > op->u.sedf.period) || - (op->u.sedf.slice <SLICE_MIN ) ) - { - rc = -EINVAL ; - goto out; - } - -/* Time-driven domains */ - for_each_vcpu ( p, v ) - { -spinlock_t *lock =vcpu_schedule_lock (v); - -EDOM_INFO (v)->weight =0 ; -EDOM_INFO (v)->extraweight =0 ; -EDOM_INFO (v)->period_orig = -EDOM_INFO (v)->period = op->u.sedf.period; -EDOM_INFO (v)->slice_orig = -EDOM_INFO (v)->slice = op->u.sedf.slice; -vcpu_schedule_unlock (lock, v); - } - } - - rc =sedf_adjust_weights (p->cpupool, nr_cpus, sumw, sumt); -if ( rc ) - goto out; - - for_each_vcpu ( p, v ) - { -spinlock_t *lock =vcpu_schedule_lock (v); - -EDOM_INFO (v)->status = - (EDOM_INFO (v)->status & - ~EXTRA_AWARE ) | (op->u.sedf.extratime &EXTRA_AWARE ); -EDOM_INFO (v)->latency = op->u.sedf.latency; -extraq_check (v); -vcpu_schedule_unlock (lock, v); - } - } -else if ( op->cmd == XEN_DOMCTL_SCHEDOP_getinfo ) - { -if ( p->vcpu[0 ] ==NULL ) - { - rc = -EINVAL ; - goto out; - } - - op->u.sedf.period =EDOM_INFO (p->vcpu[0 ])->period; - op->u.sedf.slice =EDOM_INFO (p->vcpu[0 ])->slice; - op->u.sedf.extratime =EDOM_INFO (p->vcpu[0 ])->status &EXTRA_AWARE ; - op->u.sedf.latency =EDOM_INFO (p->vcpu[0 ])->latency; - op->u.sedf.weight =EDOM_INFO (p->vcpu[0 ])->weight; - } - -out: -spin_unlock_irqrestore (&prv->lock, flags); - -xfree (sumt); -xfree (sumw); - -return rc; -} - -static struct sedf_priv_info _sedf_priv; - -const struct scheduler sched_sedf_def = { - .name ="Simple EDF Scheduler" , - .opt_name ="sedf" , - .sched_id =XEN_SCHEDULER_SEDF , - .sched_data = &_sedf_priv, - - .init_domain = sedf_init_domain, - .destroy_domain = sedf_destroy_domain, - - .insert_vcpu = sedf_insert_vcpu, - - .alloc_vdata = sedf_alloc_vdata, - .free_vdata = sedf_free_vdata, - .alloc_pdata = sedf_alloc_pdata, - .free_pdata = sedf_free_pdata, - .alloc_domdata = sedf_alloc_domdata, - .free_domdata = sedf_free_domdata, - - .init = sedf_init, - .deinit = sedf_deinit, - - .do_schedule = sedf_do_schedule, - .pick_cpu = sedf_pick_cpu, - .dump_cpu_state = sedf_dump_cpu_state, - .sleep = sedf_sleep, - .wake = sedf_wake, - .adjust = sedf_adjust, -}; - -/* -* Local variables: -* mode: C -* c-file-style: "BSD" -* c-basic-offset: 4 -* tab-width: 4 -* indent-tabs-mode: nil -* End: -*/
PATCH v4 6/7 xl: get rid of the SEDF scheduler
In reply to Dario Faggioli---
Cc: Ian Jackson <[email protected]>
Cc: Stefano Stabellini <[email protected]>
Cc: Wei Liu <[email protected]>
--- docs/man/xl.cfg.pod.5 | 24 -------- docs/man/xl.pod.1 | 42 -------------- tools/libxl/xl.h | 1 tools/libxl/xl_cmdimpl.c | 139 --------------------------------------------- tools/libxl/xl_cmdtable.c | 16 ----- 5 files changed, 1 insertion(+), 221 deletions(-)
docs/man/xl.cfg.pod.5 +1 -23
@@ -198,7 +198,7 @@ For more details, see F<docs/misc/xl-numa-placement.markdown>. A domain with a weight of 512 will get twice as much CPU as a domain with a weight of 256 on a contended host. Legal weights range from 1 to 65535 and the default is 256. -Honoured by the credit, credit2 and sedf schedulers. +Honoured by the credit and credit2 schedulers. =item B<cap=N>
@@ -222,28 +222,6 @@ that your VM gets 25% of the available power (50% of 1GHz) rather than look at performance and cpufreq options in your operating system and your BIOS. -=item B<period=NANOSECONDS> - -The normal EDF scheduling usage in nanoseconds. This means every period -the domain gets cpu time defined in slice. -Honoured by the sedf scheduler. - -=item B<slice=NANOSECONDS> - -The normal EDF scheduling usage in nanoseconds. it defines the time -a domain get every period time. -Honoured by the sedf scheduler. - -=item B<latency=N> - -Scaled period if domain is doing heavy I/O. -Honoured by the sedf scheduler. - -=item B<extratime=BOOLEAN> - -Flag for allowing domain to run in extra time. -Honoured by the sedf scheduler. - =back =head3 Memory Allocation
docs/man/xl.pod.1 +0 -42
48 lines not on this page · raw message
tools/libxl/xl.h +0 -1
@@ -66,7 +66,6 @@ int main_memmax(int argc, char **argv);int main_memset (int argc,char **argv);int main_sched_credit (int argc,char **argv);int main_sched_credit2 (int argc,char **argv); -int main_sched_sedf (int argc,char **argv);int main_sched_rtds (int argc,char **argv);int main_domid (int argc,char **argv);int main_domname (int argc,char **argv);
tools/libxl/xl_cmdimpl.c +0 -139
151 lines not on this page · raw message
tools/libxl/xl_cmdtable.c +0 -16
@@ -265,22 +265,6 @@ struct cmd_spec cmd_table[] = {"-w WEIGHT, --weight=WEIGHT Weight (int)\n" "-p CPUPOOL, --cpupool=CPUPOOL Restrict output to CPUPOOL" }, - { "sched-sedf", - &main_sched_sedf,0 ,1 , -"Get/set sedf scheduler parameters" , -"[options]" , -"-d DOMAIN, --domain=DOMAIN Domain to modify\n" -"-p MS, --period=MS Relative deadline(ms)\n" -"-s MS, --slice=MS Worst-case execution time(ms).\n" -" (slice < period)\n" -"-l MS, --latency=MS Scaled period (ms) when domain\n" -" performs heavy I/O\n" -"-e FLAG, --extra=FLAG Flag (0 or 1) controls if domain\n" -" can run in extra time\n" -"-w FLOAT, --weight=FLOAT CPU Period/slice (do not set with\n" -" --period/--slice)\n" -"-c CPUPOOL, --cpupool=CPUPOOL Restrict output to CPUPOOL" - }, { "sched-rtds", &main_sched_rtds,0 ,1 , "Get/set rtds scheduler parameters",
PATCH v4 7/7 docs: get rid of the SEDF scheduler
In reply to Dario Faggioli---
Cc: Ian Jackson <[email protected]>
Cc: Stefano Stabellini <[email protected]>
Cc: Wei Liu <[email protected]>
--- docs/INDEX | 1 - docs/man/xlcpupool.cfg.pod.5 | 4 --- docs/misc/sedf_scheduler_mini-HOWTO.txt | 44 ------------------------------- tools/examples/cpupool | 2 + 4 files changed, 1 insertion(+), 50 deletions(-) delete mode 100644 docs/misc/sedf_scheduler_mini-HOWTO.txt
docs/INDEX +0 -1
@@ -20,7 +20,6 @@ misc/xl-disk-configuration XL Disk Configuration misc/xl-network-configuration XL Network Configuration misc/distro_mapping Distro Directory Layouts misc/dump-core-format Xen Core Dump Format -misc/sedf_scheduler_mini-HOWTO sEDF Mini HOWTO misc/vtd VT-d HOWTO misc/vtpm Virtual TPM misc/xen-error-handling Xen Error Handling
docs/man/xlcpupool.cfg.pod.5 +0 -4
@@ -78,10 +78,6 @@ the credit2 scheduler the RTDS scheduler -=item B<sedf> - -the SEDF scheduler - =back The default scheduler is the one used for C<Pool-0> specified as
docs/misc/sedf_scheduler_mini-HOWTO.txt deleted +0 -44
44 lines not on this page · raw message
tools/examples/cpupool +1 -1
@@ -9,7 +9,7 @@ # the name of the new cpupool name = "Example-Cpupool" -# the scheduler to use: valid are e.g. credit, credit2, rtds and sedf +# the scheduler to use: valid are e.g. credit, credit2 and rtds sched = "credit" # list of cpus to use