On 12/9/24 1:32 AM, Li Ming wrote: > On 12/5/2024 6:46 AM, Dave Jiang wrote: >> The current cxl region size only indicates the size of the CXL memory >> region without accounting for the extended linear cache size. Retrieve the >> cache size from HMAT and append that to the cxl region size for the cxl >> region range that matches the SRAT range that has extended linear cache >> enabled. >> >> The SRAT defines the whole memory range that includes the extended linear >> cache and the CXL memory region. The new HMAT ECN/ECR to the Memory Side >> Cache Information Structure defines the size of the extended linear cache >> size and matches to the SRAT Memory Affinity Structure by the memory >> proxmity domain. Add a helper to match the cxl range to the SRAT memory >> range in order to retrieve the cache size. >> >> There are several places that checks the cxl region range against the >> decoder range. Use new helper to check between the two ranges and address >> the new cache size. >> >> Signed-off-by: Dave Jiang <dave.jiang@xxxxxxxxx> >> --- >> RFC: >> - Minor refactors (Jonathan) >> - Fix grammar (Jonathan) >> --- >> drivers/acpi/numa/hmat.c | 39 ++++++++++++++++++++++ >> drivers/cxl/core/Makefile | 1 + >> drivers/cxl/core/acpi.c | 11 ++++++ >> drivers/cxl/core/core.h | 3 ++ >> drivers/cxl/core/region.c | 70 ++++++++++++++++++++++++++++++++++++--- >> drivers/cxl/cxl.h | 2 ++ >> include/linux/acpi.h | 19 +++++++++++ >> tools/testing/cxl/Kbuild | 1 + >> 8 files changed, 142 insertions(+), 4 deletions(-) >> create mode 100644 drivers/cxl/core/acpi.c >> >> diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c >> index 976b3e1a6c2a..1c5b3c37ac29 100644 >> --- a/drivers/acpi/numa/hmat.c >> +++ b/drivers/acpi/numa/hmat.c >> @@ -108,6 +108,45 @@ static struct memory_target *find_mem_target(unsigned int mem_pxm) >> return NULL; >> } >> >> +/** >> + * hmat_get_extended_linear_cache_size - Retrieve the extended linear cache size >> + * @backing_res: resource from the backing media >> + * @nid: node id for the memory region >> + * @cache_size: (Output) size of extended linear cache. >> + * >> + * Return: 0 on success. Errno on failure. >> + * >> + */ >> +int hmat_get_extended_linear_cache_size(struct resource *backing_res, int nid, >> + resource_size_t *cache_size) >> +{ >> + unsigned int pxm = node_to_pxm(nid); >> + struct memory_target *target; >> + struct target_cache *tcache; >> + struct resource *res; >> + >> + target = find_mem_target(pxm); >> + if (!target) >> + return -ENOENT; >> + >> + list_for_each_entry(tcache, &target->caches, node) { >> + if (tcache->cache_attrs.address_mode == >> + NODE_CACHE_ADDR_MODE_EXTENDED_LINEAR) >> + continue; > > Should continue only when "tcache->cache_attrs.address_mode" is NOT "NODE_CACHE_ADDR_MODE_EXTENDED_LINEAR"? > > [snip] yes thanks. editing mistake. :( > >> +static int cxl_extended_linear_cache_resize(struct cxl_region *cxlr, >> + struct resource *res) >> +{ >> + struct cxl_region_params *p = &cxlr->params; >> + int nid = phys_to_target_node(res->start); >> + resource_size_t size, cache_size; >> + int rc; >> + >> + size = resource_size(res); >> + if (!size) >> + return -EINVAL; >> + >> + rc = cxl_acpi_get_extended_linear_cache_size(res, nid, &cache_size); >> + if (rc) >> + return rc; >> + >> + if (!cache_size) >> + return 0; >> + >> + if (size != cache_size) { >> + dev_warn(&cxlr->dev, "Extended Linear Cache is not 1:1, unsupported!"); >> + return -EOPNOTSUPP; >> + } >> + >> + /* >> + * Move the start of the range to where the cache range starts. The >> + * implementation assumes that the cache range is in front of the >> + * CXL range. This is not dictated by the HMAT spec but is how the >> + * current known implementation is configured. >> + */ >> + res->start -= cache_size; >> + p->cache_size = cache_size; >> + >> + return 0; >> +} >> + >> /* Establish an empty region covering the given HPA range */ >> static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, >> struct cxl_endpoint_decoder *cxled) >> @@ -3256,6 +3306,18 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, >> >> *res = DEFINE_RES_MEM_NAMED(hpa->start, range_len(hpa), >> dev_name(&cxlr->dev)); >> + >> + rc = cxl_extended_linear_cache_resize(cxlr, res); >> + if (rc) { >> + /* >> + * Failing to support extended linear cache region resize does not >> + * prevent the region from functioning. Only cause cxl list showing >> + * incorrect region size. >> + */ >> + dev_warn(cxlmd->dev.parent, >> + "Failed to support extended linear cache.\n"); >> + } >> + > > cxl_extended_linear_cache_resize() will adjust res->start if there is an available cache_size. > > Is it possible that below insert_resource() failed because "res->start" is less than "cxlrd->res->start"? > > My understanding is that the address range of cxlrd->res comes from CFMWS, I don't find any description in patchset about the address range defined in CFMWS including extended linear cache size. So I guess that a CFMWS will not expose a address range with extended linear cache size? The CFMWS window is expected to include the extended cache range. res->start should not to be less than cxlrd->res->start after adjustment. It's been the case in testing. I'll add a comment to address that. > > I'm studying this patchset, please correct me if I'm wrong. Thank you. > >> rc = insert_resource(cxlrd->res, res); >> if (rc) { >> /* > [snip] > > Ming >