libnvdimm/labels: Introduce CXL labels
Now that all of use sites of label data have been converted to nsl_* helpers, introduce the CXL label format. The ->cxl flag in nvdimm_drvdata indicates the label format the device expects. A follow-on patch allows a bus provider to select the label style. Note that the EFI definition of the labels represents the Linux "claim class" with a GUID. The CXL definition of the labels stores the same identifier in UUID byte order. Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Link: https://lore.kernel.org/r/163116432405.2460985.5547867384570123403.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
@@ -17,6 +17,14 @@ static guid_t nvdimm_btt2_guid;
|
||||
static guid_t nvdimm_pfn_guid;
|
||||
static guid_t nvdimm_dax_guid;
|
||||
|
||||
static uuid_t nvdimm_btt_uuid;
|
||||
static uuid_t nvdimm_btt2_uuid;
|
||||
static uuid_t nvdimm_pfn_uuid;
|
||||
static uuid_t nvdimm_dax_uuid;
|
||||
|
||||
static uuid_t cxl_region_uuid;
|
||||
static uuid_t cxl_namespace_uuid;
|
||||
|
||||
static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0";
|
||||
|
||||
static u32 best_seq(u32 a, u32 b)
|
||||
@@ -352,7 +360,7 @@ static bool nsl_validate_checksum(struct nvdimm_drvdata *ndd,
|
||||
{
|
||||
u64 sum, sum_save;
|
||||
|
||||
if (!namespace_label_has(ndd, checksum))
|
||||
if (!ndd->cxl && !efi_namespace_label_has(ndd, checksum))
|
||||
return true;
|
||||
|
||||
sum_save = nsl_get_checksum(ndd, nd_label);
|
||||
@@ -367,7 +375,7 @@ static void nsl_calculate_checksum(struct nvdimm_drvdata *ndd,
|
||||
{
|
||||
u64 sum;
|
||||
|
||||
if (!namespace_label_has(ndd, checksum))
|
||||
if (!ndd->cxl && !efi_namespace_label_has(ndd, checksum))
|
||||
return;
|
||||
nsl_set_checksum(ndd, nd_label, 0);
|
||||
sum = nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1);
|
||||
@@ -725,7 +733,7 @@ static unsigned long nd_label_offset(struct nvdimm_drvdata *ndd,
|
||||
- (unsigned long) to_namespace_index(ndd, 0);
|
||||
}
|
||||
|
||||
static enum nvdimm_claim_class to_nvdimm_cclass(guid_t *guid)
|
||||
static enum nvdimm_claim_class guid_to_nvdimm_cclass(guid_t *guid)
|
||||
{
|
||||
if (guid_equal(guid, &nvdimm_btt_guid))
|
||||
return NVDIMM_CCLASS_BTT;
|
||||
@@ -741,6 +749,23 @@ static enum nvdimm_claim_class to_nvdimm_cclass(guid_t *guid)
|
||||
return NVDIMM_CCLASS_UNKNOWN;
|
||||
}
|
||||
|
||||
/* CXL labels store UUIDs instead of GUIDs for the same data */
|
||||
static enum nvdimm_claim_class uuid_to_nvdimm_cclass(uuid_t *uuid)
|
||||
{
|
||||
if (uuid_equal(uuid, &nvdimm_btt_uuid))
|
||||
return NVDIMM_CCLASS_BTT;
|
||||
else if (uuid_equal(uuid, &nvdimm_btt2_uuid))
|
||||
return NVDIMM_CCLASS_BTT2;
|
||||
else if (uuid_equal(uuid, &nvdimm_pfn_uuid))
|
||||
return NVDIMM_CCLASS_PFN;
|
||||
else if (uuid_equal(uuid, &nvdimm_dax_uuid))
|
||||
return NVDIMM_CCLASS_DAX;
|
||||
else if (uuid_equal(uuid, &uuid_null))
|
||||
return NVDIMM_CCLASS_NONE;
|
||||
|
||||
return NVDIMM_CCLASS_UNKNOWN;
|
||||
}
|
||||
|
||||
static const guid_t *to_abstraction_guid(enum nvdimm_claim_class claim_class,
|
||||
guid_t *target)
|
||||
{
|
||||
@@ -762,6 +787,28 @@ static const guid_t *to_abstraction_guid(enum nvdimm_claim_class claim_class,
|
||||
return &guid_null;
|
||||
}
|
||||
|
||||
/* CXL labels store UUIDs instead of GUIDs for the same data */
|
||||
static const uuid_t *to_abstraction_uuid(enum nvdimm_claim_class claim_class,
|
||||
uuid_t *target)
|
||||
{
|
||||
if (claim_class == NVDIMM_CCLASS_BTT)
|
||||
return &nvdimm_btt_uuid;
|
||||
else if (claim_class == NVDIMM_CCLASS_BTT2)
|
||||
return &nvdimm_btt2_uuid;
|
||||
else if (claim_class == NVDIMM_CCLASS_PFN)
|
||||
return &nvdimm_pfn_uuid;
|
||||
else if (claim_class == NVDIMM_CCLASS_DAX)
|
||||
return &nvdimm_dax_uuid;
|
||||
else if (claim_class == NVDIMM_CCLASS_UNKNOWN) {
|
||||
/*
|
||||
* If we're modifying a namespace for which we don't
|
||||
* know the claim_class, don't touch the existing uuid.
|
||||
*/
|
||||
return target;
|
||||
} else
|
||||
return &uuid_null;
|
||||
}
|
||||
|
||||
static void reap_victim(struct nd_mapping *nd_mapping,
|
||||
struct nd_label_ent *victim)
|
||||
{
|
||||
@@ -776,18 +823,18 @@ static void reap_victim(struct nd_mapping *nd_mapping,
|
||||
static void nsl_set_type_guid(struct nvdimm_drvdata *ndd,
|
||||
struct nd_namespace_label *nd_label, guid_t *guid)
|
||||
{
|
||||
if (namespace_label_has(ndd, type_guid))
|
||||
guid_copy(&nd_label->type_guid, guid);
|
||||
if (efi_namespace_label_has(ndd, type_guid))
|
||||
guid_copy(&nd_label->efi.type_guid, guid);
|
||||
}
|
||||
|
||||
bool nsl_validate_type_guid(struct nvdimm_drvdata *ndd,
|
||||
struct nd_namespace_label *nd_label, guid_t *guid)
|
||||
{
|
||||
if (!namespace_label_has(ndd, type_guid))
|
||||
if (ndd->cxl || !efi_namespace_label_has(ndd, type_guid))
|
||||
return true;
|
||||
if (!guid_equal(&nd_label->type_guid, guid)) {
|
||||
if (!guid_equal(&nd_label->efi.type_guid, guid)) {
|
||||
dev_dbg(ndd->dev, "expect type_guid %pUb got %pUb\n", guid,
|
||||
&nd_label->type_guid);
|
||||
&nd_label->efi.type_guid);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -797,19 +844,34 @@ static void nsl_set_claim_class(struct nvdimm_drvdata *ndd,
|
||||
struct nd_namespace_label *nd_label,
|
||||
enum nvdimm_claim_class claim_class)
|
||||
{
|
||||
if (!namespace_label_has(ndd, abstraction_guid))
|
||||
if (ndd->cxl) {
|
||||
uuid_t uuid;
|
||||
|
||||
import_uuid(&uuid, nd_label->cxl.abstraction_uuid);
|
||||
export_uuid(nd_label->cxl.abstraction_uuid,
|
||||
to_abstraction_uuid(claim_class, &uuid));
|
||||
return;
|
||||
guid_copy(&nd_label->abstraction_guid,
|
||||
}
|
||||
|
||||
if (!efi_namespace_label_has(ndd, abstraction_guid))
|
||||
return;
|
||||
guid_copy(&nd_label->efi.abstraction_guid,
|
||||
to_abstraction_guid(claim_class,
|
||||
&nd_label->abstraction_guid));
|
||||
&nd_label->efi.abstraction_guid));
|
||||
}
|
||||
|
||||
enum nvdimm_claim_class nsl_get_claim_class(struct nvdimm_drvdata *ndd,
|
||||
struct nd_namespace_label *nd_label)
|
||||
{
|
||||
if (!namespace_label_has(ndd, abstraction_guid))
|
||||
if (ndd->cxl) {
|
||||
uuid_t uuid;
|
||||
|
||||
import_uuid(&uuid, nd_label->cxl.abstraction_uuid);
|
||||
return uuid_to_nvdimm_cclass(&uuid);
|
||||
}
|
||||
if (!efi_namespace_label_has(ndd, abstraction_guid))
|
||||
return NVDIMM_CCLASS_NONE;
|
||||
return to_nvdimm_cclass(&nd_label->abstraction_guid);
|
||||
return guid_to_nvdimm_cclass(&nd_label->efi.abstraction_guid);
|
||||
}
|
||||
|
||||
static int __pmem_label_update(struct nd_region *nd_region,
|
||||
@@ -942,7 +1004,7 @@ static void nsl_set_blk_isetcookie(struct nvdimm_drvdata *ndd,
|
||||
struct nd_namespace_label *nd_label,
|
||||
u64 isetcookie)
|
||||
{
|
||||
if (namespace_label_has(ndd, type_guid)) {
|
||||
if (efi_namespace_label_has(ndd, type_guid)) {
|
||||
nsl_set_isetcookie(ndd, nd_label, isetcookie);
|
||||
return;
|
||||
}
|
||||
@@ -953,7 +1015,7 @@ bool nsl_validate_blk_isetcookie(struct nvdimm_drvdata *ndd,
|
||||
struct nd_namespace_label *nd_label,
|
||||
u64 isetcookie)
|
||||
{
|
||||
if (!namespace_label_has(ndd, type_guid))
|
||||
if (!efi_namespace_label_has(ndd, type_guid))
|
||||
return true;
|
||||
|
||||
if (nsl_get_isetcookie(ndd, nd_label) != isetcookie) {
|
||||
@@ -969,7 +1031,7 @@ static void nsl_set_blk_nlabel(struct nvdimm_drvdata *ndd,
|
||||
struct nd_namespace_label *nd_label, int nlabel,
|
||||
bool first)
|
||||
{
|
||||
if (!namespace_label_has(ndd, type_guid)) {
|
||||
if (!efi_namespace_label_has(ndd, type_guid)) {
|
||||
nsl_set_nlabel(ndd, nd_label, 0); /* N/A */
|
||||
return;
|
||||
}
|
||||
@@ -980,7 +1042,7 @@ static void nsl_set_blk_position(struct nvdimm_drvdata *ndd,
|
||||
struct nd_namespace_label *nd_label,
|
||||
bool first)
|
||||
{
|
||||
if (!namespace_label_has(ndd, type_guid)) {
|
||||
if (!efi_namespace_label_has(ndd, type_guid)) {
|
||||
nsl_set_position(ndd, nd_label, 0);
|
||||
return;
|
||||
}
|
||||
@@ -1390,5 +1452,13 @@ int __init nd_label_init(void)
|
||||
WARN_ON(guid_parse(NVDIMM_PFN_GUID, &nvdimm_pfn_guid));
|
||||
WARN_ON(guid_parse(NVDIMM_DAX_GUID, &nvdimm_dax_guid));
|
||||
|
||||
WARN_ON(uuid_parse(NVDIMM_BTT_GUID, &nvdimm_btt_uuid));
|
||||
WARN_ON(uuid_parse(NVDIMM_BTT2_GUID, &nvdimm_btt2_uuid));
|
||||
WARN_ON(uuid_parse(NVDIMM_PFN_GUID, &nvdimm_pfn_uuid));
|
||||
WARN_ON(uuid_parse(NVDIMM_DAX_GUID, &nvdimm_dax_uuid));
|
||||
|
||||
WARN_ON(uuid_parse(CXL_REGION_UUID, &cxl_region_uuid));
|
||||
WARN_ON(uuid_parse(CXL_NAMESPACE_UUID, &cxl_namespace_uuid));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user