summaryrefslogtreecommitdiff
path: root/drivers/cxl/mem.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2022-04-23 01:58:11 +0300
committerDan Williams <dan.j.williams@intel.com>2022-04-23 02:09:42 +0300
commit9ea4dcf49878bb9546b8fa9319dcbdc9b7ee20f8 (patch)
tree0ab0d171f766a432e6776e45b0871f436babd1d3 /drivers/cxl/mem.c
parent35ee1f499091c76bd5f5d52f5ef79c3568ac74a6 (diff)
downloadlinux-9ea4dcf49878bb9546b8fa9319dcbdc9b7ee20f8.tar.xz
PM: CXL: Disable suspend
The CXL specification claims S3 support at a hardware level, but at a system software level there are some missing pieces. Section 9.4 (CXL 2.0) rightly claims that "CXL mem adapters may need aux power to retain memory context across S3", but there is no enumeration mechanism for the OS to determine if a given adapter has that support. Moreover the save state and resume image for the system may inadvertantly end up in a CXL device that needs to be restored before the save state is recoverable. I.e. a circular dependency that is not resolvable without a third party save-area. Arrange for the cxl_mem driver to fail S3 attempts. This still nominaly allows for suspend, but requires unbinding all CXL memory devices before the suspend to ensure the typical DRAM flow is taken. The cxl_mem unbind flow is intended to also tear down all CXL memory regions associated with a given cxl_memdev. It is reasonable to assume that any device participating in a System RAM range published in the EFI memory map is covered by aux power and save-area outside the device itself. So this restriction can be minimized in the future once pre-existing region enumeration support arrives, and perhaps a spec update to clarify if the EFI memory map is sufficent for determining the range of devices managed by platform-firmware for S3 support. Per Rafael, if the CXL configuration prevents suspend then it should fail early before tasks are frozen, and mem_sleep should stop showing 'mem' as an option [1]. Effectively CXL augments the platform suspend ->valid() op since, for example, the ACPI ops are not aware of the CXL / PCI dependencies. Given the split role of platform firmware vs OS provisioned CXL memory it is up to the cxl_mem driver to determine if the CXL configuration has elements that platform firmware may not be prepared to restore. Link: https://lore.kernel.org/r/CAJZ5v0hGVN_=3iU8OLpHY3Ak35T5+JcBM-qs8SbojKrpd0VXsA@mail.gmail.com [1] Cc: "Rafael J. Wysocki" <rafael@kernel.org> Cc: Pavel Machek <pavel@ucw.cz> Cc: Len Brown <len.brown@intel.com> Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://lore.kernel.org/r/165066828317.3907920.5690432272182042556.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/cxl/mem.c')
-rw-r--r--drivers/cxl/mem.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
index 43e73d259207..1bd2e0b67f59 100644
--- a/drivers/cxl/mem.c
+++ b/drivers/cxl/mem.c
@@ -138,6 +138,11 @@ out:
return retval;
}
+static void enable_suspend(void *data)
+{
+ cxl_mem_active_dec();
+}
+
static int cxl_mem_probe(struct device *dev)
{
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
@@ -194,7 +199,22 @@ static int cxl_mem_probe(struct device *dev)
out:
cxl_device_unlock(&parent_port->dev);
put_device(&parent_port->dev);
- return rc;
+
+ /*
+ * The kernel may be operating out of CXL memory on this device,
+ * there is no spec defined way to determine whether this device
+ * preserves contents over suspend, and there is no simple way
+ * to arrange for the suspend image to avoid CXL memory which
+ * would setup a circular dependency between PCI resume and save
+ * state restoration.
+ *
+ * TODO: support suspend when all the regions this device is
+ * hosting are locked and covered by the system address map,
+ * i.e. platform firmware owns restoring the HDM configuration
+ * that it locked.
+ */
+ cxl_mem_active_inc();
+ return devm_add_action_or_reset(dev, enable_suspend, NULL);
}
static struct cxl_driver cxl_mem_driver = {