On Tue, Oct 8, 2024 at 1:17 AM Ira Weiny <ira.weiny@xxxxxxxxx> wrote: > > Additional DCD region (partition) information is contained in the DSMAS > CDAT tables, including performance, read only, and shareable attributes. > > Match DCD partitions with DSMAS tables and store the meta data. > > To: Robert Moore <robert.moore@xxxxxxxxx> > To: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > To: Len Brown <lenb@xxxxxxxxxx> > Cc: linux-acpi@xxxxxxxxxxxxxxx > Cc: acpica-devel@xxxxxxxxxxxxxxx > Signed-off-by: Ira Weiny <ira.weiny@xxxxxxxxx> > > --- > Changes: > [iweiny: new patch] > [iweiny: Gather shareable/read-only flags for later use] > --- > drivers/cxl/core/cdat.c | 38 ++++++++++++++++++++++++++++++++++++++ > drivers/cxl/core/mbox.c | 2 ++ > drivers/cxl/cxlmem.h | 3 +++ > include/acpi/actbl1.h | 2 ++ > 4 files changed, 45 insertions(+) > > diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c > index bd50bb655741..9b2f717a16e5 100644 > --- a/drivers/cxl/core/cdat.c > +++ b/drivers/cxl/core/cdat.c > @@ -17,6 +17,8 @@ struct dsmas_entry { > struct access_coordinate cdat_coord[ACCESS_COORDINATE_MAX]; > int entries; > int qos_class; > + bool shareable; > + bool read_only; > }; > > static u32 cdat_normalize(u16 entry, u64 base, u8 type) > @@ -74,6 +76,8 @@ static int cdat_dsmas_handler(union acpi_subtable_headers *header, void *arg, > return -ENOMEM; > > dent->handle = dsmas->dsmad_handle; > + dent->shareable = dsmas->flags & ACPI_CDAT_DSMAS_SHAREABLE; > + dent->read_only = dsmas->flags & ACPI_CDAT_DSMAS_READ_ONLY; > dent->dpa_range.start = le64_to_cpu((__force __le64)dsmas->dpa_base_address); > dent->dpa_range.end = le64_to_cpu((__force __le64)dsmas->dpa_base_address) + > le64_to_cpu((__force __le64)dsmas->dpa_length) - 1; > @@ -255,6 +259,38 @@ static void update_perf_entry(struct device *dev, struct dsmas_entry *dent, > dent->coord[ACCESS_COORDINATE_CPU].write_latency); > } > > + > +static void update_dcd_perf(struct cxl_dev_state *cxlds, > + struct dsmas_entry *dent) > +{ > + struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds); > + struct device *dev = cxlds->dev; > + > + for (int i = 0; i < mds->nr_dc_region; i++) { > + /* CXL defines a u32 handle while cdat defines u8, ignore upper bits */ > + u8 dc_handle = mds->dc_region[i].dsmad_handle & 0xff; > + > + if (resource_size(&cxlds->dc_res[i])) { > + struct range dc_range = { > + .start = cxlds->dc_res[i].start, > + .end = cxlds->dc_res[i].end, > + }; > + > + if (range_contains(&dent->dpa_range, &dc_range)) { > + if (dent->handle != dc_handle) > + dev_warn(dev, "DC Region/DSMAS mis-matched handle/range; region %pra (%u); dsmas %pra (%u)\n" > + " setting DC region attributes regardless\n", > + &dent->dpa_range, dent->handle, > + &dc_range, dc_handle); > + > + mds->dc_region[i].shareable = dent->shareable; > + mds->dc_region[i].read_only = dent->read_only; > + update_perf_entry(dev, dent, &mds->dc_perf[i]); > + } > + } > + } > +} > + > static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds, > struct xarray *dsmas_xa) > { > @@ -278,6 +314,8 @@ static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds, > else if (resource_size(&cxlds->pmem_res) && > range_contains(&pmem_range, &dent->dpa_range)) > update_perf_entry(dev, dent, &mds->pmem_perf); > + else if (cxl_dcd_supported(mds)) > + update_dcd_perf(cxlds, dent); > else > dev_dbg(dev, "no partition for dsmas dpa: %pra\n", > &dent->dpa_range); > diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c > index 4b51ddd1ff94..3ba465823564 100644 > --- a/drivers/cxl/core/mbox.c > +++ b/drivers/cxl/core/mbox.c > @@ -1649,6 +1649,8 @@ struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev) > mds->cxlds.type = CXL_DEVTYPE_CLASSMEM; > mds->ram_perf.qos_class = CXL_QOS_CLASS_INVALID; > mds->pmem_perf.qos_class = CXL_QOS_CLASS_INVALID; > + for (int i = 0; i < CXL_MAX_DC_REGION; i++) > + mds->dc_perf[i].qos_class = CXL_QOS_CLASS_INVALID; > > return mds; > } > diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h > index 0690b917b1e0..c3b889a586d8 100644 > --- a/drivers/cxl/cxlmem.h > +++ b/drivers/cxl/cxlmem.h > @@ -466,6 +466,8 @@ struct cxl_dc_region_info { > u64 blk_size; > u32 dsmad_handle; > u8 flags; > + bool shareable; > + bool read_only; > u8 name[CXL_DC_REGION_STRLEN]; > }; > > @@ -533,6 +535,7 @@ struct cxl_memdev_state { > > u8 nr_dc_region; > struct cxl_dc_region_info dc_region[CXL_MAX_DC_REGION]; > + struct cxl_dpa_perf dc_perf[CXL_MAX_DC_REGION]; > > struct cxl_event_state event; > struct cxl_poison_state poison; > diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h > index 199afc2cd122..387fc821703a 100644 > --- a/include/acpi/actbl1.h > +++ b/include/acpi/actbl1.h > @@ -403,6 +403,8 @@ struct acpi_cdat_dsmas { > /* Flags for subtable above */ > > #define ACPI_CDAT_DSMAS_NON_VOLATILE (1 << 2) > +#define ACPI_CDAT_DSMAS_SHAREABLE (1 << 3) > +#define ACPI_CDAT_DSMAS_READ_ONLY (1 << 6) > > /* Subtable 1: Device scoped Latency and Bandwidth Information Structure (DSLBIS) */ > Is there an upstream ACPICA commit for this?