@@ -346,6 +346,7 @@ struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds)
*/
cxlmd->cxlds = cxlds;
cxlds->cxlmd = cxlmd;
+ INIT_LIST_HEAD(&cxlmd->qos_list);
cdev = &cxlmd->cdev;
rc = cdev_device_add(cdev, dev);
@@ -40,6 +40,7 @@
* @cxl_nvd: optional bridge to an nvdimm if the device supports pmem
* @id: id number of this memdev instance.
* @depth: endpoint port depth
+ * @qos_list: QTG ID related list of entries
*/
struct cxl_memdev {
struct device dev;
@@ -50,6 +51,7 @@ struct cxl_memdev {
struct cxl_nvdimm *cxl_nvd;
int id;
int depth;
+ struct list_head qos_list;
};
static inline struct cxl_memdev *to_cxl_memdev(struct device *dev)
@@ -215,6 +217,18 @@ struct cxl_event_state {
struct mutex log_lock;
};
+/**
+ * struct qos_prop - QoS property entry
+ * @list - list entry
+ * @dpa_range - range for DPA address
+ * @qtg_id - QoS Throttling Group ID
+ */
+struct qos_prop_entry {
+ struct list_head list;
+ struct range dpa_range;
+ u16 qtg_id;
+};
+
/**
* struct cxl_dev_state - The driver device state
*
@@ -124,6 +124,22 @@ static int cxl_port_qos_calculate(struct cxl_port *port,
return 0;
}
+static void cxl_memdev_set_qtg(struct cxl_memdev *cxlmd, struct list_head *dsmas_list)
+{
+ struct dsmas_entry *dent;
+ struct qos_prop_entry *qos;
+
+ list_for_each_entry(dent, dsmas_list, list) {
+ qos = devm_kzalloc(&cxlmd->dev, sizeof(*qos), GFP_KERNEL);
+ if (!qos)
+ return;
+
+ qos->dpa_range = dent->dpa_range;
+ qos->qtg_id = dent->qtg_id;
+ list_add_tail(&qos->list, &cxlmd->qos_list);
+ }
+}
+
static int cxl_switch_port_probe(struct cxl_port *port)
{
struct cxl_hdm *cxlhdm;
@@ -212,6 +228,7 @@ static int cxl_port_probe(struct device *dev)
read_cdat_data(port);
if (port->cdat.table) {
if (is_cxl_endpoint(port)) {
+ struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport);
LIST_HEAD(dsmas_list);
rc = cdat_table_parse_dsmas(port->cdat.table,
@@ -230,6 +247,8 @@ static int cxl_port_probe(struct device *dev)
rc = cxl_port_qos_calculate(port, &dsmas_list);
if (rc)
dev_dbg(dev, "Failed to do QoS calculations\n");
+
+ cxl_memdev_set_qtg(cxlmd, &dsmas_list);
dsmas_list_destroy(&dsmas_list);
} else {
rc = cdat_table_parse_sslbis(port->cdat.table,
Once the QTG ID _DSM is executed successfully, the QTG ID is retrieved from the return package. Create a list of entries in the cxl_memdev context and store the QTG ID and the associated DPA range. This information can be exposed to user space via sysfs in order to help region setup for hot-plugged CXL memory devices. Signed-off-by: Dave Jiang <dave.jiang@intel.com> --- drivers/cxl/core/memdev.c | 1 + drivers/cxl/cxlmem.h | 14 ++++++++++++++ drivers/cxl/port.c | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+)