[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [RFC PATCH] tools/libxl : add struct and parsing utils for the 'static_shm' xl config entry



On Thu, 20 Jul 2017, Zhongze Liu wrote:
> >>  #endif /* LIBXL_H */
> >> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> >> index 8a9849c643..8c68b45add 100644
> >> --- a/tools/libxl/libxl_types.idl
> >> +++ b/tools/libxl/libxl_types.idl
> >> @@ -779,6 +779,57 @@ libxl_device_channel = Struct("device_channel", [
> >>             ])),
> >>  ])
> >>
> >> +# static shared memory cacheability attributes
> >> +libxl_sshm_cacheattr = Enumeration("sshm_cacheattr", [
> >> +    (-1, "UNKNOWN"),
> >> +    (0, "UC"),
> >> +    (1, "WC"),          #x86 only
> >> +    (4, "WT"),
> >> +    (5, "WP"),          #x86 only
> >> +    (6, "WB"),
> >> +    (7, "SUC"),         #x86 only
> >> +    (8, "BUFFERABLE"),  #ARM only
> >> +    (9, "WA"),          #ARM only
> >> +    ], init_val = "LIBXL_SSHM_CACHEATTR_UNKNOWN")
> >
> > I would only specify UNKNOWN and WB for now.
> 
> For here and below, I actually want to left the checks for 'not
> implemented' errors
> to later stages of handling. The typical call flow of xl is like below:
> 
> xl --> libxlu_* --> xl --> libxl_* --> hypercalls
> 
> I was planning to check for options that are not implemented currently
> in the libxl_*.

Why? You can print out "not implemented" for anything that is not "WB",
right?


