tools/testing/cxl: Add partition support
In support of testing DPA allocation mechanisms in the CXL core, the cxl_test environment needs to support establishing and retrieving the 'pmem partition boundary. Replace the platform_device_add_resources() method for delineating DPA within an endpoint with an emulated DEV_SIZE amount of partitionable capacity. Set DEV_SIZE such that an endpoint has enough capacity to simultaneously participate in 8 distinct regions. Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Link: https://lore.kernel.org/r/165603887411.551046.13234212587991192347.stgit@dwillia2-xfh Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
@@ -718,12 +718,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, CXL);
|
|||||||
*/
|
*/
|
||||||
static int cxl_mem_get_partition_info(struct cxl_dev_state *cxlds)
|
static int cxl_mem_get_partition_info(struct cxl_dev_state *cxlds)
|
||||||
{
|
{
|
||||||
struct cxl_mbox_get_partition_info {
|
struct cxl_mbox_get_partition_info pi;
|
||||||
__le64 active_volatile_cap;
|
|
||||||
__le64 active_persistent_cap;
|
|
||||||
__le64 next_volatile_cap;
|
|
||||||
__le64 next_persistent_cap;
|
|
||||||
} __packed pi;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_PARTITION_INFO, NULL, 0,
|
rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_PARTITION_INFO, NULL, 0,
|
||||||
|
|||||||
@@ -301,6 +301,13 @@ struct cxl_mbox_identify {
|
|||||||
u8 qos_telemetry_caps;
|
u8 qos_telemetry_caps;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct cxl_mbox_get_partition_info {
|
||||||
|
__le64 active_volatile_cap;
|
||||||
|
__le64 active_persistent_cap;
|
||||||
|
__le64 next_volatile_cap;
|
||||||
|
__le64 next_persistent_cap;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct cxl_mbox_get_lsa {
|
struct cxl_mbox_get_lsa {
|
||||||
__le32 offset;
|
__le32 offset;
|
||||||
__le32 length;
|
__le32 length;
|
||||||
|
|||||||
@@ -569,44 +569,6 @@ static void mock_companion(struct acpi_device *adev, struct device *dev)
|
|||||||
#define SZ_512G (SZ_64G * 8)
|
#define SZ_512G (SZ_64G * 8)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct platform_device *alloc_memdev(int id)
|
|
||||||
{
|
|
||||||
struct resource res[] = {
|
|
||||||
[0] = {
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
[1] = {
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
.desc = IORES_DESC_PERSISTENT_MEMORY,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
struct platform_device *pdev;
|
|
||||||
int i, rc;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(res); i++) {
|
|
||||||
struct cxl_mock_res *r = alloc_mock_res(SZ_256M);
|
|
||||||
|
|
||||||
if (!r)
|
|
||||||
return NULL;
|
|
||||||
res[i].start = r->range.start;
|
|
||||||
res[i].end = r->range.end;
|
|
||||||
}
|
|
||||||
|
|
||||||
pdev = platform_device_alloc("cxl_mem", id);
|
|
||||||
if (!pdev)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
rc = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
|
|
||||||
if (rc)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
return pdev;
|
|
||||||
|
|
||||||
err:
|
|
||||||
platform_device_put(pdev);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __init int cxl_test_init(void)
|
static __init int cxl_test_init(void)
|
||||||
{
|
{
|
||||||
int rc, i;
|
int rc, i;
|
||||||
@@ -709,7 +671,7 @@ static __init int cxl_test_init(void)
|
|||||||
struct platform_device *dport = cxl_switch_dport[i];
|
struct platform_device *dport = cxl_switch_dport[i];
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
|
|
||||||
pdev = alloc_memdev(i);
|
pdev = platform_device_alloc("cxl_mem", i);
|
||||||
if (!pdev)
|
if (!pdev)
|
||||||
goto err_mem;
|
goto err_mem;
|
||||||
pdev->dev.parent = &dport->dev;
|
pdev->dev.parent = &dport->dev;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <cxlmem.h>
|
#include <cxlmem.h>
|
||||||
|
|
||||||
#define LSA_SIZE SZ_128K
|
#define LSA_SIZE SZ_128K
|
||||||
|
#define DEV_SIZE SZ_2G
|
||||||
#define EFFECT(x) (1U << x)
|
#define EFFECT(x) (1U << x)
|
||||||
|
|
||||||
static struct cxl_cel_entry mock_cel[] = {
|
static struct cxl_cel_entry mock_cel[] = {
|
||||||
@@ -25,6 +26,10 @@ static struct cxl_cel_entry mock_cel[] = {
|
|||||||
.opcode = cpu_to_le16(CXL_MBOX_OP_GET_LSA),
|
.opcode = cpu_to_le16(CXL_MBOX_OP_GET_LSA),
|
||||||
.effect = cpu_to_le16(0),
|
.effect = cpu_to_le16(0),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.opcode = cpu_to_le16(CXL_MBOX_OP_GET_PARTITION_INFO),
|
||||||
|
.effect = cpu_to_le16(0),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.opcode = cpu_to_le16(CXL_MBOX_OP_SET_LSA),
|
.opcode = cpu_to_le16(CXL_MBOX_OP_SET_LSA),
|
||||||
.effect = cpu_to_le16(EFFECT(1) | EFFECT(2)),
|
.effect = cpu_to_le16(EFFECT(1) | EFFECT(2)),
|
||||||
@@ -97,46 +102,41 @@ static int mock_get_log(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd)
|
|||||||
|
|
||||||
static int mock_id(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd)
|
static int mock_id(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = to_platform_device(cxlds->dev);
|
|
||||||
struct cxl_mbox_identify id = {
|
struct cxl_mbox_identify id = {
|
||||||
.fw_revision = { "mock fw v1 " },
|
.fw_revision = { "mock fw v1 " },
|
||||||
.lsa_size = cpu_to_le32(LSA_SIZE),
|
.lsa_size = cpu_to_le32(LSA_SIZE),
|
||||||
/* FIXME: Add partition support */
|
.partition_align =
|
||||||
.partition_align = cpu_to_le64(0),
|
cpu_to_le64(SZ_256M / CXL_CAPACITY_MULTIPLIER),
|
||||||
|
.total_capacity =
|
||||||
|
cpu_to_le64(DEV_SIZE / CXL_CAPACITY_MULTIPLIER),
|
||||||
};
|
};
|
||||||
u64 capacity = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (cmd->size_out < sizeof(id))
|
if (cmd->size_out < sizeof(id))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
struct resource *res;
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
|
|
||||||
if (!res)
|
|
||||||
break;
|
|
||||||
|
|
||||||
capacity += resource_size(res) / CXL_CAPACITY_MULTIPLIER;
|
|
||||||
|
|
||||||
if (le64_to_cpu(id.partition_align))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (res->desc == IORES_DESC_PERSISTENT_MEMORY)
|
|
||||||
id.persistent_capacity = cpu_to_le64(
|
|
||||||
resource_size(res) / CXL_CAPACITY_MULTIPLIER);
|
|
||||||
else
|
|
||||||
id.volatile_capacity = cpu_to_le64(
|
|
||||||
resource_size(res) / CXL_CAPACITY_MULTIPLIER);
|
|
||||||
}
|
|
||||||
|
|
||||||
id.total_capacity = cpu_to_le64(capacity);
|
|
||||||
|
|
||||||
memcpy(cmd->payload_out, &id, sizeof(id));
|
memcpy(cmd->payload_out, &id, sizeof(id));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mock_partition_info(struct cxl_dev_state *cxlds,
|
||||||
|
struct cxl_mbox_cmd *cmd)
|
||||||
|
{
|
||||||
|
struct cxl_mbox_get_partition_info pi = {
|
||||||
|
.active_volatile_cap =
|
||||||
|
cpu_to_le64(DEV_SIZE / 2 / CXL_CAPACITY_MULTIPLIER),
|
||||||
|
.active_persistent_cap =
|
||||||
|
cpu_to_le64(DEV_SIZE / 2 / CXL_CAPACITY_MULTIPLIER),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cmd->size_out < sizeof(pi))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
memcpy(cmd->payload_out, &pi, sizeof(pi));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd)
|
static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd)
|
||||||
{
|
{
|
||||||
struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in;
|
struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in;
|
||||||
@@ -221,6 +221,9 @@ static int cxl_mock_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *
|
|||||||
case CXL_MBOX_OP_GET_LSA:
|
case CXL_MBOX_OP_GET_LSA:
|
||||||
rc = mock_get_lsa(cxlds, cmd);
|
rc = mock_get_lsa(cxlds, cmd);
|
||||||
break;
|
break;
|
||||||
|
case CXL_MBOX_OP_GET_PARTITION_INFO:
|
||||||
|
rc = mock_partition_info(cxlds, cmd);
|
||||||
|
break;
|
||||||
case CXL_MBOX_OP_SET_LSA:
|
case CXL_MBOX_OP_SET_LSA:
|
||||||
rc = mock_set_lsa(cxlds, cmd);
|
rc = mock_set_lsa(cxlds, cmd);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user