mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:02:20 +00:00
cxl/test: Improve init-order fidelity relative to real-world systems
The investigation of an initialization failure [1] highlighted that cxl_test does not reflect the init-order of real world systems. The expected order is root/bus first then async probing of the memory devices. Fix up cxl_test to reflect that order. While it did not reproduce the initial bug report (since that is dependent on built-in vs modular builds), it did reveal a separate latent bug in the subsystem's decoder shutdown flow. Fix for that sent separately. Link: http://lore.kernel.org/20241004212504.1246-1-gourry@gourry.net [1] Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: Jonathan Cameron <jonathan.cameron@huawei.com> Cc: Dave Jiang <dave.jiang@intel.com> Cc: Alison Schofield <alison.schofield@intel.com> Cc: Vishal Verma <vishal.l.verma@intel.com> Cc: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Link: https://patch.msgid.link/172964784521.81806.15791069994065969243.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Ira Weiny <ira.weiny@intel.com>
This commit is contained in:
parent
105b6235ad
commit
3a2b97b321
@ -1058,7 +1058,7 @@ static void mock_companion(struct acpi_device *adev, struct device *dev)
|
||||
#define SZ_64G (SZ_32G * 2)
|
||||
#endif
|
||||
|
||||
static __init int cxl_rch_init(void)
|
||||
static __init int cxl_rch_topo_init(void)
|
||||
{
|
||||
int rc, i;
|
||||
|
||||
@ -1086,30 +1086,8 @@ static __init int cxl_rch_init(void)
|
||||
goto err_bridge;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cxl_rcd); i++) {
|
||||
int idx = NR_MEM_MULTI + NR_MEM_SINGLE + i;
|
||||
struct platform_device *rch = cxl_rch[i];
|
||||
struct platform_device *pdev;
|
||||
|
||||
pdev = platform_device_alloc("cxl_rcd", idx);
|
||||
if (!pdev)
|
||||
goto err_mem;
|
||||
pdev->dev.parent = &rch->dev;
|
||||
set_dev_node(&pdev->dev, i % 2);
|
||||
|
||||
rc = platform_device_add(pdev);
|
||||
if (rc) {
|
||||
platform_device_put(pdev);
|
||||
goto err_mem;
|
||||
}
|
||||
cxl_rcd[i] = pdev;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_mem:
|
||||
for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_rcd[i]);
|
||||
err_bridge:
|
||||
for (i = ARRAY_SIZE(cxl_rch) - 1; i >= 0; i--) {
|
||||
struct platform_device *pdev = cxl_rch[i];
|
||||
@ -1123,12 +1101,10 @@ err_bridge:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void cxl_rch_exit(void)
|
||||
static void cxl_rch_topo_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_rcd[i]);
|
||||
for (i = ARRAY_SIZE(cxl_rch) - 1; i >= 0; i--) {
|
||||
struct platform_device *pdev = cxl_rch[i];
|
||||
|
||||
@ -1139,7 +1115,7 @@ static void cxl_rch_exit(void)
|
||||
}
|
||||
}
|
||||
|
||||
static __init int cxl_single_init(void)
|
||||
static __init int cxl_single_topo_init(void)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
@ -1224,29 +1200,8 @@ static __init int cxl_single_init(void)
|
||||
cxl_swd_single[i] = pdev;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cxl_mem_single); i++) {
|
||||
struct platform_device *dport = cxl_swd_single[i];
|
||||
struct platform_device *pdev;
|
||||
|
||||
pdev = platform_device_alloc("cxl_mem", NR_MEM_MULTI + i);
|
||||
if (!pdev)
|
||||
goto err_mem;
|
||||
pdev->dev.parent = &dport->dev;
|
||||
set_dev_node(&pdev->dev, i % 2);
|
||||
|
||||
rc = platform_device_add(pdev);
|
||||
if (rc) {
|
||||
platform_device_put(pdev);
|
||||
goto err_mem;
|
||||
}
|
||||
cxl_mem_single[i] = pdev;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_mem:
|
||||
for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_mem_single[i]);
|
||||
err_dport:
|
||||
for (i = ARRAY_SIZE(cxl_swd_single) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_swd_single[i]);
|
||||
@ -1269,12 +1224,10 @@ err_bridge:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void cxl_single_exit(void)
|
||||
static void cxl_single_topo_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_mem_single[i]);
|
||||
for (i = ARRAY_SIZE(cxl_swd_single) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_swd_single[i]);
|
||||
for (i = ARRAY_SIZE(cxl_swu_single) - 1; i >= 0; i--)
|
||||
@ -1291,6 +1244,91 @@ static void cxl_single_exit(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void cxl_mem_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_rcd[i]);
|
||||
for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_mem_single[i]);
|
||||
for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_mem[i]);
|
||||
}
|
||||
|
||||
static int cxl_mem_init(void)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cxl_mem); i++) {
|
||||
struct platform_device *dport = cxl_switch_dport[i];
|
||||
struct platform_device *pdev;
|
||||
|
||||
pdev = platform_device_alloc("cxl_mem", i);
|
||||
if (!pdev)
|
||||
goto err_mem;
|
||||
pdev->dev.parent = &dport->dev;
|
||||
set_dev_node(&pdev->dev, i % 2);
|
||||
|
||||
rc = platform_device_add(pdev);
|
||||
if (rc) {
|
||||
platform_device_put(pdev);
|
||||
goto err_mem;
|
||||
}
|
||||
cxl_mem[i] = pdev;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cxl_mem_single); i++) {
|
||||
struct platform_device *dport = cxl_swd_single[i];
|
||||
struct platform_device *pdev;
|
||||
|
||||
pdev = platform_device_alloc("cxl_mem", NR_MEM_MULTI + i);
|
||||
if (!pdev)
|
||||
goto err_single;
|
||||
pdev->dev.parent = &dport->dev;
|
||||
set_dev_node(&pdev->dev, i % 2);
|
||||
|
||||
rc = platform_device_add(pdev);
|
||||
if (rc) {
|
||||
platform_device_put(pdev);
|
||||
goto err_single;
|
||||
}
|
||||
cxl_mem_single[i] = pdev;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cxl_rcd); i++) {
|
||||
int idx = NR_MEM_MULTI + NR_MEM_SINGLE + i;
|
||||
struct platform_device *rch = cxl_rch[i];
|
||||
struct platform_device *pdev;
|
||||
|
||||
pdev = platform_device_alloc("cxl_rcd", idx);
|
||||
if (!pdev)
|
||||
goto err_rcd;
|
||||
pdev->dev.parent = &rch->dev;
|
||||
set_dev_node(&pdev->dev, i % 2);
|
||||
|
||||
rc = platform_device_add(pdev);
|
||||
if (rc) {
|
||||
platform_device_put(pdev);
|
||||
goto err_rcd;
|
||||
}
|
||||
cxl_rcd[i] = pdev;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_rcd:
|
||||
for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_rcd[i]);
|
||||
err_single:
|
||||
for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_mem_single[i]);
|
||||
err_mem:
|
||||
for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_mem[i]);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static __init int cxl_test_init(void)
|
||||
{
|
||||
int rc, i;
|
||||
@ -1403,29 +1441,11 @@ static __init int cxl_test_init(void)
|
||||
cxl_switch_dport[i] = pdev;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cxl_mem); i++) {
|
||||
struct platform_device *dport = cxl_switch_dport[i];
|
||||
struct platform_device *pdev;
|
||||
|
||||
pdev = platform_device_alloc("cxl_mem", i);
|
||||
if (!pdev)
|
||||
goto err_mem;
|
||||
pdev->dev.parent = &dport->dev;
|
||||
set_dev_node(&pdev->dev, i % 2);
|
||||
|
||||
rc = platform_device_add(pdev);
|
||||
if (rc) {
|
||||
platform_device_put(pdev);
|
||||
goto err_mem;
|
||||
}
|
||||
cxl_mem[i] = pdev;
|
||||
}
|
||||
|
||||
rc = cxl_single_init();
|
||||
rc = cxl_single_topo_init();
|
||||
if (rc)
|
||||
goto err_mem;
|
||||
goto err_dport;
|
||||
|
||||
rc = cxl_rch_init();
|
||||
rc = cxl_rch_topo_init();
|
||||
if (rc)
|
||||
goto err_single;
|
||||
|
||||
@ -1438,19 +1458,20 @@ static __init int cxl_test_init(void)
|
||||
|
||||
rc = platform_device_add(cxl_acpi);
|
||||
if (rc)
|
||||
goto err_add;
|
||||
goto err_root;
|
||||
|
||||
rc = cxl_mem_init();
|
||||
if (rc)
|
||||
goto err_root;
|
||||
|
||||
return 0;
|
||||
|
||||
err_add:
|
||||
err_root:
|
||||
platform_device_put(cxl_acpi);
|
||||
err_rch:
|
||||
cxl_rch_exit();
|
||||
cxl_rch_topo_exit();
|
||||
err_single:
|
||||
cxl_single_exit();
|
||||
err_mem:
|
||||
for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_mem[i]);
|
||||
cxl_single_topo_exit();
|
||||
err_dport:
|
||||
for (i = ARRAY_SIZE(cxl_switch_dport) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_switch_dport[i]);
|
||||
@ -1482,11 +1503,10 @@ static __exit void cxl_test_exit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
cxl_mem_exit();
|
||||
platform_device_unregister(cxl_acpi);
|
||||
cxl_rch_exit();
|
||||
cxl_single_exit();
|
||||
for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_mem[i]);
|
||||
cxl_rch_topo_exit();
|
||||
cxl_single_topo_exit();
|
||||
for (i = ARRAY_SIZE(cxl_switch_dport) - 1; i >= 0; i--)
|
||||
platform_device_unregister(cxl_switch_dport[i]);
|
||||
for (i = ARRAY_SIZE(cxl_switch_uport) - 1; i >= 0; i--)
|
||||
|
@ -1673,6 +1673,7 @@ static struct platform_driver cxl_mock_mem_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.dev_groups = cxl_mock_mem_groups,
|
||||
.groups = cxl_mock_mem_core_groups,
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user