mirror of https://github.com/xemu-project/xemu.git
hw/nvme updates
Small set of fixes and some updates for the FDP support. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEUigzqnXi3OaiR2bATeGvMW1PDekFAmSb/D4ACgkQTeGvMW1P DemziAf/eQfjnVr57A+Kglf8J15MCW0GiArbHCJfcl9vf0HPP/iY1c9V4cCZjTLG vkkkU6W+TFaYALGOVgAldHWC7OCpOi7GHrlqRJDuw86d2dyLDn/l+GQin/rVoocD fzF2gRVQU4x9qzmjRUikVhRzZbrB4F/AH6QQ8EV3wx2wrljyusItEGe53FEuCugx pwtKrG990188+UCT1ofr2JYhLq3OmYQi3o2fWgzMp9jP+NeROgKaevWG4UEhFonG CdeL9BMlSRAfrdR1gTvZpG2mFsrroeBCCjXcrKSwkAxBqpMJDSLvbGqoGJo6kDWm c9x82Zy2/wVuQaDk+atmcTF1+Pddgw== =//ks -----END PGP SIGNATURE----- Merge tag 'nvme-next-pull-request' of https://gitlab.com/birkelund/qemu into staging hw/nvme updates Small set of fixes and some updates for the FDP support. # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCgAdFiEEUigzqnXi3OaiR2bATeGvMW1PDekFAmSb/D4ACgkQTeGvMW1P # DemziAf/eQfjnVr57A+Kglf8J15MCW0GiArbHCJfcl9vf0HPP/iY1c9V4cCZjTLG # vkkkU6W+TFaYALGOVgAldHWC7OCpOi7GHrlqRJDuw86d2dyLDn/l+GQin/rVoocD # fzF2gRVQU4x9qzmjRUikVhRzZbrB4F/AH6QQ8EV3wx2wrljyusItEGe53FEuCugx # pwtKrG990188+UCT1ofr2JYhLq3OmYQi3o2fWgzMp9jP+NeROgKaevWG4UEhFonG # CdeL9BMlSRAfrdR1gTvZpG2mFsrroeBCCjXcrKSwkAxBqpMJDSLvbGqoGJo6kDWm # c9x82Zy2/wVuQaDk+atmcTF1+Pddgw== # =//ks # -----END PGP SIGNATURE----- # gpg: Signature made Wed 28 Jun 2023 11:24:14 AM CEST # gpg: using RSA key 522833AA75E2DCE6A24766C04DE1AF316D4F0DE9 # gpg: Good signature from "Klaus Jensen <its@irrelevant.dk>" [unknown] # gpg: aka "Klaus Jensen <k.jensen@samsung.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: DDCA 4D9C 9EF9 31CC 3468 4272 63D5 6FC5 E55D A838 # Subkey fingerprint: 5228 33AA 75E2 DCE6 A247 66C0 4DE1 AF31 6D4F 0DE9 * tag 'nvme-next-pull-request' of https://gitlab.com/birkelund/qemu: docs: update hw/nvme documentation for TP4146 hw/nvme: add placement handle list ranges hw/nvme: verify uniqueness of reclaim unit handle identifiers hw/nvme: fix verification of number of ruhis hw/nvme: check maximum copy length (MCL) for COPY hw/nvme: consider COPY command in nvme_aio_err hw/nvme: add comment for nvme-ns properties Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
aa1048e33c
|
@ -212,6 +212,41 @@ The namespace may be configured with additional parameters
|
|||
the minimum memory page size (CAP.MPSMIN). The default value (``0``)
|
||||
has this property inherit the ``mdts`` value.
|
||||
|
||||
Flexible Data Placement
|
||||
-----------------------
|
||||
|
||||
The device may be configured to support TP4146 ("Flexible Data Placement") by
|
||||
configuring it (``fdp=on``) on the subsystem::
|
||||
|
||||
-device nvme-subsys,id=nvme-subsys-0,nqn=subsys0,fdp=on,fdp.nruh=16
|
||||
|
||||
The subsystem emulates a single Endurance Group, on which Flexible Data
|
||||
Placement will be supported. Also note that the device emulation deviates
|
||||
slightly from the specification, by always enabling the "FDP Mode" feature on
|
||||
the controller if the subsystems is configured for Flexible Data Placement.
|
||||
|
||||
Enabling Flexible Data Placement on the subsyste enables the following
|
||||
parameters:
|
||||
|
||||
``fdp.nrg`` (default: ``1``)
|
||||
Set the number of Reclaim Groups.
|
||||
|
||||
``fdp.nruh`` (default: ``0``)
|
||||
Set the number of Reclaim Unit Handles. This is a mandatory paramater and
|
||||
must be non-zero.
|
||||
|
||||
``fdp.runs`` (default: ``96M``)
|
||||
Set the Reclaim Unit Nominal Size. Defaults to 96 MiB.
|
||||
|
||||
Namespaces within this subsystem may requests Reclaim Unit Handles::
|
||||
|
||||
-device nvme-ns,drive=nvm-1,fdp.ruhs=RUHLIST
|
||||
|
||||
The ``RUHLIST`` is a semicolon separated list (i.e. ``0;1;2;3``) and may
|
||||
include ranges (i.e. ``0;8-15``). If no reclaim unit handle list is specified,
|
||||
the controller will assign the controller-specified reclaim unit handle to
|
||||
placement handle identifier 0.
|
||||
|
||||
Metadata
|
||||
--------
|
||||
|
||||
|
@ -320,4 +355,4 @@ controller are:
|
|||
|
||||
.. code-block:: console
|
||||
|
||||
echo 0000:01:00.1 > /sys/bus/pci/drivers/nvme/bind
|
||||
echo 0000:01:00.1 > /sys/bus/pci/drivers/nvme/bind
|
||||
|
|
|
@ -43,7 +43,14 @@
|
|||
* subsys=<subsys_id>
|
||||
* -device nvme-ns,drive=<drive_id>,bus=<bus_name>,nsid=<nsid>,\
|
||||
* zoned=<true|false[optional]>, \
|
||||
* subsys=<subsys_id>,detached=<true|false[optional]>
|
||||
* subsys=<subsys_id>,shared=<true|false[optional]>, \
|
||||
* detached=<true|false[optional]>, \
|
||||
* zoned.zone_size=<N[optional]>, \
|
||||
* zoned.zone_capacity=<N[optional]>, \
|
||||
* zoned.descr_ext_size=<N[optional]>, \
|
||||
* zoned.max_active=<N[optional]>, \
|
||||
* zoned.max_open=<N[optional]>, \
|
||||
* zoned.cross_read=<true|false[optional]>
|
||||
*
|
||||
* Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at
|
||||
* offset 0 in BAR2 and supports only WDS, RDS and SQS for now. By default, the
|
||||
|
@ -1748,6 +1755,7 @@ static void nvme_aio_err(NvmeRequest *req, int ret)
|
|||
case NVME_CMD_WRITE:
|
||||
case NVME_CMD_WRITE_ZEROES:
|
||||
case NVME_CMD_ZONE_APPEND:
|
||||
case NVME_CMD_COPY:
|
||||
status = NVME_WRITE_FAULT;
|
||||
break;
|
||||
default:
|
||||
|
@ -2847,6 +2855,25 @@ static void nvme_copy_source_range_parse(void *ranges, int idx, uint8_t format,
|
|||
}
|
||||
}
|
||||
|
||||
static inline uint16_t nvme_check_copy_mcl(NvmeNamespace *ns,
|
||||
NvmeCopyAIOCB *iocb, uint16_t nr)
|
||||
{
|
||||
uint32_t copy_len = 0;
|
||||
|
||||
for (int idx = 0; idx < nr; idx++) {
|
||||
uint32_t nlb;
|
||||
nvme_copy_source_range_parse(iocb->ranges, idx, iocb->format, NULL,
|
||||
&nlb, NULL, NULL, NULL);
|
||||
copy_len += nlb + 1;
|
||||
}
|
||||
|
||||
if (copy_len > ns->id_ns.mcl) {
|
||||
return NVME_CMD_SIZE_LIMIT | NVME_DNR;
|
||||
}
|
||||
|
||||
return NVME_SUCCESS;
|
||||
}
|
||||
|
||||
static void nvme_copy_out_completed_cb(void *opaque, int ret)
|
||||
{
|
||||
NvmeCopyAIOCB *iocb = opaque;
|
||||
|
@ -3159,6 +3186,11 @@ static uint16_t nvme_copy(NvmeCtrl *n, NvmeRequest *req)
|
|||
}
|
||||
}
|
||||
|
||||
status = nvme_check_copy_mcl(ns, iocb, nr);
|
||||
if (status) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
iocb->req = req;
|
||||
iocb->ret = 0;
|
||||
iocb->nr = nr;
|
||||
|
|
55
hw/nvme/ns.c
55
hw/nvme/ns.c
|
@ -400,8 +400,9 @@ static bool nvme_ns_init_fdp(NvmeNamespace *ns, Error **errp)
|
|||
NvmeRuHandle *ruh;
|
||||
uint8_t lbafi = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas);
|
||||
g_autofree unsigned int *ruhids = NULL;
|
||||
unsigned int *ruhid;
|
||||
char *r, *p, *token;
|
||||
unsigned int n, m, *ruhid;
|
||||
const char *endptr, *token;
|
||||
char *r, *p;
|
||||
uint16_t *ph;
|
||||
|
||||
if (!ns->params.fdp.ruhs) {
|
||||
|
@ -438,23 +439,55 @@ static bool nvme_ns_init_fdp(NvmeNamespace *ns, Error **errp)
|
|||
|
||||
/* parse the placement handle identifiers */
|
||||
while ((token = qemu_strsep(&p, ";")) != NULL) {
|
||||
ns->fdp.nphs += 1;
|
||||
if (ns->fdp.nphs > NVME_FDP_MAXPIDS ||
|
||||
ns->fdp.nphs == endgrp->fdp.nruh) {
|
||||
error_setg(errp, "too many placement handles");
|
||||
free(r);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (qemu_strtoui(token, NULL, 0, ruhid++) < 0) {
|
||||
if (qemu_strtoui(token, &endptr, 0, &n) < 0) {
|
||||
error_setg(errp, "cannot parse reclaim unit handle identifier");
|
||||
free(r);
|
||||
return false;
|
||||
}
|
||||
|
||||
m = n;
|
||||
|
||||
/* parse range */
|
||||
if (*endptr == '-') {
|
||||
token = endptr + 1;
|
||||
|
||||
if (qemu_strtoui(token, NULL, 0, &m) < 0) {
|
||||
error_setg(errp, "cannot parse reclaim unit handle identifier");
|
||||
free(r);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m < n) {
|
||||
error_setg(errp, "invalid reclaim unit handle identifier range");
|
||||
free(r);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (; n <= m; n++) {
|
||||
if (ns->fdp.nphs++ == endgrp->fdp.nruh) {
|
||||
error_setg(errp, "too many placement handles");
|
||||
free(r);
|
||||
return false;
|
||||
}
|
||||
|
||||
*ruhid++ = n;
|
||||
}
|
||||
}
|
||||
|
||||
free(r);
|
||||
|
||||
/* verify that the ruhids are unique */
|
||||
for (unsigned int i = 0; i < ns->fdp.nphs; i++) {
|
||||
for (unsigned int j = i + 1; j < ns->fdp.nphs; j++) {
|
||||
if (ruhids[i] == ruhids[j]) {
|
||||
error_setg(errp, "duplicate reclaim unit handle identifier: %u",
|
||||
ruhids[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ph = ns->fdp.phs = g_new(uint16_t, ns->fdp.nphs);
|
||||
|
||||
ruhid = ruhids;
|
||||
|
|
|
@ -158,8 +158,10 @@ static bool nvme_subsys_setup_fdp(NvmeSubsystem *subsys, Error **errp)
|
|||
|
||||
endgrp->fdp.nrg = subsys->params.fdp.nrg;
|
||||
|
||||
if (!subsys->params.fdp.nruh) {
|
||||
error_setg(errp, "fdp.nruh must be non-zero");
|
||||
if (!subsys->params.fdp.nruh ||
|
||||
subsys->params.fdp.nruh > NVME_FDP_MAXPIDS) {
|
||||
error_setg(errp, "fdp.nruh must be non-zero and less than %u",
|
||||
NVME_FDP_MAXPIDS);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue