diff mbox series

[v2,19/21] cxl: Store QTG IDs and related info to the CXL memory device context

Message ID 167995356029.2857312.4374564094571467987.stgit@djiang5-mobl3
State New
Headers show
Series cxl: Add support for QTG ID retrieval for CXL subsystem | expand

Commit Message

Dave Jiang March 27, 2023, 9:46 p.m. UTC
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(+)
diff mbox series

Patch

diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
index 28a05f2fe32d..d2605fc39240 100644
--- a/drivers/cxl/core/memdev.c
+++ b/drivers/cxl/core/memdev.c
@@ -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);
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index 001dabf0231b..c8b8d4865e49 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -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
  *
diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c
index f6646d91ae26..4e7e22c13790 100644
--- a/drivers/cxl/port.c
+++ b/drivers/cxl/port.c
@@ -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,