Message ID | 168193569130.1178687.11664485128816659216.stgit@djiang5-mobl3 |
---|---|
State | New |
Headers | show |
Series | cxl: Add support for QTG ID retrieval for CXL subsystem | expand |
Dave Jiang wrote: > Provide a callback function to the CDAT parser in order to parse the Device > Scoped Memory Affinity Structure (DSMAS). Each DSMAS structure contains the > DPA range and its associated attributes in each entry. See the CDAT > specification for details. > > Coherent Device Attribute Table 1.03 2.1 Device Scoped memory Affinity > Structure (DSMAS) > > Signed-off-by: Dave Jiang <dave.jiang@intel.com> > > --- > v3: > - Add spec section number. (Alison) > - Remove cast from void *. (Alison) > - Refactor cxl_port_probe() block. (Alison) > - Move CDAT parse to cxl_endpoint_port_probe() > > v2: > - Add DSMAS table size check. (Lukas) > - Use local DSMAS header for LE handling. > - Remove dsmas lock. (Jonathan) > - Fix handle size (Jonathan) > - Add LE to host conversion for DSMAS address and length. > - Make dsmas_list local > --- > drivers/cxl/core/cdat.c | 26 ++++++++++++++++++++++++++ > drivers/cxl/cxl.h | 1 + > drivers/cxl/cxlpci.h | 18 ++++++++++++++++++ > drivers/cxl/port.c | 22 ++++++++++++++++++++++ > 4 files changed, 67 insertions(+) > > diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c > index 210f4499bddb..6f20af83a3ed 100644 > --- a/drivers/cxl/core/cdat.c > +++ b/drivers/cxl/core/cdat.c > @@ -98,3 +98,29 @@ int cdat_table_parse_sslbis(struct cdat_header *table, > return cdat_table_parse_entries(CDAT_TYPE_SSLBIS, table, &proc); > } > EXPORT_SYMBOL_NS_GPL(cdat_table_parse_sslbis, CXL); > + > +int cxl_dsmas_parse_entry(struct cdat_entry_header *header, void *arg) > +{ > + struct cdat_dsmas *dsmas = (struct cdat_dsmas *)header; > + struct list_head *dsmas_list = arg; > + struct dsmas_entry *dent; > + > + if (dsmas->hdr.length != sizeof(*dsmas)) { > + pr_warn("Malformed DSMAS table length: (%lu:%u)\n", > + (unsigned long)sizeof(*dsmas), dsmas->hdr.length); > + return -EINVAL; > + } > + > + dent = kzalloc(sizeof(*dent), GFP_KERNEL); > + if (!dent) > + return -ENOMEM; > + > + dent->handle = dsmas->dsmad_handle; > + dent->dpa_range.start = le64_to_cpu(dsmas->dpa_base_address); > + dent->dpa_range.end = le64_to_cpu(dsmas->dpa_base_address) + > + le64_to_cpu(dsmas->dpa_length) - 1; > + list_add_tail(&dent->list, dsmas_list); > + > + return 0; > +} > +EXPORT_SYMBOL_NS_GPL(cxl_dsmas_parse_entry, CXL); > diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h > index 278ab6952332..18ca25c7e527 100644 > --- a/drivers/cxl/cxl.h > +++ b/drivers/cxl/cxl.h > @@ -8,6 +8,7 @@ > #include <linux/bitfield.h> > #include <linux/bitops.h> > #include <linux/log2.h> > +#include <linux/list.h> > #include <linux/io.h> > > /** > diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h > index 45e2f2bf5ef8..9a2468a93d83 100644 > --- a/drivers/cxl/cxlpci.h > +++ b/drivers/cxl/cxlpci.h > @@ -104,6 +104,22 @@ struct cdat_subtable_entry { > enum cdat_type type; > }; > > +struct dsmas_entry { > + struct list_head list; > + struct range dpa_range; > + u8 handle; > +}; > + > +/* Sub-table 0: Device Scoped Memory Affinity Structure (DSMAS) */ > +struct cdat_dsmas { > + struct cdat_entry_header hdr; > + u8 dsmad_handle; > + u8 flags; > + __u16 reserved; > + __le64 dpa_base_address; > + __le64 dpa_length; > +} __packed; > + > int devm_cxl_port_enumerate_dports(struct cxl_port *port); > struct cxl_dev_state; > int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm, > @@ -119,4 +135,6 @@ int cdat_table_parse_##x(struct cdat_header *table, \ > cdat_table_parse(dsmas); > cdat_table_parse(dslbis); > cdat_table_parse(sslbis); > + > +int cxl_dsmas_parse_entry(struct cdat_entry_header *header, void *arg); > #endif /* __CXL_PCI_H__ */ > diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c > index 615e0ef6b440..3022bdd52439 100644 > --- a/drivers/cxl/port.c > +++ b/drivers/cxl/port.c > @@ -57,6 +57,16 @@ static int discover_region(struct device *dev, void *root) > return 0; > } > > +static void dsmas_list_destroy(struct list_head *dsmas_list) > +{ > + struct dsmas_entry *dentry, *n; > + > + list_for_each_entry_safe(dentry, n, dsmas_list, list) { > + list_del(&dentry->list); > + kfree(dentry); > + } > +} > + > static int cxl_switch_port_probe(struct cxl_port *port) > { > struct cxl_hdm *cxlhdm; > @@ -125,6 +135,18 @@ static int cxl_endpoint_port_probe(struct cxl_port *port) > device_for_each_child(&port->dev, root, discover_region); > put_device(&root->dev); > > + if (port->cdat.table) { > + LIST_HEAD(dsmas_list); > + > + rc = cdat_table_parse_dsmas(port->cdat.table, > + cxl_dsmas_parse_entry, > + (void *)&dsmas_list); > + if (rc < 0) > + dev_warn(&port->dev, "Failed to parse DSMAS: %d\n", rc); > + > + dsmas_list_destroy(&dsmas_list); > + } > + Do these entries need to be cached in a list? For example all the table walking in drivers/acpi/numa/srat.c injects the data directly into their final kernel data structure location, it's all self contained in the parse handler.
On 4/20/2023 4:21 AM, Dave Jiang wrote: > Provide a callback function to the CDAT parser in order to parse the Device > Scoped Memory Affinity Structure (DSMAS). Each DSMAS structure contains the > DPA range and its associated attributes in each entry. See the CDAT > specification for details. > > Coherent Device Attribute Table 1.03 2.1 Device Scoped memory Affinity > Structure (DSMAS) > > Signed-off-by: Dave Jiang <dave.jiang@intel.com> > > --- > v3: > - Add spec section number. (Alison) > - Remove cast from void *. (Alison) > - Refactor cxl_port_probe() block. (Alison) > - Move CDAT parse to cxl_endpoint_port_probe() > > v2: > - Add DSMAS table size check. (Lukas) > - Use local DSMAS header for LE handling. > - Remove dsmas lock. (Jonathan) > - Fix handle size (Jonathan) > - Add LE to host conversion for DSMAS address and length. > - Make dsmas_list local > --- > drivers/cxl/core/cdat.c | 26 ++++++++++++++++++++++++++ > drivers/cxl/cxl.h | 1 + > drivers/cxl/cxlpci.h | 18 ++++++++++++++++++ > drivers/cxl/port.c | 22 ++++++++++++++++++++++ > 4 files changed, 67 insertions(+) > > diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c > index 210f4499bddb..6f20af83a3ed 100644 > --- a/drivers/cxl/core/cdat.c > +++ b/drivers/cxl/core/cdat.c > @@ -98,3 +98,29 @@ int cdat_table_parse_sslbis(struct cdat_header *table, > return cdat_table_parse_entries(CDAT_TYPE_SSLBIS, table, &proc); > } > EXPORT_SYMBOL_NS_GPL(cdat_table_parse_sslbis, CXL); > + > +int cxl_dsmas_parse_entry(struct cdat_entry_header *header, void *arg) > +{ > + struct cdat_dsmas *dsmas = (struct cdat_dsmas *)header; > + struct list_head *dsmas_list = arg; > + struct dsmas_entry *dent; > + > + if (dsmas->hdr.length != sizeof(*dsmas)) { > + pr_warn("Malformed DSMAS table length: (%lu:%u)\n", > + (unsigned long)sizeof(*dsmas), dsmas->hdr.length); > + return -EINVAL; > + } > + > + dent = kzalloc(sizeof(*dent), GFP_KERNEL); > + if (!dent) > + return -ENOMEM; > + > + dent->handle = dsmas->dsmad_handle; > + dent->dpa_range.start = le64_to_cpu(dsmas->dpa_base_address); > + dent->dpa_range.end = le64_to_cpu(dsmas->dpa_base_address) + > + le64_to_cpu(dsmas->dpa_length) - 1; Hi Dave, I saw you didn't store flags field into dent, it is not needed or missed? Thanks Ming
On 4/25/23 8:44 PM, Li, Ming wrote: > On 4/20/2023 4:21 AM, Dave Jiang wrote: >> Provide a callback function to the CDAT parser in order to parse the Device >> Scoped Memory Affinity Structure (DSMAS). Each DSMAS structure contains the >> DPA range and its associated attributes in each entry. See the CDAT >> specification for details. >> >> Coherent Device Attribute Table 1.03 2.1 Device Scoped memory Affinity >> Structure (DSMAS) >> >> Signed-off-by: Dave Jiang <dave.jiang@intel.com> >> >> --- >> v3: >> - Add spec section number. (Alison) >> - Remove cast from void *. (Alison) >> - Refactor cxl_port_probe() block. (Alison) >> - Move CDAT parse to cxl_endpoint_port_probe() >> >> v2: >> - Add DSMAS table size check. (Lukas) >> - Use local DSMAS header for LE handling. >> - Remove dsmas lock. (Jonathan) >> - Fix handle size (Jonathan) >> - Add LE to host conversion for DSMAS address and length. >> - Make dsmas_list local >> --- >> drivers/cxl/core/cdat.c | 26 ++++++++++++++++++++++++++ >> drivers/cxl/cxl.h | 1 + >> drivers/cxl/cxlpci.h | 18 ++++++++++++++++++ >> drivers/cxl/port.c | 22 ++++++++++++++++++++++ >> 4 files changed, 67 insertions(+) >> >> diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c >> index 210f4499bddb..6f20af83a3ed 100644 >> --- a/drivers/cxl/core/cdat.c >> +++ b/drivers/cxl/core/cdat.c >> @@ -98,3 +98,29 @@ int cdat_table_parse_sslbis(struct cdat_header *table, >> return cdat_table_parse_entries(CDAT_TYPE_SSLBIS, table, &proc); >> } >> EXPORT_SYMBOL_NS_GPL(cdat_table_parse_sslbis, CXL); >> + >> +int cxl_dsmas_parse_entry(struct cdat_entry_header *header, void *arg) >> +{ >> + struct cdat_dsmas *dsmas = (struct cdat_dsmas *)header; >> + struct list_head *dsmas_list = arg; >> + struct dsmas_entry *dent; >> + >> + if (dsmas->hdr.length != sizeof(*dsmas)) { >> + pr_warn("Malformed DSMAS table length: (%lu:%u)\n", >> + (unsigned long)sizeof(*dsmas), dsmas->hdr.length); >> + return -EINVAL; >> + } >> + >> + dent = kzalloc(sizeof(*dent), GFP_KERNEL); >> + if (!dent) >> + return -ENOMEM; >> + >> + dent->handle = dsmas->dsmad_handle; >> + dent->dpa_range.start = le64_to_cpu(dsmas->dpa_base_address); >> + dent->dpa_range.end = le64_to_cpu(dsmas->dpa_base_address) + >> + le64_to_cpu(dsmas->dpa_length) - 1; > > Hi Dave, > > I saw you didn't store flags field into dent, it is not needed or missed? Hi Ming, I didn't have a need for it for this patch set. But I think it may be needed in the future for DCD. I figured when we do, we can add it. > > Thanks > Ming > >
diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c index 210f4499bddb..6f20af83a3ed 100644 --- a/drivers/cxl/core/cdat.c +++ b/drivers/cxl/core/cdat.c @@ -98,3 +98,29 @@ int cdat_table_parse_sslbis(struct cdat_header *table, return cdat_table_parse_entries(CDAT_TYPE_SSLBIS, table, &proc); } EXPORT_SYMBOL_NS_GPL(cdat_table_parse_sslbis, CXL); + +int cxl_dsmas_parse_entry(struct cdat_entry_header *header, void *arg) +{ + struct cdat_dsmas *dsmas = (struct cdat_dsmas *)header; + struct list_head *dsmas_list = arg; + struct dsmas_entry *dent; + + if (dsmas->hdr.length != sizeof(*dsmas)) { + pr_warn("Malformed DSMAS table length: (%lu:%u)\n", + (unsigned long)sizeof(*dsmas), dsmas->hdr.length); + return -EINVAL; + } + + dent = kzalloc(sizeof(*dent), GFP_KERNEL); + if (!dent) + return -ENOMEM; + + dent->handle = dsmas->dsmad_handle; + dent->dpa_range.start = le64_to_cpu(dsmas->dpa_base_address); + dent->dpa_range.end = le64_to_cpu(dsmas->dpa_base_address) + + le64_to_cpu(dsmas->dpa_length) - 1; + list_add_tail(&dent->list, dsmas_list); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(cxl_dsmas_parse_entry, CXL); diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 278ab6952332..18ca25c7e527 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -8,6 +8,7 @@ #include <linux/bitfield.h> #include <linux/bitops.h> #include <linux/log2.h> +#include <linux/list.h> #include <linux/io.h> /** diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h index 45e2f2bf5ef8..9a2468a93d83 100644 --- a/drivers/cxl/cxlpci.h +++ b/drivers/cxl/cxlpci.h @@ -104,6 +104,22 @@ struct cdat_subtable_entry { enum cdat_type type; }; +struct dsmas_entry { + struct list_head list; + struct range dpa_range; + u8 handle; +}; + +/* Sub-table 0: Device Scoped Memory Affinity Structure (DSMAS) */ +struct cdat_dsmas { + struct cdat_entry_header hdr; + u8 dsmad_handle; + u8 flags; + __u16 reserved; + __le64 dpa_base_address; + __le64 dpa_length; +} __packed; + int devm_cxl_port_enumerate_dports(struct cxl_port *port); struct cxl_dev_state; int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm, @@ -119,4 +135,6 @@ int cdat_table_parse_##x(struct cdat_header *table, \ cdat_table_parse(dsmas); cdat_table_parse(dslbis); cdat_table_parse(sslbis); + +int cxl_dsmas_parse_entry(struct cdat_entry_header *header, void *arg); #endif /* __CXL_PCI_H__ */ diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c index 615e0ef6b440..3022bdd52439 100644 --- a/drivers/cxl/port.c +++ b/drivers/cxl/port.c @@ -57,6 +57,16 @@ static int discover_region(struct device *dev, void *root) return 0; } +static void dsmas_list_destroy(struct list_head *dsmas_list) +{ + struct dsmas_entry *dentry, *n; + + list_for_each_entry_safe(dentry, n, dsmas_list, list) { + list_del(&dentry->list); + kfree(dentry); + } +} + static int cxl_switch_port_probe(struct cxl_port *port) { struct cxl_hdm *cxlhdm; @@ -125,6 +135,18 @@ static int cxl_endpoint_port_probe(struct cxl_port *port) device_for_each_child(&port->dev, root, discover_region); put_device(&root->dev); + if (port->cdat.table) { + LIST_HEAD(dsmas_list); + + rc = cdat_table_parse_dsmas(port->cdat.table, + cxl_dsmas_parse_entry, + (void *)&dsmas_list); + if (rc < 0) + dev_warn(&port->dev, "Failed to parse DSMAS: %d\n", rc); + + dsmas_list_destroy(&dsmas_list); + } + return 0; }
Provide a callback function to the CDAT parser in order to parse the Device Scoped Memory Affinity Structure (DSMAS). Each DSMAS structure contains the DPA range and its associated attributes in each entry. See the CDAT specification for details. Coherent Device Attribute Table 1.03 2.1 Device Scoped memory Affinity Structure (DSMAS) Signed-off-by: Dave Jiang <dave.jiang@intel.com> --- v3: - Add spec section number. (Alison) - Remove cast from void *. (Alison) - Refactor cxl_port_probe() block. (Alison) - Move CDAT parse to cxl_endpoint_port_probe() v2: - Add DSMAS table size check. (Lukas) - Use local DSMAS header for LE handling. - Remove dsmas lock. (Jonathan) - Fix handle size (Jonathan) - Add LE to host conversion for DSMAS address and length. - Make dsmas_list local --- drivers/cxl/core/cdat.c | 26 ++++++++++++++++++++++++++ drivers/cxl/cxl.h | 1 + drivers/cxl/cxlpci.h | 18 ++++++++++++++++++ drivers/cxl/port.c | 22 ++++++++++++++++++++++ 4 files changed, 67 insertions(+)