Skip to content

Commit

Permalink
libnvdimm/labels: Introduce CXL labels
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dan Williams committed Sep 21, 2021
1 parent 540ccaa commit 5af9683
Show file tree
Hide file tree
Showing 3 changed files with 241 additions and 50 deletions.
104 changes: 87 additions & 17 deletions drivers/nvdimm/label.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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)
{
Expand All @@ -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)
{
Expand All @@ -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;
Expand All @@ -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;
}

if (!efi_namespace_label_has(ndd, abstraction_guid))
return;
guid_copy(&nd_label->abstraction_guid,
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,
Expand Down Expand Up @@ -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;
}
Expand All @@ -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) {
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
52 changes: 49 additions & 3 deletions drivers/nvdimm/label.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ struct cxl_region_label {
};

/**
* struct nd_namespace_label - namespace superblock
* struct nvdimm_efi_label - namespace superblock
* @uuid: UUID per RFC 4122
* @name: optional name (NULL-terminated)
* @flags: see NSLABEL_FLAG_*
Expand All @@ -117,7 +117,7 @@ struct cxl_region_label {
* @reserved2: reserved
* @checksum: fletcher64 sum of this object
*/
struct nd_namespace_label {
struct nvdimm_efi_label {
u8 uuid[NSLABEL_UUID_LEN];
u8 name[NSLABEL_NAME_LEN];
__le32 flags;
Expand All @@ -130,7 +130,7 @@ struct nd_namespace_label {
__le32 slot;
/*
* Accessing fields past this point should be gated by a
* namespace_label_has() check.
* efi_namespace_label_has() check.
*/
u8 align;
u8 reserved[3];
Expand All @@ -140,11 +140,57 @@ struct nd_namespace_label {
__le64 checksum;
};

/**
* struct nvdimm_cxl_label - CXL 2.0 Table 212
* @type: uuid identifying this label format (namespace)
* @uuid: uuid for the namespace this label describes
* @name: friendly name for the namespace
* @flags: NSLABEL_FLAG_UPDATING (all other flags reserved)
* @nrange: discontiguous namespace support
* @position: this label's position in the set
* @dpa: start address in device-local capacity for this label
* @rawsize: size of this label's contribution to namespace
* @slot: slot id of this label in label area
* @align: alignment in SZ_256M blocks
* @region_uuid: host interleave set identifier
* @abstraction_uuid: personality driver for this namespace
* @lbasize: address geometry for disk-like personalities
* @reserved: reserved
* @checksum: fletcher64 sum of this label
*/
struct nvdimm_cxl_label {
u8 type[NSLABEL_UUID_LEN];
u8 uuid[NSLABEL_UUID_LEN];
u8 name[NSLABEL_NAME_LEN];
__le32 flags;
__le16 nrange;
__le16 position;
__le64 dpa;
__le64 rawsize;
__le32 slot;
__le32 align;
u8 region_uuid[16];
u8 abstraction_uuid[16];
__le16 lbasize;
u8 reserved[0x56];
__le64 checksum;
};

struct nd_namespace_label {
union {
struct nvdimm_cxl_label cxl;
struct nvdimm_efi_label efi;
};
};

#define NVDIMM_BTT_GUID "8aed63a2-29a2-4c66-8b12-f05d15d3922a"
#define NVDIMM_BTT2_GUID "18633bfc-1735-4217-8ac9-17239282d3f8"
#define NVDIMM_PFN_GUID "266400ba-fb9f-4677-bcb0-968f11d0d225"
#define NVDIMM_DAX_GUID "97a86d9c-3cdd-4eda-986f-5068b4f80088"

#define CXL_REGION_UUID "529d7c61-da07-47c4-a93f-ecdf2c06f444"
#define CXL_NAMESPACE_UUID "68bb2c0a-5a77-4937-9f85-3caf41a0f93c"

/**
* struct nd_label_id - identifier string for dpa allocation
* @id: "{blk|pmem}-<namespace uuid>"
Expand Down
Loading

0 comments on commit 5af9683

Please sign in to comment.