203 lines
6.4 KiB
Diff
203 lines
6.4 KiB
Diff
|
From 4f588b964dccf72030b1c432ed5dd8e2856f9d38 Mon Sep 17 00:00:00 2001
|
||
|
From: Alison Schofield <alison.schofield@intel.com>
|
||
|
Date: Tue, 22 Feb 2022 11:56:03 -0800
|
||
|
Subject: [PATCH 132/217] libcxl: add GET_PARTITION_INFO mailbox command and
|
||
|
accessors
|
||
|
|
||
|
The CXL PMEM provisioning model depends upon the values reported
|
||
|
in the CXL GET_PARTITION_INFO mailbox command when changing the
|
||
|
partitioning between volatile and persistent capacity.
|
||
|
|
||
|
Add libcxl APIs to create a new GET_PARTITION_INFO mailbox command,
|
||
|
the command output data structure (privately), and accessor APIs to
|
||
|
return the fields in the partition info output.
|
||
|
|
||
|
Per the CXL 2.0 specification, devices report partition capacities
|
||
|
as multiples of 256MB. Define and use a capacity multiplier to
|
||
|
convert the raw data into bytes for user consumption. Use byte
|
||
|
format as the norm for all capacity values produced or consumed
|
||
|
using CXL Mailbox commands.
|
||
|
|
||
|
Link: https://lore.kernel.org/r/6cd7fffe1a95c9a1bc2239cb342067df564401a5.1645558189.git.alison.schofield@intel.com
|
||
|
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
|
||
|
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
|
||
|
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
|
||
|
---
|
||
|
Documentation/cxl/lib/libcxl.txt | 1 +
|
||
|
cxl/lib/libcxl.c | 66 ++++++++++++++++++++++++++++++++
|
||
|
cxl/lib/libcxl.sym | 5 +++
|
||
|
cxl/lib/private.h | 10 +++++
|
||
|
cxl/libcxl.h | 5 +++
|
||
|
util/size.h | 1 +
|
||
|
6 files changed, 88 insertions(+)
|
||
|
|
||
|
diff --git a/Documentation/cxl/lib/libcxl.txt b/Documentation/cxl/lib/libcxl.txt
|
||
|
index 4392b47..a6986ab 100644
|
||
|
--- a/Documentation/cxl/lib/libcxl.txt
|
||
|
+++ b/Documentation/cxl/lib/libcxl.txt
|
||
|
@@ -131,6 +131,7 @@ int cxl_memdev_read_label(struct cxl_memdev *memdev, void *buf, size_t length,
|
||
|
size_t offset);
|
||
|
int cxl_memdev_write_label(struct cxl_memdev *memdev, void *buf, size_t length,
|
||
|
size_t offset);
|
||
|
+struct cxl_cmd *cxl_cmd_new_get_partition(struct cxl_memdev *memdev);
|
||
|
|
||
|
----
|
||
|
|
||
|
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
|
||
|
index e0b443f..4557a71 100644
|
||
|
--- a/cxl/lib/libcxl.c
|
||
|
+++ b/cxl/lib/libcxl.c
|
||
|
@@ -1985,6 +1985,11 @@ static int cxl_cmd_validate_status(struct cxl_cmd *cmd, u32 id)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static uint64_t cxl_capacity_to_bytes(leint64_t size)
|
||
|
+{
|
||
|
+ return le64_to_cpu(size) * CXL_CAPACITY_MULTIPLIER;
|
||
|
+}
|
||
|
+
|
||
|
/* Helpers for health_info fields (no endian conversion) */
|
||
|
#define cmd_get_field_u8(cmd, n, N, field) \
|
||
|
do { \
|
||
|
@@ -2371,6 +2376,67 @@ CXL_EXPORT ssize_t cxl_cmd_read_label_get_payload(struct cxl_cmd *cmd,
|
||
|
return length;
|
||
|
}
|
||
|
|
||
|
+CXL_EXPORT struct cxl_cmd *cxl_cmd_new_get_partition(struct cxl_memdev *memdev)
|
||
|
+{
|
||
|
+ return cxl_cmd_new_generic(memdev,
|
||
|
+ CXL_MEM_COMMAND_ID_GET_PARTITION_INFO);
|
||
|
+}
|
||
|
+
|
||
|
+static struct cxl_cmd_get_partition *
|
||
|
+cmd_to_get_partition(struct cxl_cmd *cmd)
|
||
|
+{
|
||
|
+ if (cxl_cmd_validate_status(cmd, CXL_MEM_COMMAND_ID_GET_PARTITION_INFO))
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ if (!cmd)
|
||
|
+ return NULL;
|
||
|
+ return cmd->output_payload;
|
||
|
+}
|
||
|
+
|
||
|
+CXL_EXPORT unsigned long long
|
||
|
+cxl_cmd_partition_get_active_volatile_size(struct cxl_cmd *cmd)
|
||
|
+{
|
||
|
+ struct cxl_cmd_get_partition *c;
|
||
|
+
|
||
|
+ c = cmd_to_get_partition(cmd);
|
||
|
+ if (!c)
|
||
|
+ return ULLONG_MAX;
|
||
|
+ return cxl_capacity_to_bytes(c->active_volatile);
|
||
|
+}
|
||
|
+
|
||
|
+CXL_EXPORT unsigned long long
|
||
|
+cxl_cmd_partition_get_active_persistent_size(struct cxl_cmd *cmd)
|
||
|
+{
|
||
|
+ struct cxl_cmd_get_partition *c;
|
||
|
+
|
||
|
+ c = cmd_to_get_partition(cmd);
|
||
|
+ if (!c)
|
||
|
+ return ULLONG_MAX;
|
||
|
+ return cxl_capacity_to_bytes(c->active_persistent);
|
||
|
+}
|
||
|
+
|
||
|
+CXL_EXPORT unsigned long long
|
||
|
+cxl_cmd_partition_get_next_volatile_size(struct cxl_cmd *cmd)
|
||
|
+{
|
||
|
+ struct cxl_cmd_get_partition *c;
|
||
|
+
|
||
|
+ c = cmd_to_get_partition(cmd);
|
||
|
+ if (!c)
|
||
|
+ return ULLONG_MAX;
|
||
|
+ return cxl_capacity_to_bytes(c->next_volatile);
|
||
|
+}
|
||
|
+
|
||
|
+CXL_EXPORT unsigned long long
|
||
|
+cxl_cmd_partition_get_next_persistent_size(struct cxl_cmd *cmd)
|
||
|
+{
|
||
|
+ struct cxl_cmd_get_partition *c;
|
||
|
+
|
||
|
+ c = cmd_to_get_partition(cmd);
|
||
|
+ if (!c)
|
||
|
+ return ULLONG_MAX;
|
||
|
+ return cxl_capacity_to_bytes(c->next_persistent);
|
||
|
+}
|
||
|
+
|
||
|
CXL_EXPORT int cxl_cmd_submit(struct cxl_cmd *cmd)
|
||
|
{
|
||
|
struct cxl_memdev *memdev = cmd->memdev;
|
||
|
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
|
||
|
index e56a2bf..509e62d 100644
|
||
|
--- a/cxl/lib/libcxl.sym
|
||
|
+++ b/cxl/lib/libcxl.sym
|
||
|
@@ -155,4 +155,9 @@ global:
|
||
|
cxl_dport_get_port;
|
||
|
cxl_port_get_dport_by_memdev;
|
||
|
cxl_dport_maps_memdev;
|
||
|
+ cxl_cmd_new_get_partition;
|
||
|
+ cxl_cmd_partition_get_active_volatile_size;
|
||
|
+ cxl_cmd_partition_get_active_persistent_size;
|
||
|
+ cxl_cmd_partition_get_next_volatile_size;
|
||
|
+ cxl_cmd_partition_get_next_persistent_size;
|
||
|
} LIBCXL_1;
|
||
|
diff --git a/cxl/lib/private.h b/cxl/lib/private.h
|
||
|
index f483c30..7f3a562 100644
|
||
|
--- a/cxl/lib/private.h
|
||
|
+++ b/cxl/lib/private.h
|
||
|
@@ -7,6 +7,7 @@
|
||
|
#include <cxl/cxl_mem.h>
|
||
|
#include <ccan/endian/endian.h>
|
||
|
#include <ccan/short_types/short_types.h>
|
||
|
+#include <util/size.h>
|
||
|
|
||
|
#define CXL_EXPORT __attribute__ ((visibility("default")))
|
||
|
|
||
|
@@ -185,6 +186,15 @@ struct cxl_cmd_get_health_info {
|
||
|
le32 pmem_errors;
|
||
|
} __attribute__((packed));
|
||
|
|
||
|
+struct cxl_cmd_get_partition {
|
||
|
+ le64 active_volatile;
|
||
|
+ le64 active_persistent;
|
||
|
+ le64 next_volatile;
|
||
|
+ le64 next_persistent;
|
||
|
+} __attribute__((packed));
|
||
|
+
|
||
|
+#define CXL_CAPACITY_MULTIPLIER SZ_256M
|
||
|
+
|
||
|
/* CXL 2.0 8.2.9.5.3 Byte 0 Health Status */
|
||
|
#define CXL_CMD_HEALTH_INFO_STATUS_MAINTENANCE_NEEDED_MASK BIT(0)
|
||
|
#define CXL_CMD_HEALTH_INFO_STATUS_PERFORMANCE_DEGRADED_MASK BIT(1)
|
||
|
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
|
||
|
index 3b2293b..2c0a8d1 100644
|
||
|
--- a/cxl/libcxl.h
|
||
|
+++ b/cxl/libcxl.h
|
||
|
@@ -242,6 +242,11 @@ ssize_t cxl_cmd_read_label_get_payload(struct cxl_cmd *cmd, void *buf,
|
||
|
unsigned int length);
|
||
|
struct cxl_cmd *cxl_cmd_new_write_label(struct cxl_memdev *memdev,
|
||
|
void *buf, unsigned int offset, unsigned int length);
|
||
|
+struct cxl_cmd *cxl_cmd_new_get_partition(struct cxl_memdev *memdev);
|
||
|
+unsigned long long cxl_cmd_partition_get_active_volatile_size(struct cxl_cmd *cmd);
|
||
|
+unsigned long long cxl_cmd_partition_get_active_persistent_size(struct cxl_cmd *cmd);
|
||
|
+unsigned long long cxl_cmd_partition_get_next_volatile_size(struct cxl_cmd *cmd);
|
||
|
+unsigned long long cxl_cmd_partition_get_next_persistent_size(struct cxl_cmd *cmd);
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
} /* extern "C" */
|
||
|
diff --git a/util/size.h b/util/size.h
|
||
|
index a0f3593..e72467f 100644
|
||
|
--- a/util/size.h
|
||
|
+++ b/util/size.h
|
||
|
@@ -15,6 +15,7 @@
|
||
|
#define SZ_4M 0x00400000
|
||
|
#define SZ_16M 0x01000000
|
||
|
#define SZ_64M 0x04000000
|
||
|
+#define SZ_256M 0x10000000
|
||
|
#define SZ_1G 0x40000000
|
||
|
#define SZ_1T 0x10000000000ULL
|
||
|
|
||
|
--
|
||
|
2.27.0
|
||
|
|