Message ID | 20191128135813.8893-1-pdurrant@amazon.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [PATCH-for-4.13,v4] Rationalize max_grant_frames and max_maptrack_frames handling | expand |
On 28.11.2019 14:58, Paul Durrant wrote: > --- a/xen/common/grant_table.c > +++ b/xen/common/grant_table.c > @@ -84,11 +84,43 @@ struct grant_table { > struct grant_table_arch arch; > }; > > +static int __init parse_gnttab_limit(const char *param, const char *arg, No __init please here and below, for this being runtime option parsing functions. > + unsigned int *valp) > +{ > + const char *e; > + unsigned long val; > + > + val = simple_strtoul(arg, &e, 0); > + if ( *e ) > + return -EINVAL; > + > + if ( val <= INT_MAX ) > + *valp = val; > + else > + printk("parameter \"%s\" value \"%s\" is out of range; using value \"%u\"\n", > + param, arg, *valp); Better store INT_MAX in this case rather than leaving the value unchanged? Or otherwise ... > + return 0; ... at least don't return success? > +} > + > unsigned int __read_mostly opt_max_grant_frames = 64; > -integer_runtime_param("gnttab_max_frames", opt_max_grant_frames); > + > +static int __init parse_gnttab_max_frames(const char *arg) > +{ > + return parse_gnttab_limit("gnttab_max_frames", arg, > + &opt_max_grant_frames); > +} > +custom_runtime_param("gnttab_max_frames", parse_gnttab_max_frames); > > unsigned int __read_mostly opt_max_maptrack_frames = 1024; As indicated this wants to become static now. > --- a/xen/include/public/domctl.h > +++ b/xen/include/public/domctl.h > @@ -82,13 +82,15 @@ struct xen_domctl_createdomain { > uint32_t iommu_opts; > > /* > - * Various domain limits, which impact the quantity of resources (global > - * mapping space, xenheap, etc) a guest may consume. > + * Various domain limits, which impact the quantity of resources > + * (global mapping space, xenheap, etc) a guest may consume. For > + * max_grant_frames and max_maptrack_frames, < 0 means "use the > + * default maximum value in the hypervisor". > */ > uint32_t max_vcpus; > uint32_t max_evtchn_port; > - uint32_t max_grant_frames; > - uint32_t max_maptrack_frames; > + int32_t max_grant_frames; > + int32_t max_maptrack_frames; While this may want backporting aiui, we need to be a little careful with the interface change here. Jan
Jan Beulich writes ("Re: [PATCH-for-4.13 v4] Rationalize max_grant_frames and max_maptrack_frames handling"): > On 28.11.2019 14:58, Paul Durrant wrote: > > uint32_t max_vcpus; > > uint32_t max_evtchn_port; > > - uint32_t max_grant_frames; > > - uint32_t max_maptrack_frames; > > + int32_t max_grant_frames; > > + int32_t max_maptrack_frames; > > While this may want backporting aiui, we need to be a little > careful with the interface change here. A note here in a list discussion, or even in a commit message, is perhaps not going to be very effective to deal with this. How bad would it be to change the names as well as the types ? Ian.
> -----Original Message----- > From: Jan Beulich <jbeulich@suse.com> > Sent: 28 November 2019 16:37 > To: Durrant, Paul <pdurrant@amazon.com> > Cc: xen-devel@lists.xenproject.org; Andrew Cooper > <andrew.cooper3@citrix.com>; Anthony PERARD <anthony.perard@citrix.com>; > George Dunlap <george.dunlap@citrix.com>; Roger Pau Monné > <roger.pau@citrix.com>; Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>; > George Dunlap <George.Dunlap@eu.citrix.com>; Ian Jackson > <ian.jackson@eu.citrix.com>; Marek Marczykowski-Górecki > <marmarek@invisiblethingslab.com>; Stefano Stabellini > <sstabellini@kernel.org>; Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>; > Julien Grall <julien@xen.org>; Wei Liu <wl@xen.org> > Subject: Re: [PATCH-for-4.13 v4] Rationalize max_grant_frames and > max_maptrack_frames handling > > On 28.11.2019 14:58, Paul Durrant wrote: > > --- a/xen/common/grant_table.c > > +++ b/xen/common/grant_table.c > > @@ -84,11 +84,43 @@ struct grant_table { > > struct grant_table_arch arch; > > }; > > > > +static int __init parse_gnttab_limit(const char *param, const char > *arg, > > No __init please here and below, for this being runtime option > parsing functions. > Sorry, yes... forgot about the runtime part. > > + unsigned int *valp) > > +{ > > + const char *e; > > + unsigned long val; > > + > > + val = simple_strtoul(arg, &e, 0); > > + if ( *e ) > > + return -EINVAL; > > + > > + if ( val <= INT_MAX ) > > + *valp = val; > > + else > > + printk("parameter \"%s\" value \"%s\" is out of range; using > value \"%u\"\n", > > + param, arg, *valp); > > Better store INT_MAX in this case rather than leaving the value > unchanged? Or otherwise ... > > > + return 0; > > ... at least don't return success? TBH I wasn't sure what the best thing to do was. In the end I opted for the warning and a successful completion as I thought a failure would be largely unhelpful. I can change this into an error though. > > > +} > > + > > unsigned int __read_mostly opt_max_grant_frames = 64; > > -integer_runtime_param("gnttab_max_frames", opt_max_grant_frames); > > + > > +static int __init parse_gnttab_max_frames(const char *arg) > > +{ > > + return parse_gnttab_limit("gnttab_max_frames", arg, > > + &opt_max_grant_frames); > > +} > > +custom_runtime_param("gnttab_max_frames", parse_gnttab_max_frames); > > > > unsigned int __read_mostly opt_max_maptrack_frames = 1024; > > As indicated this wants to become static now. Sorry I forgot about that. Paul
On 28.11.19 17:36, Jan Beulich wrote: > On 28.11.2019 14:58, Paul Durrant wrote: >> --- a/xen/common/grant_table.c >> +++ b/xen/common/grant_table.c >> @@ -84,11 +84,43 @@ struct grant_table { >> struct grant_table_arch arch; >> }; >> >> +static int __init parse_gnttab_limit(const char *param, const char *arg, > > No __init please here and below, for this being runtime option > parsing functions. > >> + unsigned int *valp) >> +{ >> + const char *e; >> + unsigned long val; >> + >> + val = simple_strtoul(arg, &e, 0); >> + if ( *e ) >> + return -EINVAL; >> + >> + if ( val <= INT_MAX ) >> + *valp = val; >> + else >> + printk("parameter \"%s\" value \"%s\" is out of range; using value \"%u\"\n", >> + param, arg, *valp); > > Better store INT_MAX in this case rather than leaving the value No, INT_MAX is no good idea. In case of this happening at boot time we'd allocate an array of 2 billion pointers for dom0... Juergen
On 28.11.2019 17:42, Durrant, Paul wrote: >> From: Jan Beulich <jbeulich@suse.com> >> Sent: 28 November 2019 16:37 >> >> On 28.11.2019 14:58, Paul Durrant wrote: >>> + val = simple_strtoul(arg, &e, 0); >>> + if ( *e ) >>> + return -EINVAL; >>> + >>> + if ( val <= INT_MAX ) >>> + *valp = val; >>> + else >>> + printk("parameter \"%s\" value \"%s\" is out of range; using >> value \"%u\"\n", >>> + param, arg, *valp); >> >> Better store INT_MAX in this case rather than leaving the value >> unchanged? Or otherwise ... >> >>> + return 0; >> >> ... at least don't return success? > > TBH I wasn't sure what the best thing to do was. In the end I opted > for the warning and a successful completion as I thought a failure > would be largely unhelpful. I can change this into an error though. Well, if you return success, then the option should be handled in at least a best effort manner, i.e. by storing INT_MAX as indicated. Jan
On 28.11.2019 17:47, Jürgen Groß wrote: > On 28.11.19 17:36, Jan Beulich wrote: >> On 28.11.2019 14:58, Paul Durrant wrote: >>> --- a/xen/common/grant_table.c >>> +++ b/xen/common/grant_table.c >>> @@ -84,11 +84,43 @@ struct grant_table { >>> struct grant_table_arch arch; >>> }; >>> >>> +static int __init parse_gnttab_limit(const char *param, const char *arg, >> >> No __init please here and below, for this being runtime option >> parsing functions. >> >>> + unsigned int *valp) >>> +{ >>> + const char *e; >>> + unsigned long val; >>> + >>> + val = simple_strtoul(arg, &e, 0); >>> + if ( *e ) >>> + return -EINVAL; >>> + >>> + if ( val <= INT_MAX ) >>> + *valp = val; >>> + else >>> + printk("parameter \"%s\" value \"%s\" is out of range; using value \"%u\"\n", >>> + param, arg, *valp); >> >> Better store INT_MAX in this case rather than leaving the value > > No, INT_MAX is no good idea. In case of this happening at boot time we'd > allocate an array of 2 billion pointers for dom0... But we've been asked for even more. We should let the admin shoot itself in the foot, I think. Jan
On 28.11.2019 17:42, Ian Jackson wrote: > Jan Beulich writes ("Re: [PATCH-for-4.13 v4] Rationalize max_grant_frames and max_maptrack_frames handling"): >> On 28.11.2019 14:58, Paul Durrant wrote: >>> uint32_t max_vcpus; >>> uint32_t max_evtchn_port; >>> - uint32_t max_grant_frames; >>> - uint32_t max_maptrack_frames; >>> + int32_t max_grant_frames; >>> + int32_t max_maptrack_frames; >> >> While this may want backporting aiui, we need to be a little >> careful with the interface change here. > > A note here in a list discussion, or even in a commit message, is > perhaps not going to be very effective to deal with this. > > How bad would it be to change the names as well as the types ? Hmm, not sure - on one hand this would flag the issue to people consuming the interface. Otoh it wouldn't help people using derived header files (they'd notice far later), and causing breakage like this in stable trees does't look very friendly either. Jan
diff --git a/docs/man/xl.conf.5.pod b/docs/man/xl.conf.5.pod index 962144e38e..207ab3e77a 100644 --- a/docs/man/xl.conf.5.pod +++ b/docs/man/xl.conf.5.pod @@ -81,13 +81,15 @@ Default: C</var/lock/xl> Sets the default value for the C<max_grant_frames> domain config value. -Default: C<32> on hosts up to 16TB of memory, C<64> on hosts larger than 16TB +Default: value of Xen command line B<gnttab_max_frames> parameter (or its +default value if unspecified). =item B<max_maptrack_frames=NUMBER> Sets the default value for the C<max_maptrack_frames> domain config value. -Default: C<1024> +Default: value of Xen command line B<gnttab_max_maptrack_frames> +parameter (or its default value if unspecified). =item B<vif.default.script="PATH"> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index 49b56fa1a3..a2a5d321c5 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -364,8 +364,8 @@ */ #define LIBXL_HAVE_BUILDINFO_GRANT_LIMITS 1 -#define LIBXL_MAX_GRANT_FRAMES_DEFAULT 32 -#define LIBXL_MAX_MAPTRACK_FRAMES_DEFAULT 1024 +#define LIBXL_MAX_GRANT_FRAMES_DEFAULT -1 +#define LIBXL_MAX_MAPTRACK_FRAMES_DEFAULT -1 /* * LIBXL_HAVE_BUILDINFO_* indicates that libxl_domain_build_info has diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index 0546d7865a..63e29bb2fb 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -511,8 +511,8 @@ libxl_domain_build_info = Struct("domain_build_info",[ ("vnuma_nodes", Array(libxl_vnode_info, "num_vnuma_nodes")), - ("max_grant_frames", uint32, {'init_val': 'LIBXL_MAX_GRANT_FRAMES_DEFAULT'}), - ("max_maptrack_frames", uint32, {'init_val': 'LIBXL_MAX_MAPTRACK_FRAMES_DEFAULT'}), + ("max_grant_frames", integer, {'init_val': 'LIBXL_MAX_GRANT_FRAMES_DEFAULT'}), + ("max_maptrack_frames", integer, {'init_val': 'LIBXL_MAX_MAPTRACK_FRAMES_DEFAULT'}), ("device_model_version", libxl_device_model_version), ("device_model_stubdomain", libxl_defbool), diff --git a/tools/libxl/libxlu_cfg.c b/tools/libxl/libxlu_cfg.c index 72815d25dd..cafc632fc1 100644 --- a/tools/libxl/libxlu_cfg.c +++ b/tools/libxl/libxlu_cfg.c @@ -268,8 +268,9 @@ int xlu_cfg_replace_string(const XLU_Config *cfg, const char *n, return 0; } -int xlu_cfg_get_long(const XLU_Config *cfg, const char *n, - long *value_r, int dont_warn) { +int xlu_cfg_get_bounded_long(const XLU_Config *cfg, const char *n, + long min, long max, long *value_r, + int dont_warn) { long l; XLU_ConfigSetting *set; int e; @@ -303,10 +304,31 @@ int xlu_cfg_get_long(const XLU_Config *cfg, const char *n, cfg->config_source, set->lineno, n); return EINVAL; } + if (l < min) { + if (!dont_warn) + fprintf(cfg->report, + "%s:%d: warning: value `%ld' is smaller than minimum bound '%ld'\n", + cfg->config_source, set->lineno, l, min); + return EINVAL; + } + if (l > max) { + if (!dont_warn) + fprintf(cfg->report, + "%s:%d: warning: value `%ld' is greater than maximum bound '%ld'\n", + cfg->config_source, set->lineno, l, max); + return EINVAL; + } + *value_r= l; return 0; } +int xlu_cfg_get_long(const XLU_Config *cfg, const char *n, + long *value_r, int dont_warn) { + return xlu_cfg_get_bounded_long(cfg, n, LONG_MIN, LONG_MAX, value_r, + dont_warn); +} + int xlu_cfg_get_defbool(const XLU_Config *cfg, const char *n, libxl_defbool *b, int dont_warn) { diff --git a/tools/libxl/libxlutil.h b/tools/libxl/libxlutil.h index 057cc25cb2..92e35c5462 100644 --- a/tools/libxl/libxlutil.h +++ b/tools/libxl/libxlutil.h @@ -63,6 +63,8 @@ int xlu_cfg_replace_string(const XLU_Config *cfg, const char *n, char **value_r, int dont_warn); int xlu_cfg_get_long(const XLU_Config*, const char *n, long *value_r, int dont_warn); +int xlu_cfg_get_bounded_long(const XLU_Config*, const char *n, long min, + long max, long *value_r, int dont_warn); int xlu_cfg_get_defbool(const XLU_Config*, const char *n, libxl_defbool *b, int dont_warn); diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 44d3606141..a751e85910 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -127,8 +127,8 @@ static PyObject *pyxc_domain_create(XcObject *self, }, .max_vcpus = 1, .max_evtchn_port = -1, /* No limit. */ - .max_grant_frames = 32, - .max_maptrack_frames = 1024, + .max_grant_frames = -1, + .max_maptrack_frames = -1, }; static char *kwd_list[] = { "domid", "ssidref", "handle", "flags", diff --git a/tools/xl/xl.c b/tools/xl/xl.c index ddd29b3f1b..921c64f5ed 100644 --- a/tools/xl/xl.c +++ b/tools/xl/xl.c @@ -23,6 +23,7 @@ #include <ctype.h> #include <inttypes.h> #include <regex.h> +#include <limits.h> #include <libxl.h> #include <libxl_utils.h> @@ -96,7 +97,6 @@ static void parse_global_config(const char *configfile, XLU_Config *config; int e; const char *buf; - libxl_physinfo physinfo; config = xlu_cfg_init(stderr, configfile); if (!config) { @@ -197,16 +197,11 @@ static void parse_global_config(const char *configfile, xlu_cfg_replace_string (config, "colo.default.proxyscript", &default_colo_proxy_script, 0); - if (!xlu_cfg_get_long (config, "max_grant_frames", &l, 0)) + if (!xlu_cfg_get_bounded_long (config, "max_grant_frames", 0, INT_MAX, + &l, 0)) max_grant_frames = l; - else { - libxl_physinfo_init(&physinfo); - max_grant_frames = (libxl_get_physinfo(ctx, &physinfo) != 0 || - !(physinfo.max_possible_mfn >> 32)) - ? 32 : 64; - libxl_physinfo_dispose(&physinfo); - } - if (!xlu_cfg_get_long (config, "max_maptrack_frames", &l, 0)) + if (!xlu_cfg_get_bounded_long (config, "max_maptrack_frames", 0, + INT_MAX, &l, 0)) max_maptrack_frames = l; libxl_cpu_bitmap_alloc(ctx, &global_vm_affinity_mask, 0); diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index 112f8ee026..555991dae3 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -1411,13 +1411,16 @@ void parse_config_data(const char *config_source, !xlu_cfg_get_string (config, "cpus_soft", &buf, 0)) parse_vcpu_affinity(b_info, cpus, buf, num_cpus, false); - if (!xlu_cfg_get_long (config, "max_grant_frames", &l, 0)) + if (!xlu_cfg_get_bounded_long (config, "max_grant_frames", 0, INT_MAX, + &l, 0)) b_info->max_grant_frames = l; else b_info->max_grant_frames = max_grant_frames; - if (!xlu_cfg_get_long (config, "max_maptrack_frames", &l, 0)) + + if (!xlu_cfg_get_bounded_long (config, "max_maptrack_frames", 0, + INT_MAX, &l, 0)) b_info->max_maptrack_frames = l; - else if (max_maptrack_frames != -1) + else b_info->max_maptrack_frames = max_maptrack_frames; libxl_defbool_set(&b_info->claim_mode, claim_mode); diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 51d32106b7..3c899cd4a0 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -789,7 +789,7 @@ void __init start_xen(unsigned long boot_phys_offset, .flags = XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap, .max_evtchn_port = -1, .max_grant_frames = gnttab_dom0_frames(), - .max_maptrack_frames = opt_max_maptrack_frames, + .max_maptrack_frames = -1, }; int rc; diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 00ee87bde5..7d27f36053 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -697,8 +697,8 @@ void __init noreturn __start_xen(unsigned long mbi_p) struct xen_domctl_createdomain dom0_cfg = { .flags = IS_ENABLED(CONFIG_TBOOT) ? XEN_DOMCTL_CDF_s3_integrity : 0, .max_evtchn_port = -1, - .max_grant_frames = opt_max_grant_frames, - .max_maptrack_frames = opt_max_maptrack_frames, + .max_grant_frames = -1, + .max_maptrack_frames = -1, }; /* Critical region without IDT or TSS. Any fault is deadly! */ diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index b34d520f6d..c5d4201223 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -84,11 +84,43 @@ struct grant_table { struct grant_table_arch arch; }; +static int __init parse_gnttab_limit(const char *param, const char *arg, + unsigned int *valp) +{ + const char *e; + unsigned long val; + + val = simple_strtoul(arg, &e, 0); + if ( *e ) + return -EINVAL; + + if ( val <= INT_MAX ) + *valp = val; + else + printk("parameter \"%s\" value \"%s\" is out of range; using value \"%u\"\n", + param, arg, *valp); + + return 0; +} + unsigned int __read_mostly opt_max_grant_frames = 64; -integer_runtime_param("gnttab_max_frames", opt_max_grant_frames); + +static int __init parse_gnttab_max_frames(const char *arg) +{ + return parse_gnttab_limit("gnttab_max_frames", arg, + &opt_max_grant_frames); +} +custom_runtime_param("gnttab_max_frames", parse_gnttab_max_frames); unsigned int __read_mostly opt_max_maptrack_frames = 1024; -integer_runtime_param("gnttab_max_maptrack_frames", opt_max_maptrack_frames); + +static int __init parse_gnttab_max_maptrack_frames(const char *arg) +{ + return parse_gnttab_limit("gnttab_max_maptrack_frames", arg, + &opt_max_maptrack_frames); +} +custom_runtime_param("gnttab_max_maptrack_frames", + parse_gnttab_max_maptrack_frames); #ifndef GNTTAB_MAX_VERSION #define GNTTAB_MAX_VERSION 2 @@ -1837,12 +1869,18 @@ active_alloc_failed: return -ENOMEM; } -int grant_table_init(struct domain *d, unsigned int max_grant_frames, - unsigned int max_maptrack_frames) +int grant_table_init(struct domain *d, int max_grant_frames, + int max_maptrack_frames) { struct grant_table *gt; int ret = -ENOMEM; + /* Default to maximum value if no value was specified */ + if ( max_grant_frames < 0 ) + max_grant_frames = opt_max_grant_frames; + if ( max_maptrack_frames < 0 ) + max_maptrack_frames = opt_max_maptrack_frames; + if ( max_grant_frames < INITIAL_NR_GRANT_FRAMES || max_grant_frames > opt_max_grant_frames || max_maptrack_frames > opt_max_maptrack_frames ) diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 9f2cfd602c..e313da499f 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -82,13 +82,15 @@ struct xen_domctl_createdomain { uint32_t iommu_opts; /* - * Various domain limits, which impact the quantity of resources (global - * mapping space, xenheap, etc) a guest may consume. + * Various domain limits, which impact the quantity of resources + * (global mapping space, xenheap, etc) a guest may consume. For + * max_grant_frames and max_maptrack_frames, < 0 means "use the + * default maximum value in the hypervisor". */ uint32_t max_vcpus; uint32_t max_evtchn_port; - uint32_t max_grant_frames; - uint32_t max_maptrack_frames; + int32_t max_grant_frames; + int32_t max_maptrack_frames; struct xen_arch_domainconfig arch; }; diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h index 6f9345d9ef..34886bb6f8 100644 --- a/xen/include/xen/grant_table.h +++ b/xen/include/xen/grant_table.h @@ -36,8 +36,8 @@ extern unsigned int opt_max_grant_frames; extern unsigned int opt_max_maptrack_frames; /* Create/destroy per-domain grant table context. */ -int grant_table_init(struct domain *d, unsigned int max_grant_frames, - unsigned int max_maptrack_frames); +int grant_table_init(struct domain *d, int max_grant_frames, + int max_maptrack_frames); void grant_table_destroy( struct domain *d); void grant_table_init_vcpu(struct vcpu *v); @@ -68,8 +68,8 @@ int gnttab_get_status_frame(struct domain *d, unsigned long idx, #define opt_max_maptrack_frames 0 static inline int grant_table_init(struct domain *d, - unsigned int max_grant_frames, - unsigned int max_maptrack_frames) + int max_grant_frames, + int max_maptrack_frames) { return 0; }