> >> +# static shared memory shareability attributes
> >> +libxl_sshm_shareattr = Enumeration("sshm_shareattr", [
> >> +    (-1, "UNKNOWN"),
> >> +    (0, "NON"),
> >> +    (2, "OUTER"),
> >> +    (3, "INNER"),
> >> +    ], init_val = "LIBXL_SSHM_SHAREATTR_UNKNOWN")
> >> +
> >> +libxl_sshm_prot = Enumeration("sshm_prot", [
> >> +    (-1, "UNKNOWN"),
> >> +    (0, "N"),
> >> +    (1, "R"),
> >> +    (2, "W"),
> >> +    (4, "X"),
> >> +    (3, "RW"),
> >> +    (5, "RX"),
> >> +    (6, "WX"),
> >> +    (7, "RWX"),
> >> +    ], init_val = "LIBXL_SSHM_PROT_UNKNOWN")
> >> +
> >> +libxl_sshm_role = Enumeration("sshm_role", [
> >> +    (-1, "UNKNOWN"),
> >> +    (0, "MASTER"),
> >> +    (1, "SLAVE"),
> >> +    ], init_val = "LIBXL_SSHM_ROLE_UNKNOWN")
> >> +
> >> +libxl_static_shm = Struct("static_shm", [
> >> +    ("id", string),
> >> +    ("begin", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
> >> +    ("end", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
> >> +    ("prot", libxl_sshm_prot),
> >> +    ("arm_shareattr", libxl_sshm_shareattr),
> >> +    ("arm_inner_cacheattr", libxl_sshm_cacheattr),
> >> +    ("arm_outer_cacheattr", libxl_sshm_cacheattr),
> >
> > I would have a single arm_cacheattr
> 
> Why? Am I supposed to use a '|' to combine inner and outer cacheattrs ?

Because the cacheattr are the same no matter the inner or outer setting.
I don't see why we should have two different keys (arm_inner_cacheattr
and arm_outer_cacheattr) instead of only one.


> >
> >
> >> +    ("x86_cacheattr", libxl_sshm_cacheattr),
> >> +    ("role", libxl_sshm_role),
> >> +])
> >> +
> >>  libxl_domain_config = Struct("domain_config", [
> >>      ("c_info", libxl_domain_create_info),
> >>      ("b_info", libxl_domain_build_info),
> >> @@ -797,6 +848,7 @@ libxl_domain_config = Struct("domain_config", [
> >>      ("channels", Array(libxl_device_channel, "num_channels")),
> >>      ("usbctrls", Array(libxl_device_usbctrl, "num_usbctrls")),
> >>      ("usbdevs", Array(libxl_device_usbdev, "num_usbdevs")),
> >> +    ("sshms", Array(libxl_static_shm, "num_sshms")),
> >>
> >>      ("on_poweroff", libxl_action_on_shutdown),
> >>      ("on_reboot", libxl_action_on_shutdown),
> >> diff --git a/tools/libxl/libxlu_sshm.c b/tools/libxl/libxlu_sshm.c
> >> new file mode 100644
> >> index 0000000000..fcd65af4d9
> >> --- /dev/null
> >> +++ b/tools/libxl/libxlu_sshm.c
> >> @@ -0,0 +1,274 @@
> >> +#include "libxl_osdeps.h" /* must come before any other headers */
> >> +#include "libxlu_internal.h"
> >> +
> >> +#include <ctype.h>
> >> +
> >> +#define PARAM_RE(EXPR) "^\\s*" EXPR "\\s*(,|$)"
> >> +#define KEY_RE         "([_a-zA-Z0-9]+)"
> >> +#define VAL_RE         "([^ \t\n,]+)"
> >> +#define EQU_RE         PARAM_RE(KEY_RE "\\s*=\\s*" VAL_RE)
> >> +
> >> +#define MASK_4K        ((uint64_t)0xfff)
> >> +#define MAX_ID_LEN     128
> >> +#define CACHEATTR_ARM  0
> >> +#define CACHEATTR_X86  1
> >> +
> >> +#define INVAL_ERR(msg, curr_str)  do {              \
> >> +        xlu__sshm_err(cfg, msg, curr_str);          \
> >> +        rc = EINVAL;                                \
> >> +        goto out;                                   \
> >> +    } while(0)
> >> +
> >> +/* set a member in libxl_static_shm and report an error if it's 
> >> respecified,
> >> + * @curr_str indicates the head of the remaining string. */
> >> +#define SET_VAL(var, name, type, value, curr_str)  do {                 \
> >> +        if ((var) != LIBXL_SSHM_##type##_UNKNOWN && (var) != value) {   \
> >> +            INVAL_ERR("\"" name "\" respecified", curr_str);            \
> >> +        }                                                               \
> >> +        (var) = value;                                                  \
> >> +    } while(0)
> >> +
> >> +
> >> +static void xlu__sshm_err(XLU_Config *cfg, const char *msg,
> >> +                          const char *curr_str) {
> >> +    fprintf(cfg->report,
> >> +            "%s: config parsing error in shared_memory: %s at '%s'\n",
> >> +            cfg->config_source, msg, curr_str);
> >> +}
> >> +
> >> +static int parse_prot(XLU_Config *cfg, char *str, libxl_sshm_prot *prot)
> >> +{
> >> +    int rc;
> >> +    libxl_sshm_prot new_prot;
> >> +
> >> +    if (!strcmp(str, "r") || !strcmp(str, "ro")) {
> >> +        new_prot = LIBXL_SSHM_PROT_R;
> >> +    } else if (!strcmp(str, "w") || !strcmp(str, "wo")) {
> >> +        new_prot = LIBXL_SSHM_PROT_W;
> >> +    } else if (!strcmp(str, "x") || !strcmp(str, "xo")) {
> >> +        new_prot = LIBXL_SSHM_PROT_X;
> >> +    } else if (!strcmp(str, "rw")) {
> >> +        new_prot = LIBXL_SSHM_PROT_RW;
> >> +    } else if (!strcmp(str, "rx")) {
> >> +        new_prot = LIBXL_SSHM_PROT_RX;
> >> +    } else if (!strcmp(str, "wx")) {
> >> +        new_prot = LIBXL_SSHM_PROT_WX;
> >> +    } else if (!strcmp(str, "rwx")) {
> >> +        new_prot = LIBXL_SSHM_PROT_RWX;
> >> +    } else if (!strcmp(str, "n")) {
> >> +        new_prot = LIBXL_SSHM_PROT_N;
> >> +    } else {
> >> +        INVAL_ERR("invalid permission flags", str);
> >
> > shouldn't this return an error?
> 
> This macro does return an error. but it seems that the naming is not
> very appropriate. may I should change it to RET_INVAL or something?

Ops, sorry! I didn't realize INVAL_ERR sets rc and even calls goto! I'll
leave this to the tools maintainer, but I wouldn't want to have a macro,
which looks like it's just setting an error message, also do a goto.


> >
> >
> >> +    }
> >> +
> >> +    SET_VAL(*prot, "permission flags", PROT, new_prot, str);
> >> +
> >> +    rc = 0;
> >> +
> >> + out:
> >> +    return rc;
> >> +}
> >> +
> >> +static int parse_cacheattr(XLU_Config *cfg, char *str, int arch,
> >> +                           libxl_sshm_cacheattr *cattr)
> >> +{
> >> +    int rc;
> >> +    libxl_sshm_cacheattr new_cattr;
> >> +
> >> +    if (!strcmp(str, "uc")) {
> >> +        new_cattr = LIBXL_SSHM_CACHEATTR_UC;
> >> +    } else if (!strcmp(str, "wc")) {
> >> +        if (CACHEATTR_X86 != arch) {
> >> +            INVAL_ERR("invalid cacheability attribute", str);
> >> +        }
> >> +        new_cattr = LIBXL_SSHM_CACHEATTR_WC;
> >> +    } else if (!strcmp(str, "wt")) {
> >> +        new_cattr = LIBXL_SSHM_CACHEATTR_WT;
> >> +    } else if (!strcmp(str, "wp")) {
> >> +        if (CACHEATTR_X86 != arch) {
> >> +            INVAL_ERR("invalid cacheability attribute", str);
> >> +        }
> >> +        new_cattr = LIBXL_SSHM_CACHEATTR_WP;
> >> +    } else if (!strcmp(str, "wb")) {
> >> +        new_cattr = LIBXL_SSHM_CACHEATTR_WB;
> >> +    } else if (!strcmp(str, "suc")) {
> >> +        if (CACHEATTR_X86 != arch) {
> >> +            INVAL_ERR("invalid cacheability attribute", str);
> >> +        }
> >> +        new_cattr = LIBXL_SSHM_CACHEATTR_SUC;
> >> +    } else if (!strcmp(str, "bufferable")) {
> >> +        if (CACHEATTR_ARM != arch) {
> >> +            INVAL_ERR("invalid cacheability attribute", str);
> >> +        }
> >> +        new_cattr = LIBXL_SSHM_CACHEATTR_BUFFERABLE;
> >> +    } else if (!strcmp(str, "wa")) {
> >> +        if (CACHEATTR_ARM != arch) {
> >> +            INVAL_ERR("invalid cacheability attribute", str);
> >> +        }
> >> +        new_cattr = LIBXL_SSHM_CACHEATTR_WA;
> >> +    } else {
> >> +        INVAL_ERR("invalid cacheability attribute", str);
> >
> > shouldn't this return an error?
> >
> >
> >> +    }
> >
> > I don't know if the other maintainers agree, but I think we should just
> > check that str is "wb" and fail in all other cases.
> 
> Just as pointed out above, I prefer to implement all the options in this part
> of the code, since parsing and actual handling are two somewhat independent
> parts. The checks for options that are not implemented could be left to later
> stages.

It's important that we check now for what is implemented and return
error for anything that is not implemented. How we do that is less
important. However, given that we might change our minds about what
should be the options in the future, I would prefer to only handle
explicitly the one option we intend to implement now.

That said, I would probably wait for a second opinion from one of the
tools maintainers.

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.