[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 14/14] libxl: build a device tree for ARM guests
Ian Campbell writes ("[PATCH v3 14/14] libxl: build a device tree for ARM guests"): > Uses xc_dom_devicetree_mem which was just added. The call to this needs to be > carefully sequenced to be after xc_dom_parse_image (so we can tell which kind > of guest we are building, although we don't use this yet) and before > xc_dom_mem_init which tries to decide where to place the FDT in guest RAM. ... > diff --git a/tools/libxl/libxl_arch.h b/tools/libxl/libxl_arch.h > index abe6685..3de2d76 100644 > --- a/tools/libxl/libxl_arch.h > +++ b/tools/libxl/libxl_arch.h > @@ -19,4 +19,8 @@ > int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config, > uint32_t domid); > > +/* */ > +int libxl__arch_domain_configure(libxl__gc *gc, > + libxl_domain_build_info *info, > + struct xc_dom_image *dom); Missing content for comment ? Or maybe the comment just wants to go. > +typedef uint32_t __be32; > +typedef __be32 gic_interrupt_t[3]; Identifiers starting with __, and ones ending _t, are reserved for the C implementation. > +static void set_cell(__be32 **cellp, int size, uint64_t val) > +{ > + int cells = size; > + > + while ( size-- ) The spaces inside ( ) aren't expected inside libxl. > +static int make_memory_node(libxl__gc *gc, void *fdt, > + unsigned long long base, > + unsigned long long size) > +{ > + int res; > + char name[strlen("memory@") + 8 + 1]; > + > + snprintf(name, sizeof(name), "memory@%08llx", base); Why not use GCSPRINTF ? > +/* > + * Call "call" handling FDR_ERR_*. Will either: > + * - loop back to retry_resize > + * - set rc and goto out > + * - fall through successfully > + * > + * On FDT_ERR_NOSPACE we start again from scratch rather than > + * realloc+libfdt_open_into because "call" may have failed half way > + * through a series of steps leaving the partial tree in an > + * inconsistent state, e.g. leaving a node open. > + */ > +#define FDT( call ) do { \ > + int fdt_res = (call); \ > + if (fdt_res == -FDT_ERR_NOSPACE && fdt_size < FDT_MAX_SIZE) \ > + goto retry_resize; \ > + else if (fdt_res < 0) { \ > + LOG(ERROR, "FDT: %s failed: %d = %s", \ > + #call, fdt_res, fdt_strerror(fdt_res)); \ > + rc = ERROR_FAIL; \ > + goto out; \ > + } \ > +} while(0) My preference would be for this to be defined inside libxl__arch_domain_configure and #undef'd at the end, so as to limit the scope of the implicit reference to the label retry_resize. > +int libxl__arch_domain_configure(libxl__gc *gc, > + libxl_domain_build_info *info, > + struct xc_dom_image *dom) > +{ > + void *fdt; > + int rc, res, fd; > + size_t fdt_size = 0; > + > + const libxl_version_info *vers; > + const struct arch_info *ainfo; > + > + assert(info->type == LIBXL_DOMAIN_TYPE_PV); > + > + vers = libxl_get_version_info(CTX); > + if (vers == NULL) return ERROR_FAIL; > + > + ainfo = get_arch_info(gc, dom); > + if (ainfo == NULL) return ERROR_FAIL; > + > + LOG(DEBUG, "constructing DTB for Xen version %d.%d guest", > + vers->xen_version_major, vers->xen_version_minor); > + > +retry_resize: For form's sake, how about making this an explicit loop ? e.g. for (;;) { next_resize:; blah blah if (something) goto next_resize; Then the end of the loop would be more obvious. You'd have to write "break". (And you can #undef FDT at the end of the loop rather than the end of the function, as the label becomes semantically void after the end of the loop.) (If C had labelled loops you could do for resize (;;) { blah blah next resize; but it doesn't. Emulating this with goto is a lot nicer IMO than the naked goto.) > + if (fdt_size) { > + fdt_size <<= 1; > + LOG(DEBUG, "Increasing FDT size to %zd and retrying", fdt_size); > + } else { > + fdt_size = 4096; > + } Can we rule out this loop getting out of control ? > +#ifndef NDEBUG Please don't key off NDEBUG. libxl ought never to be compiled with NDEBUG. I don't see why you can't just have this code present all the time. > + if ( getenv("LIBXL_DEBUG_DUMP_DTB") ) { > + const char *dtb = getenv("LIBXL_DEBUG_DUMP_DTB"); > + > + fd = open(dtb, O_CREAT|O_TRUNC|O_WRONLY, 0666); > + if ( fd < 0 ) { > + LOGE(DEBUG, "cannot open %s for LIBXL_DEBUG_DUMP_DTB", dtb); > + goto no_debug_dump; This construction with "goto" is pretty ugly. Perhaps if you made the whole thing a separate function it would be less so. > + } > + > + rc = libxl_write_exactly(CTX, fd, fdt, fdt_totalsize(fdt), > + dtb, "dtb"); > + if ( rc < 0 ) { > + LOG(DEBUG, "unable to write DTB debug dump output %d", rc); > + goto no_debug_dump; For example, if you had made it a separate function with the "goto out" error handling style you wouldn't leak fd in this particular error case :-). (Also, no spaces inside ( ) in ifs, please.) > diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c > index 10f976c..6351ebd 100644 > --- a/tools/libxl/libxl_dom.c > +++ b/tools/libxl/libxl_dom.c > @@ -400,6 +400,10 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid, > LOGE(ERROR, "xc_dom_parse_image failed"); > goto out; > } > + if ( (ret = libxl__arch_domain_configure(gc, info, dom)) != 0 ) { > + LOGE(ERROR, "libxl__arch_domain_configure failed"); > + goto out; > + } > if ( (ret = xc_dom_mem_init(dom, info->target_memkb / 1024)) != 0 ) { > LOGE(ERROR, "xc_dom_mem_init failed"); > goto out; The style in this function is anomalous: * spaces inside ( ) * use of if ((ret = blah) !=0 ) which hides the meat in the if and has !=0 clobber, instead of rc = blah; if (rc) goto out; * use of "ret" for a libxl error code, rather than rc. But I won't insist on you fixing it. Adding an extra occurrence is probably better than having one call which is different to all the others. Thanks, Ian. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |