[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 1/8] x86/pdx: simplify calculation of domain struct allocation boundary
On Thu, Jun 12, 2025 at 11:03:21AM +0200, Jan Beulich wrote: > On 11.06.2025 19:16, Roger Pau Monne wrote: > > @@ -498,14 +474,15 @@ struct domain *alloc_domain_struct(void) > > * On systems with CONFIG_BIGMEM there's no packing, and so there's no > > * such restriction. > > */ > > -#if defined(CONFIG_BIGMEM) || !defined(CONFIG_PDX_COMPRESSION) > > - const unsigned int bits = IS_ENABLED(CONFIG_BIGMEM) ? 0 : > > - 32 + PAGE_SHIFT; > > +#if defined(CONFIG_BIGMEM) > > + const unsigned int bits = 0; > > #else > > - static unsigned int __read_mostly bits; > > + static unsigned int __ro_after_init bits; > > > > if ( unlikely(!bits) ) > > - bits = _domain_struct_bits(); > > + bits = flsl(pfn_to_paddr(pdx_to_pfn( > > + 1UL << (sizeof(((struct page_info *)NULL)->v.inuse._domain) * > > 8)))) > > + - 1; > > While Andrew did point you at sizeof_field(), we can have this even less > verbose > by utilizing that frame_table is of the right type and (almost) globally in > scope. > > Further, why use pfn_to_paddr()? > > bits = flsl(pdx_to_pfn(1UL << > (sizeof(frame_table->v.inuse._domain) * 8))) + > PAGE_SHIFT - 1; I've introduced and used pdx_to_paddr(), which I think it's more natural. We already had a paddr_to_pdx() which was missing it's bidirectional equivalent. It's now: bits = flsl(pdx_to_paddr(1UL << (sizeof_field(struct page_info, v.inuse._domain) * 8))) - 1; > However, it further feels like this was off by one; we had similar issues over > time in several places. There potentially being a gap between one less than > the PDX used here and that very PDX, don't we need to calculate based on the > "one less" value here? Hmm, there being a gap means no allocation would > succeed for the precise value of "bits" (in the mask-compression scheme), so > functionally all would be fine. Yet just to avoid setting a bad precedent I > think we'd still be better off using > > bits = flsl(pdx_to_pfn((1UL << > (sizeof(frame_table->v.inuse._domain) * 8)) - > 1)) + PAGE_SHIFT; > > If one would log the value of bits, the result would then also be less > confusing in (at least) the mask-compression scheme. Is the above correct tough? Take for example the hypothetical case where pdx_to_pfn() returns 0x10. Then flsl() will return 5 (let's leave the PAGE_SHIFT adjustment out for the example here). The allocation bit width would be off-by-one, because allocating using a bit width of 5 would also allow 0x11 to be allocated, and that won't be correct. I think we need to get the bit width of the next pdx (so the non-inclusive end of the range), and then subtract 1 from it, otherwise the allocation bit width is possibly off-by-one. Thanks, Roger.
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |