This patch parses to enable user configurable parameters to specify RDM resource and according policies which are defined previously,
Global RDM parameter: rdm = "strategy=host,policy=strict/relaxed" Per-device RDM parameter: pci = [ 'sbdf, rdm_policy=strict/relaxed' ] Default per-device RDM policy is same as default global RDM policy as being 'relaxed'. And the per-device policy would override the global policy like others. CC: Ian Jackson <ian.jack...@eu.citrix.com> CC: Stefano Stabellini <stefano.stabell...@eu.citrix.com> CC: Ian Campbell <ian.campb...@citrix.com> CC: Wei Liu <wei.l...@citrix.com> Acked-by: Wei Liu <wei.l...@citrix.com> Signed-off-by: Tiejun Chen <tiejun.c...@intel.com> --- v9 ~ v11: * Nothing is changed. v8: * Clean some codes style issues. v7: * Just sync with the fallout of renaming parameters from patch #10. v6: * Just sync those renames introduced by patch #10. v5: * Need a rebase after we make all rdm variables specific to .hvm. * Like other pci option, the per-device policy always follows the global policy by default. v4: * Separated from current patch #11 to parse/enable our rdm policy parameters since its make a lot sense and these stuffs are specific to xl/libxlu. tools/libxl/libxlu_pci.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++- tools/libxl/libxlutil.h | 4 +++ tools/libxl/xl_cmdimpl.c | 13 +++++++ 3 files changed, 108 insertions(+), 1 deletion(-) diff --git a/tools/libxl/libxlu_pci.c b/tools/libxl/libxlu_pci.c index 26fb143..026413b 100644 --- a/tools/libxl/libxlu_pci.c +++ b/tools/libxl/libxlu_pci.c @@ -42,6 +42,9 @@ static int pcidev_struct_fill(libxl_device_pci *pcidev, unsigned int domain, #define STATE_OPTIONS_K 6 #define STATE_OPTIONS_V 7 #define STATE_TERMINAL 8 +#define STATE_TYPE 9 +#define STATE_RDM_STRATEGY 10 +#define STATE_RESERVE_POLICY 11 int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str) { unsigned state = STATE_DOMAIN; @@ -143,7 +146,18 @@ int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str pcidev->permissive = atoi(tok); }else if ( !strcmp(optkey, "seize") ) { pcidev->seize = atoi(tok); - }else{ + } else if (!strcmp(optkey, "rdm_policy")) { + if (!strcmp(tok, "strict")) { + pcidev->rdm_policy = LIBXL_RDM_RESERVE_POLICY_STRICT; + } else if (!strcmp(tok, "relaxed")) { + pcidev->rdm_policy = LIBXL_RDM_RESERVE_POLICY_RELAXED; + } else { + XLU__PCI_ERR(cfg, "%s is not an valid PCI RDM property" + " policy: 'strict' or 'relaxed'.", + tok); + goto parse_error; + } + } else { XLU__PCI_ERR(cfg, "Unknown PCI BDF option: %s", optkey); } tok = ptr + 1; @@ -167,6 +181,82 @@ parse_error: return ERROR_INVAL; } +int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str) +{ + unsigned state = STATE_TYPE; + char *buf2, *tok, *ptr, *end; + + if (NULL == (buf2 = ptr = strdup(str))) + return ERROR_NOMEM; + + for (tok = ptr, end = ptr + strlen(ptr) + 1; ptr < end; ptr++) { + switch(state) { + case STATE_TYPE: + if (*ptr == '=') { + state = STATE_RDM_STRATEGY; + *ptr = '\0'; + if (strcmp(tok, "strategy")) { + XLU__PCI_ERR(cfg, "Unknown RDM state option: %s", tok); + goto parse_error; + } + tok = ptr + 1; + } + break; + case STATE_RDM_STRATEGY: + if (*ptr == '\0' || *ptr == ',') { + state = STATE_RESERVE_POLICY; + *ptr = '\0'; + if (!strcmp(tok, "host")) { + rdm->strategy = LIBXL_RDM_RESERVE_STRATEGY_HOST; + } else { + XLU__PCI_ERR(cfg, "Unknown RDM strategy option: %s", tok); + goto parse_error; + } + tok = ptr + 1; + } + break; + case STATE_RESERVE_POLICY: + if (*ptr == '=') { + state = STATE_OPTIONS_V; + *ptr = '\0'; + if (strcmp(tok, "policy")) { + XLU__PCI_ERR(cfg, "Unknown RDM property value: %s", tok); + goto parse_error; + } + tok = ptr + 1; + } + break; + case STATE_OPTIONS_V: + if (*ptr == ',' || *ptr == '\0') { + state = STATE_TERMINAL; + *ptr = '\0'; + if (!strcmp(tok, "strict")) { + rdm->policy = LIBXL_RDM_RESERVE_POLICY_STRICT; + } else if (!strcmp(tok, "relaxed")) { + rdm->policy = LIBXL_RDM_RESERVE_POLICY_RELAXED; + } else { + XLU__PCI_ERR(cfg, "Unknown RDM property policy value: %s", + tok); + goto parse_error; + } + tok = ptr + 1; + } + default: + break; + } + } + + free(buf2); + + if (tok != ptr || state != STATE_TERMINAL) + goto parse_error; + + return 0; + +parse_error: + return ERROR_INVAL; +} + /* * Local variables: * mode: C diff --git a/tools/libxl/libxlutil.h b/tools/libxl/libxlutil.h index 989605a..e81b644 100644 --- a/tools/libxl/libxlutil.h +++ b/tools/libxl/libxlutil.h @@ -106,6 +106,10 @@ int xlu_disk_parse(XLU_Config *cfg, int nspecs, const char *const *specs, */ int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str); +/* + * RDM parsing + */ +int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str); /* * Vif rate parsing. diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 615b78b..d102439 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -1980,6 +1980,14 @@ skip_vfb: xlu_cfg_get_defbool(config, "e820_host", &b_info->u.pv.e820_host, 0); } + if (!xlu_cfg_get_string(config, "rdm", &buf, 0)) { + libxl_rdm_reserve rdm; + if (!xlu_rdm_parse(config, &rdm, buf)) { + b_info->u.hvm.rdm.strategy = rdm.strategy; + b_info->u.hvm.rdm.policy = rdm.policy; + } + } + if (!xlu_cfg_get_list (config, "pci", &pcis, 0, 0)) { d_config->num_pcidevs = 0; d_config->pcidevs = NULL; @@ -1993,6 +2001,11 @@ skip_vfb: pcidev->power_mgmt = pci_power_mgmt; pcidev->permissive = pci_permissive; pcidev->seize = pci_seize; + /* + * Like other pci option, the per-device policy always follows + * the global policy by default. + */ + pcidev->rdm_policy = b_info->u.hvm.rdm.policy; e = xlu_pci_parse_bdf(config, pcidev, buf); if (e) { fprintf(stderr, -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel