[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH 5/8] nvme: add support for metadata
From: |
Klaus Birkelund Jensen |
Subject: |
[Qemu-block] [PATCH 5/8] nvme: add support for metadata |
Date: |
Fri, 17 May 2019 10:42:31 +0200 |
The new `ms` parameter may be used to indicate the number of metadata
bytes provided per LBA.
Signed-off-by: Klaus Birkelund Jensen <address@hidden>
---
hw/block/nvme.c | 31 +++++++++++++++++++++++++++++--
hw/block/nvme.h | 11 ++++++++++-
2 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index c514f93f3867..675967a596d1 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -33,6 +33,8 @@
* num_ns=<int> : Namespaces to make out of the backing storage,
* Default:1
* num_queues=<int> : Number of possible IO Queues, Default:64
+ * ms=<int> : Number of metadata bytes provided per LBA,
+ * Default:0
* cmb_size_mb=<int> : Size of CMB in MBs, Default:0
*
* Parameters will be verified against conflicting capabilities and attributes
@@ -386,6 +388,8 @@ static uint16_t nvme_blk_map(NvmeCtrl *n, NvmeCmd *cmd,
NvmeRequest *req)
uint32_t unit_len = nvme_ns_lbads_bytes(ns);
uint32_t len = req->nlb * unit_len;
+ uint32_t meta_unit_len = nvme_ns_ms(ns);
+ uint32_t meta_len = req->nlb * meta_unit_len;
uint64_t prp1 = le64_to_cpu(cmd->prp1);
uint64_t prp2 = le64_to_cpu(cmd->prp2);
@@ -399,6 +403,19 @@ static uint16_t nvme_blk_map(NvmeCtrl *n, NvmeCmd *cmd,
NvmeRequest *req)
return err;
}
+ qsg.nsg = 0;
+ qsg.size = 0;
+
+ if (cmd->mptr && n->params.ms) {
+ qemu_sglist_add(&qsg, le64_to_cpu(cmd->mptr), meta_len);
+
+ err = nvme_blk_setup(n, ns, &qsg, ns->blk_offset_md, meta_unit_len,
+ req);
+ if (err) {
+ return err;
+ }
+ }
+
qemu_sglist_destroy(&qsg);
return NVME_SUCCESS;
@@ -1902,6 +1919,11 @@ static int nvme_check_constraints(NvmeCtrl *n, Error
**errp)
return 1;
}
+ if (params->ms && !is_power_of_2(params->ms)) {
+ error_setg(errp, "nvme: invalid metadata configuration");
+ return 1;
+ }
+
return 0;
}
@@ -2066,17 +2088,20 @@ static void nvme_init_ctrl(NvmeCtrl *n)
static uint64_t nvme_ns_calc_blks(NvmeCtrl *n, NvmeNamespace *ns)
{
- return n->ns_size / nvme_ns_lbads_bytes(ns);
+ return n->ns_size / (nvme_ns_lbads_bytes(ns) + nvme_ns_ms(ns));
}
static void nvme_ns_init_identify(NvmeCtrl *n, NvmeIdNs *id_ns)
{
+ NvmeParams *params = &n->params;
+
id_ns->nlbaf = 0;
id_ns->flbas = 0;
- id_ns->mc = 0;
+ id_ns->mc = params->ms ? 0x2 : 0;
id_ns->dpc = 0;
id_ns->dps = 0;
id_ns->lbaf[0].lbads = BDRV_SECTOR_BITS;
+ id_ns->lbaf[0].ms = params->ms;
}
static int nvme_init_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp)
@@ -2086,6 +2111,8 @@ static int nvme_init_namespace(NvmeCtrl *n, NvmeNamespace
*ns, Error **errp)
nvme_ns_init_identify(n, id_ns);
ns->ns_blks = nvme_ns_calc_blks(n, ns);
+ ns->blk_offset_md = ns->blk_offset + nvme_ns_lbads_bytes(ns) * ns->ns_blks;
+
id_ns->nuse = id_ns->ncap = id_ns->nsze = cpu_to_le64(ns->ns_blks);
return 0;
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index 711ca249eac5..81ee0c5173d5 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -8,13 +8,15 @@
DEFINE_PROP_UINT32("cmb_size_mb", _state, _props.cmb_size_mb, 0), \
DEFINE_PROP_UINT32("num_queues", _state, _props.num_queues, 64), \
DEFINE_PROP_UINT32("num_ns", _state, _props.num_ns, 1), \
- DEFINE_PROP_UINT8("mdts", _state, _props.mdts, 7)
+ DEFINE_PROP_UINT8("mdts", _state, _props.mdts, 7), \
+ DEFINE_PROP_UINT8("ms", _state, _props.ms, 0)
typedef struct NvmeParams {
char *serial;
uint32_t num_queues;
uint32_t num_ns;
uint8_t mdts;
+ uint8_t ms;
uint32_t cmb_size_mb;
} NvmeParams;
@@ -91,6 +93,7 @@ typedef struct NvmeNamespace {
uint32_t id;
uint64_t ns_blks;
uint64_t blk_offset;
+ uint64_t blk_offset_md;
} NvmeNamespace;
#define TYPE_NVME "nvme"
@@ -154,4 +157,10 @@ static inline size_t nvme_ns_lbads_bytes(NvmeNamespace *ns)
return 1 << nvme_ns_lbads(ns);
}
+static inline uint16_t nvme_ns_ms(NvmeNamespace *ns)
+{
+ NvmeIdNs *id = &ns->id_ns;
+ return le16_to_cpu(id->lbaf[NVME_ID_NS_FLBAS_INDEX(id->flbas)].ms);
+}
+
#endif /* HW_NVME_H */
--
2.21.0
- [Qemu-block] [PATCH 0/8] nvme: v1.3, sgls, metadata and new 'ocssd' device, Klaus Birkelund Jensen, 2019/05/17
- [Qemu-block] [PATCH 1/8] nvme: move device parameters to separate struct, Klaus Birkelund Jensen, 2019/05/17
- [Qemu-block] [PATCH 5/8] nvme: add support for metadata,
Klaus Birkelund Jensen <=
- [Qemu-block] [PATCH 7/8] nvme: keep a copy of the NVMe command in request, Klaus Birkelund Jensen, 2019/05/17
- [Qemu-block] [PATCH 4/8] nvme: allow multiple i/o's per request, Klaus Birkelund Jensen, 2019/05/17
- [Qemu-block] [PATCH 3/8] nvme: simplify PRP mappings, Klaus Birkelund Jensen, 2019/05/17
- [Qemu-block] [PATCH 6/8] nvme: add support for scatter gather lists, Klaus Birkelund Jensen, 2019/05/17
- [Qemu-block] [PATCH 2/8] nvme: bump supported spec to 1.3, Klaus Birkelund Jensen, 2019/05/17
- [Qemu-block] [PATCH 8/8] nvme: add an OpenChannel 2.0 NVMe device (ocssd), Klaus Birkelund Jensen, 2019/05/17
- Re: [Qemu-block] [PATCH 0/8] nvme: v1.3, sgls, metadata and new 'ocssd' device, Kevin Wolf, 2019/05/20