Skip to content

Commit f847502

Browse files
weiny2djbw
authored andcommitted
cxl/mem: Account for partitionable space in ram/pmem ranges
Memory devices may specify volatile only, persistent only, and partitionable space which when added together result in a total capacity. If Identify Memory Device.Partition Alignment != 0 the device supports partitionable space. This partitionable space can be split between volatile and persistent space. The total volatile and persistent sizes are reported in Get Partition Info. ie active volatile memory = volatile only + partitionable volatile active persistent memory = persistent only + partitionable persistent Define cxl_mem_get_partition(), check for partitionable support, and use cxl_mem_get_partition() if applicable. Reviewed-by: Jonathan Cameron <[email protected]> Signed-off-by: Ira Weiny <[email protected]> Reported-by: kernel test robot <[email protected]> Signed-off-by: Dan Williams <[email protected]>
1 parent 0b9159d commit f847502

File tree

2 files changed

+96
-5
lines changed

2 files changed

+96
-5
lines changed

drivers/cxl/cxlmem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,10 @@ struct cxl_mem {
9999
u64 volatile_only_bytes;
100100
u64 persistent_only_bytes;
101101
u64 partition_align_bytes;
102+
103+
u64 active_volatile_bytes;
104+
u64 active_persistent_bytes;
105+
u64 next_volatile_bytes;
106+
u64 next_persistent_bytes;
102107
};
103108
#endif /* __CXL_MEM_H__ */

drivers/cxl/pci.c

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,53 @@ static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_mem *cxlm)
12631263
return ret;
12641264
}
12651265

1266+
/**
1267+
* cxl_mem_get_partition_info - Get partition info
1268+
* @cxlm: The device to act on
1269+
* @active_volatile_bytes: returned active volatile capacity
1270+
* @active_persistent_bytes: returned active persistent capacity
1271+
* @next_volatile_bytes: return next volatile capacity
1272+
* @next_persistent_bytes: return next persistent capacity
1273+
*
1274+
* Retrieve the current partition info for the device specified. If not 0, the
1275+
* 'next' values are pending and take affect on next cold reset.
1276+
*
1277+
* Return: 0 if no error: or the result of the mailbox command.
1278+
*
1279+
* See CXL @8.2.9.5.2.1 Get Partition Info
1280+
*/
1281+
static int cxl_mem_get_partition_info(struct cxl_mem *cxlm,
1282+
u64 *active_volatile_bytes,
1283+
u64 *active_persistent_bytes,
1284+
u64 *next_volatile_bytes,
1285+
u64 *next_persistent_bytes)
1286+
{
1287+
struct cxl_mbox_get_partition_info {
1288+
__le64 active_volatile_cap;
1289+
__le64 active_persistent_cap;
1290+
__le64 next_volatile_cap;
1291+
__le64 next_persistent_cap;
1292+
} __packed pi;
1293+
int rc;
1294+
1295+
rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_PARTITION_INFO,
1296+
NULL, 0, &pi, sizeof(pi));
1297+
if (rc)
1298+
return rc;
1299+
1300+
*active_volatile_bytes = le64_to_cpu(pi.active_volatile_cap);
1301+
*active_persistent_bytes = le64_to_cpu(pi.active_persistent_cap);
1302+
*next_volatile_bytes = le64_to_cpu(pi.next_volatile_cap);
1303+
*next_persistent_bytes = le64_to_cpu(pi.next_volatile_cap);
1304+
1305+
*active_volatile_bytes *= CXL_CAPACITY_MULTIPLIER;
1306+
*active_persistent_bytes *= CXL_CAPACITY_MULTIPLIER;
1307+
*next_volatile_bytes *= CXL_CAPACITY_MULTIPLIER;
1308+
*next_persistent_bytes *= CXL_CAPACITY_MULTIPLIER;
1309+
1310+
return 0;
1311+
}
1312+
12661313
/**
12671314
* cxl_mem_enumerate_cmds() - Enumerate commands for a device.
12681315
* @cxlm: The device.
@@ -1381,18 +1428,53 @@ static int cxl_mem_identify(struct cxl_mem *cxlm)
13811428
cxlm->persistent_only_bytes,
13821429
cxlm->partition_align_bytes);
13831430

1431+
cxlm->lsa_size = le32_to_cpu(id.lsa_size);
1432+
memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision));
1433+
1434+
return 0;
1435+
}
1436+
1437+
static int cxl_mem_create_range_info(struct cxl_mem *cxlm)
1438+
{
1439+
int rc;
1440+
1441+
if (cxlm->partition_align_bytes == 0) {
1442+
cxlm->ram_range.start = 0;
1443+
cxlm->ram_range.end = cxlm->volatile_only_bytes - 1;
1444+
cxlm->pmem_range.start = 0;
1445+
cxlm->pmem_range.end = cxlm->persistent_only_bytes - 1;
1446+
return 0;
1447+
}
1448+
1449+
rc = cxl_mem_get_partition_info(cxlm,
1450+
&cxlm->active_volatile_bytes,
1451+
&cxlm->active_persistent_bytes,
1452+
&cxlm->next_volatile_bytes,
1453+
&cxlm->next_persistent_bytes);
1454+
if (rc < 0) {
1455+
dev_err(&cxlm->pdev->dev, "Failed to query partition information\n");
1456+
return rc;
1457+
}
1458+
1459+
dev_dbg(&cxlm->pdev->dev, "Get Partition Info\n"
1460+
" active_volatile_bytes = %#llx\n"
1461+
" active_persistent_bytes = %#llx\n"
1462+
" next_volatile_bytes = %#llx\n"
1463+
" next_persistent_bytes = %#llx\n",
1464+
cxlm->active_volatile_bytes,
1465+
cxlm->active_persistent_bytes,
1466+
cxlm->next_volatile_bytes,
1467+
cxlm->next_persistent_bytes);
1468+
13841469
/*
13851470
* TODO: enumerate DPA map, as 'ram' and 'pmem' do not alias.
13861471
* For now, only the capacity is exported in sysfs
13871472
*/
13881473
cxlm->ram_range.start = 0;
1389-
cxlm->ram_range.end = cxlm->volatile_only_bytes - 1;
1474+
cxlm->ram_range.end = cxlm->active_volatile_bytes - 1;
13901475

13911476
cxlm->pmem_range.start = 0;
1392-
cxlm->pmem_range.end = cxlm->persistent_only_bytes - 1;
1393-
1394-
cxlm->lsa_size = le32_to_cpu(id.lsa_size);
1395-
memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision));
1477+
cxlm->pmem_range.end = cxlm->active_persistent_bytes - 1;
13961478

13971479
return 0;
13981480
}
@@ -1427,6 +1509,10 @@ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
14271509
if (rc)
14281510
return rc;
14291511

1512+
rc = cxl_mem_create_range_info(cxlm);
1513+
if (rc)
1514+
return rc;
1515+
14301516
cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlm, &cxl_memdev_fops);
14311517
if (IS_ERR(cxlmd))
14321518
return PTR_ERR(cxlmd);

0 commit comments

Comments
 (0)