Message ID | 20241029202041.25334-4-gourry@gourry.net (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | memory,x86,acpi: hotplug memory alignment advisement | expand |
On 29.10.24 21:20, Gregory Price wrote: > Capacity is stranded when CFMWS regions are not aligned to block size. > On x86, block size increases with capacity (2G blocks @ 64G capacity). > > Use CFMWS base/size to report memory block size alignment advice. > > Suggested-by: Dan Williams <dan.j.williams@intel.com> > Signed-off-by: Gregory Price <gourry@gourry.net> > --- > drivers/acpi/numa/srat.c | 19 +++++++++++++++++-- > 1 file changed, 17 insertions(+), 2 deletions(-) > > diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c > index 44f91f2c6c5d..a24aff38c465 100644 > --- a/drivers/acpi/numa/srat.c > +++ b/drivers/acpi/numa/srat.c > @@ -14,6 +14,7 @@ > #include <linux/errno.h> > #include <linux/acpi.h> > #include <linux/memblock.h> > +#include <linux/memory.h> > #include <linux/numa.h> > #include <linux/nodemask.h> > #include <linux/topology.h> > @@ -338,12 +339,26 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, > { > struct acpi_cedt_cfmws *cfmws; > int *fake_pxm = arg; > - u64 start, end; > + u64 start, end, align, size; > int node; > > cfmws = (struct acpi_cedt_cfmws *)header; > start = cfmws->base_hpa; > - end = cfmws->base_hpa + cfmws->window_size; > + size = cfmws->window_size; > + end = cfmws->base_hpa + size; > + > + /* Align memblock size to CFMW regions if possible */ > + for (align = SZ_64T; align >= SZ_256M; align >>= 1) { > + if (IS_ALIGNED(start, align) && IS_ALIGNED(size, align)) > + break; > + } Are there maybe some nice tricks bi-tricks to avoid the loop and these hardcoded limits? :) align = 1UL << __ffs(start | end)); Assuming "unsigned long" is sufficient in this code (64bit) and "start | end" will never be 0.
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c index 44f91f2c6c5d..a24aff38c465 100644 --- a/drivers/acpi/numa/srat.c +++ b/drivers/acpi/numa/srat.c @@ -14,6 +14,7 @@ #include <linux/errno.h> #include <linux/acpi.h> #include <linux/memblock.h> +#include <linux/memory.h> #include <linux/numa.h> #include <linux/nodemask.h> #include <linux/topology.h> @@ -338,12 +339,26 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, { struct acpi_cedt_cfmws *cfmws; int *fake_pxm = arg; - u64 start, end; + u64 start, end, align, size; int node; cfmws = (struct acpi_cedt_cfmws *)header; start = cfmws->base_hpa; - end = cfmws->base_hpa + cfmws->window_size; + size = cfmws->window_size; + end = cfmws->base_hpa + size; + + /* Align memblock size to CFMW regions if possible */ + for (align = SZ_64T; align >= SZ_256M; align >>= 1) { + if (IS_ALIGNED(start, align) && IS_ALIGNED(size, align)) + break; + } + + if (align >= SZ_256M) { + if (memory_block_advise_max_size(align) < 0) + pr_warn("CFMWS: memblock size advise failed\n"); + } else { + pr_err("CFMWS: [BIOS BUG] base/size alignment violates spec\n"); + } /* * The SRAT may have already described NUMA details for all,
Capacity is stranded when CFMWS regions are not aligned to block size. On x86, block size increases with capacity (2G blocks @ 64G capacity). Use CFMWS base/size to report memory block size alignment advice. Suggested-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Gregory Price <gourry@gourry.net> --- drivers/acpi/numa/srat.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)