[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v12 1/3] xen/domain: unify domain ID allocation
On Wed Jul 30, 2025 at 5:34 AM CEST, dmkhn wrote: > From: Denis Mukhin <dmukhin@xxxxxxxx> > > Currently, there are two different domain ID allocation implementations: > > 1) Sequential IDs allocation in dom0less Arm code based on max_init_domid; > > 2) Sequential IDs allocation in XEN_DOMCTL_createdomain; does not use > max_init_domid (both Arm and x86). > > The domain ID allocation covers dom0 or late hwdom, predefined domains, > post-boot domains, excluding Xen system domains (domid >= > DOMID_FIRST_RESERVED). > > It makes sense to have a common helper code for such task across architectures > (Arm and x86) and between dom0less / toolstack domU allocation. > > Note, fixing dependency on max_init_domid is out of scope of this patch. > > Wrap the domain ID allocation as an arch-independent function domid_alloc() in > new common/domid.c based on the bitmap. > > Allocation algorithm: > - If an explicit domain ID is provided, verify its availability and use it if > ID is not used; > - If DOMID_INVALID is provided, search the range [1..DOMID_FIRST_RESERVED-1], > starting from the last used ID. IDs are not wrapped around in dom0less case. > Implementation guarantees that two consecutive calls will never return the > same ID. ID#0 is reserved for the first boot domain (currently, dom0) and > excluded from the allocation range. > > Remove is_free_domid() helper as it is not needed now. > > No functional change intended. > > Signed-off-by: Denis Mukhin <dmukhin@xxxxxxxx> > --- > Changes since v11: > - fixed commentaries > - dropped cf_check for new calls > - dropped ifdef-ry from domid_alloc(), max_init_domid check in create_domUs() > preserved > - added ASSERT() to domid_free() > --- > xen/arch/arm/domain_build.c | 7 +- > xen/arch/x86/setup.c | 7 +- > xen/common/Makefile | 1 + > xen/common/device-tree/dom0less-build.c | 15 ++-- > xen/common/domain.c | 2 + > xen/common/domctl.c | 42 ++--------- > xen/common/domid.c | 94 +++++++++++++++++++++++++ > xen/include/xen/domain.h | 3 + > 8 files changed, 124 insertions(+), 47 deletions(-) > create mode 100644 xen/common/domid.c > > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c > index 463ae4474d30..789f2b9d3ce7 100644 > --- a/xen/arch/arm/domain_build.c > +++ b/xen/arch/arm/domain_build.c > @@ -2050,6 +2050,7 @@ void __init create_dom0(void) > .grant_opts = XEN_DOMCTL_GRANT_version(opt_gnttab_max_version), > }; > unsigned int flags = CDF_privileged | CDF_hardware; > + domid_t domid; > int rc; > > /* The vGIC for DOM0 is exactly emulating the hardware GIC */ > @@ -2074,7 +2075,11 @@ void __init create_dom0(void) > if ( !llc_coloring_enabled ) > flags |= CDF_directmap; > > - dom0 = domain_create(0, &dom0_cfg, flags); > + domid = domid_alloc(0); > + if ( domid == DOMID_INVALID ) > + panic("Error allocating domain ID 0\n"); > + > + dom0 = domain_create(domid, &dom0_cfg, flags); > if ( IS_ERR(dom0) ) > panic("Error creating domain 0 (rc = %ld)\n", PTR_ERR(dom0)); > > diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c > index 1543dd251cc6..2ff7c28c277b 100644 > --- a/xen/arch/x86/setup.c > +++ b/xen/arch/x86/setup.c > @@ -1047,8 +1047,11 @@ static struct domain *__init create_dom0(struct > boot_info *bi) > if ( iommu_enabled ) > dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu; > > - /* Create initial domain. Not d0 for pvshim. */ > - bd->domid = get_initial_domain_id(); > + /* Allocate initial domain ID. Not d0 for pvshim. */ > + bd->domid = domid_alloc(get_initial_domain_id()); > + if ( bd->domid == DOMID_INVALID ) > + panic("Error allocating domain ID %d\n", get_initial_domain_id()); > + > d = domain_create(bd->domid, &dom0_cfg, > pv_shim ? 0 : CDF_privileged | CDF_hardware); > if ( IS_ERR(d) ) > diff --git a/xen/common/Makefile b/xen/common/Makefile > index c316957fcb36..0c7d0f5d46e1 100644 > --- a/xen/common/Makefile > +++ b/xen/common/Makefile > @@ -11,6 +11,7 @@ obj-$(filter-out $(CONFIG_X86),$(CONFIG_ACPI)) += device.o > obj-$(CONFIG_DEVICE_TREE_PARSE) += device-tree/ > obj-$(CONFIG_IOREQ_SERVER) += dm.o > obj-y += domain.o > +obj-y += domid.o > obj-y += event_2l.o > obj-y += event_channel.o > obj-$(CONFIG_EVTCHN_FIFO) += event_fifo.o > diff --git a/xen/common/device-tree/dom0less-build.c > b/xen/common/device-tree/dom0less-build.c > index 6bb038111de9..f4b6b515d2d2 100644 > --- a/xen/common/device-tree/dom0less-build.c > +++ b/xen/common/device-tree/dom0less-build.c > @@ -833,6 +833,7 @@ void __init create_domUs(void) > { > struct kernel_info ki = KERNEL_INFO_INIT; > int rc = parse_dom0less_node(node, &ki.bd); > + domid_t domid; > > if ( rc == -ENOENT ) > continue; > @@ -842,13 +843,13 @@ void __init create_domUs(void) > if ( (max_init_domid + 1) >= DOMID_FIRST_RESERVED ) > panic("No more domain IDs available\n"); > > - /* > - * The variable max_init_domid is initialized with zero, so here it's > - * very important to use the pre-increment operator to call > - * domain_create() with a domid > 0. (domid == 0 is reserved for > Dom0) > - */ > - ki.bd.d = domain_create(++max_init_domid, > - &ki.bd.create_cfg, ki.bd.create_flags); > + domid = domid_alloc(DOMID_INVALID); > + if ( domid == DOMID_INVALID ) > + panic("Error allocating ID for domain %s\n", dt_node_name(node)); > + > + max_init_domid = max(max_init_domid, domid); > + > + ki.bd.d = domain_create(domid, &ki.bd.create_cfg, > ki.bd.create_flags); > if ( IS_ERR(ki.bd.d) ) > panic("Error creating domain %s (rc = %ld)\n", > dt_node_name(node), PTR_ERR(ki.bd.d)); > diff --git a/xen/common/domain.c b/xen/common/domain.c > index 5241a1629eeb..12fbab01cd8e 100644 > --- a/xen/common/domain.c > +++ b/xen/common/domain.c > @@ -1473,6 +1473,8 @@ void domain_destroy(struct domain *d) > /* Remove from the domlist/hash. */ > domlist_remove(d); > > + domid_free(d->domain_id); > + > /* Schedule RCU asynchronous completion of domain destroy. */ > call_rcu(&d->rcu, complete_domain_destroy); > } > diff --git a/xen/common/domctl.c b/xen/common/domctl.c > index f2a7caaf853c..5509998aa139 100644 > --- a/xen/common/domctl.c > +++ b/xen/common/domctl.c > @@ -51,20 +51,6 @@ static int xenctl_bitmap_to_nodemask(nodemask_t *nodemask, > MAX_NUMNODES); > } > > -static inline int is_free_domid(domid_t dom) > -{ > - struct domain *d; > - > - if ( dom >= DOMID_FIRST_RESERVED ) > - return 0; > - > - if ( (d = rcu_lock_domain_by_id(dom)) == NULL ) > - return 1; > - > - rcu_unlock_domain(d); > - return 0; > -} > - > void getdomaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info) > { > struct vcpu *v; > @@ -423,36 +409,18 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) > u_domctl) > > case XEN_DOMCTL_createdomain: > { > - domid_t dom; > - static domid_t rover = 0; > + domid_t domid = domid_alloc(op->domain); > > - dom = op->domain; > - if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) ) > + if ( domid == DOMID_INVALID ) > { > ret = -EEXIST; > - if ( !is_free_domid(dom) ) > - break; > - } > - else > - { > - for ( dom = rover + 1; dom != rover; dom++ ) > - { > - if ( dom == DOMID_FIRST_RESERVED ) > - dom = 1; > - if ( is_free_domid(dom) ) > - break; > - } > - > - ret = -ENOMEM; > - if ( dom == rover ) > - break; > - > - rover = dom; > + break; > } > > - d = domain_create(dom, &op->u.createdomain, false); > + d = domain_create(domid, &op->u.createdomain, false); > if ( IS_ERR(d) ) > { > + domid_free(domid); > ret = PTR_ERR(d); > d = NULL; > break; > diff --git a/xen/common/domid.c b/xen/common/domid.c > new file mode 100644 > index 000000000000..155fef4236ad > --- /dev/null > +++ b/xen/common/domid.c > @@ -0,0 +1,94 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Domain ID allocator. > + * > + * Covers dom0 or late hwdom, predefined domains, post-boot domains. > + * Excludes Xen system domains (ID >= DOMID_FIRST_RESERVED). > + * > + * Copyright 2025 Ford Motor Company > + */ > + > +#include <xen/domain.h> > + > +static DEFINE_SPINLOCK(domid_lock); > +static DECLARE_BITMAP(domid_bitmap, DOMID_FIRST_RESERVED); > + > +/* > + * Allocate domain ID. > + * > + * @param domid Domain ID hint: > + * - If an explicit domain ID is provided, verify its availability and use it > + * if ID is not used; > + * - If DOMID_INVALID is provided, search [1..DOMID_FIRST_RESERVED-1] range, > + * starting from the last used ID. IDs are not wrapped around in dom0less > + * case. Implementation guarantees that two consecutive calls will never The remark about dom0less is no longer relevant after removing the dom0less ifdef guards, and it should be in the in domain.h rather than here. With that: Reviewed-by: Alejandro Vallejo <alejandro.garciavallejo@xxxxxxx> Cheers, Alejandro
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |