Commit 8dd2bc0f authored by Ben Widawsky's avatar Ben Widawsky Committed by Dan Williams
Browse files

cxl/mem: Add the cxl_mem driver



At this point the subsystem can enumerate all CXL ports (CXL.mem decode
resources in upstream switch ports and host bridges) in a system. The
last mile is connecting those ports to endpoints.

The cxl_mem driver connects an endpoint device to the platform CXL.mem
protoctol decode-topology. At ->probe() time it walks its
device-topology-ancestry and adds a CXL Port object at every Upstream
Port hop until it gets to CXL root. The CXL root object is only present
after a platform firmware driver registers platform CXL resources. For
ACPI based platform this is managed by the ACPI0017 device and the
cxl_acpi driver.

The ports are registered such that disabling a given port automatically
unregisters all descendant ports, and the chain can only be registered
after the root is established.

Given ACPI device scanning may run asynchronously compared to PCI device
scanning the root driver is tasked with rescanning the bus after the
root successfully probes.

Conversely if any ports in a chain between the root and an endpoint
becomes disconnected it subsequently triggers the endpoint to
unregister. Given lock depenedencies the endpoint unregistration happens
in a workqueue asynchronously. If userspace cares about synchronizing
delayed work after port events the /sys/bus/cxl/flush attribute is
available for that purpose.

Reported-by: default avatarRandy Dunlap <rdunlap@infradead.org>
Signed-off-by: default avatarBen Widawsky <ben.widawsky@intel.com>
Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
[djbw: clarify changelog, rework hotplug support]
Link: https://lore.kernel.org/r/164398782997.903003.9725273241627693186.stgit@dwillia2-desk3.amr.corp.intel.com


Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 2703c16c
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
What:		/sys/bus/cxl/flush
Date:		Januarry, 2022
KernelVersion:	v5.18
Contact:	linux-cxl@vger.kernel.org
Description:
		(WO) If userspace manually unbinds a port the kernel schedules
		all descendant memdevs for unbind. Writing '1' to this attribute
		flushes that work.

What:		/sys/bus/cxl/devices/memX/firmware_version
Date:		December, 2020
KernelVersion:	v5.12
+9 −0
Original line number Diff line number Diff line
@@ -325,6 +325,9 @@ CXL Memory Device
.. kernel-doc:: drivers/cxl/pci.c
   :internal:

.. kernel-doc:: drivers/cxl/mem.c
   :doc: cxl mem

CXL Port
--------
.. kernel-doc:: drivers/cxl/port.c
@@ -344,6 +347,12 @@ CXL Core
.. kernel-doc:: drivers/cxl/core/port.c
   :identifiers:

.. kernel-doc:: drivers/cxl/core/pci.c
   :doc: cxl core pci

.. kernel-doc:: drivers/cxl/core/pci.c
   :identifiers:

.. kernel-doc:: drivers/cxl/core/pmem.c
   :doc: cxl pmem

+16 −0
Original line number Diff line number Diff line
@@ -78,6 +78,22 @@ config CXL_PMEM

	  If unsure say 'm'.

config CXL_MEM
	tristate "CXL: Memory Expansion"
	depends on CXL_PCI
	default CXL_BUS
	help
	  The CXL.mem protocol allows a device to act as a provider of "System
	  RAM" and/or "Persistent Memory" that is fully coherent as if the
	  memory were attached to the typical CPU memory controller. This is
	  known as HDM "Host-managed Device Memory".

	  Say 'y/m' to enable a driver that will attach to CXL.mem devices for
	  memory expansion and control of HDM. See Chapter 9.13 in the CXL 2.0
	  specification for a detailed description of HDM.

	  If unsure say 'm'.

config CXL_PORT
	default CXL_BUS
	tristate
+2 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_CXL_BUS) += core/
obj-$(CONFIG_CXL_PCI) += cxl_pci.o
obj-$(CONFIG_CXL_MEM) += cxl_mem.o
obj-$(CONFIG_CXL_ACPI) += cxl_acpi.o
obj-$(CONFIG_CXL_PMEM) += cxl_pmem.o
obj-$(CONFIG_CXL_PORT) += cxl_port.o

cxl_mem-y := mem.o
cxl_pci-y := pci.o
cxl_acpi-y := acpi.o
cxl_pmem-y := pmem.o
+2 −1
Original line number Diff line number Diff line
@@ -314,7 +314,8 @@ static int cxl_acpi_probe(struct platform_device *pdev)
	if (rc < 0)
		return rc;

	return 0;
	/* In case PCI is scanned before ACPI re-trigger memdev attach */
	return cxl_bus_rescan();
}

static const struct acpi_device_id cxl_acpi_ids[] = {
Loading