Commit f847502a authored by Ira Weiny's avatar Ira Weiny Committed by Dan Williams

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: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: default avatarIra Weiny <ira.weiny@intel.com>
Reported-by: default avatarkernel test robot <lkp@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 0b9159d0
...@@ -99,5 +99,10 @@ struct cxl_mem { ...@@ -99,5 +99,10 @@ struct cxl_mem {
u64 volatile_only_bytes; u64 volatile_only_bytes;
u64 persistent_only_bytes; u64 persistent_only_bytes;
u64 partition_align_bytes; u64 partition_align_bytes;
u64 active_volatile_bytes;
u64 active_persistent_bytes;
u64 next_volatile_bytes;
u64 next_persistent_bytes;
}; };
#endif /* __CXL_MEM_H__ */ #endif /* __CXL_MEM_H__ */
...@@ -1263,6 +1263,53 @@ static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_mem *cxlm) ...@@ -1263,6 +1263,53 @@ static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_mem *cxlm)
return ret; return ret;
} }
/**
* cxl_mem_get_partition_info - Get partition info
* @cxlm: The device to act on
* @active_volatile_bytes: returned active volatile capacity
* @active_persistent_bytes: returned active persistent capacity
* @next_volatile_bytes: return next volatile capacity
* @next_persistent_bytes: return next persistent capacity
*
* Retrieve the current partition info for the device specified. If not 0, the
* 'next' values are pending and take affect on next cold reset.
*
* Return: 0 if no error: or the result of the mailbox command.
*
* See CXL @8.2.9.5.2.1 Get Partition Info
*/
static int cxl_mem_get_partition_info(struct cxl_mem *cxlm,
u64 *active_volatile_bytes,
u64 *active_persistent_bytes,
u64 *next_volatile_bytes,
u64 *next_persistent_bytes)
{
struct cxl_mbox_get_partition_info {
__le64 active_volatile_cap;
__le64 active_persistent_cap;
__le64 next_volatile_cap;
__le64 next_persistent_cap;
} __packed pi;
int rc;
rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_PARTITION_INFO,
NULL, 0, &pi, sizeof(pi));
if (rc)
return rc;
*active_volatile_bytes = le64_to_cpu(pi.active_volatile_cap);
*active_persistent_bytes = le64_to_cpu(pi.active_persistent_cap);
*next_volatile_bytes = le64_to_cpu(pi.next_volatile_cap);
*next_persistent_bytes = le64_to_cpu(pi.next_volatile_cap);
*active_volatile_bytes *= CXL_CAPACITY_MULTIPLIER;
*active_persistent_bytes *= CXL_CAPACITY_MULTIPLIER;
*next_volatile_bytes *= CXL_CAPACITY_MULTIPLIER;
*next_persistent_bytes *= CXL_CAPACITY_MULTIPLIER;
return 0;
}
/** /**
* cxl_mem_enumerate_cmds() - Enumerate commands for a device. * cxl_mem_enumerate_cmds() - Enumerate commands for a device.
* @cxlm: The device. * @cxlm: The device.
...@@ -1381,18 +1428,53 @@ static int cxl_mem_identify(struct cxl_mem *cxlm) ...@@ -1381,18 +1428,53 @@ static int cxl_mem_identify(struct cxl_mem *cxlm)
cxlm->persistent_only_bytes, cxlm->persistent_only_bytes,
cxlm->partition_align_bytes); cxlm->partition_align_bytes);
cxlm->lsa_size = le32_to_cpu(id.lsa_size);
memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision));
return 0;
}
static int cxl_mem_create_range_info(struct cxl_mem *cxlm)
{
int rc;
if (cxlm->partition_align_bytes == 0) {
cxlm->ram_range.start = 0;
cxlm->ram_range.end = cxlm->volatile_only_bytes - 1;
cxlm->pmem_range.start = 0;
cxlm->pmem_range.end = cxlm->persistent_only_bytes - 1;
return 0;
}
rc = cxl_mem_get_partition_info(cxlm,
&cxlm->active_volatile_bytes,
&cxlm->active_persistent_bytes,
&cxlm->next_volatile_bytes,
&cxlm->next_persistent_bytes);
if (rc < 0) {
dev_err(&cxlm->pdev->dev, "Failed to query partition information\n");
return rc;
}
dev_dbg(&cxlm->pdev->dev, "Get Partition Info\n"
" active_volatile_bytes = %#llx\n"
" active_persistent_bytes = %#llx\n"
" next_volatile_bytes = %#llx\n"
" next_persistent_bytes = %#llx\n",
cxlm->active_volatile_bytes,
cxlm->active_persistent_bytes,
cxlm->next_volatile_bytes,
cxlm->next_persistent_bytes);
/* /*
* TODO: enumerate DPA map, as 'ram' and 'pmem' do not alias. * TODO: enumerate DPA map, as 'ram' and 'pmem' do not alias.
* For now, only the capacity is exported in sysfs * For now, only the capacity is exported in sysfs
*/ */
cxlm->ram_range.start = 0; cxlm->ram_range.start = 0;
cxlm->ram_range.end = cxlm->volatile_only_bytes - 1; cxlm->ram_range.end = cxlm->active_volatile_bytes - 1;
cxlm->pmem_range.start = 0; cxlm->pmem_range.start = 0;
cxlm->pmem_range.end = cxlm->persistent_only_bytes - 1; cxlm->pmem_range.end = cxlm->active_persistent_bytes - 1;
cxlm->lsa_size = le32_to_cpu(id.lsa_size);
memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision));
return 0; return 0;
} }
...@@ -1427,6 +1509,10 @@ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1427,6 +1509,10 @@ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc) if (rc)
return rc; return rc;
rc = cxl_mem_create_range_info(cxlm);
if (rc)
return rc;
cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlm, &cxl_memdev_fops); cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlm, &cxl_memdev_fops);
if (IS_ERR(cxlmd)) if (IS_ERR(cxlmd))
return PTR_ERR(cxlmd); return PTR_ERR(cxlmd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment