nvme: refactor spdk_nvme_map_prps into two functions
Change spdk_nvme_map_prps to a internal fucntion with a new parameter `max_iovcnt` to protect the IOVs. Also for the purpose to keep API compatibility, we still leave the API here. Change-Id: I9a638beb87aab20bba5f8a4fa0a9396110d56aff Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7335 Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
2fd233413b
commit
1d3b01e261
@ -4172,18 +4172,19 @@ spdk_nvme_ctrlr_free_qid(struct spdk_nvme_ctrlr *ctrlr, uint16_t qid)
|
|||||||
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
|
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME need to specify max number of iovs */
|
static int
|
||||||
int
|
nvme_cmd_map_prps(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs,
|
||||||
spdk_nvme_map_prps(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs,
|
uint32_t max_iovcnt, uint32_t len, size_t mps,
|
||||||
uint32_t len, size_t mps,
|
void *(*gpa_to_vva)(void *prv, uint64_t addr, uint64_t len))
|
||||||
void *(*gpa_to_vva)(void *prv, uint64_t addr, uint64_t len))
|
|
||||||
{
|
{
|
||||||
uint64_t prp1, prp2;
|
uint64_t prp1, prp2;
|
||||||
void *vva;
|
void *vva;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint32_t residue_len, nents;
|
uint32_t residue_len, nents;
|
||||||
uint64_t *prp_list;
|
uint64_t *prp_list;
|
||||||
int iovcnt;
|
uint32_t iovcnt;
|
||||||
|
|
||||||
|
assert(max_iovcnt > 0);
|
||||||
|
|
||||||
prp1 = cmd->dptr.prp.prp1;
|
prp1 = cmd->dptr.prp.prp1;
|
||||||
prp2 = cmd->dptr.prp.prp2;
|
prp2 = cmd->dptr.prp.prp2;
|
||||||
@ -4195,16 +4196,18 @@ spdk_nvme_map_prps(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs,
|
|||||||
vva = gpa_to_vva(prv, prp1, residue_len);
|
vva = gpa_to_vva(prv, prp1, residue_len);
|
||||||
if (spdk_unlikely(vva == NULL)) {
|
if (spdk_unlikely(vva == NULL)) {
|
||||||
SPDK_ERRLOG("GPA to VVA failed\n");
|
SPDK_ERRLOG("GPA to VVA failed\n");
|
||||||
return -1;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
iovs[0].iov_base = vva;
|
iovs[0].iov_base = vva;
|
||||||
iovs[0].iov_len = residue_len;
|
iovs[0].iov_len = residue_len;
|
||||||
len -= residue_len;
|
len -= residue_len;
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
|
assert(max_iovcnt > 1);
|
||||||
|
|
||||||
if (spdk_unlikely(prp2 == 0)) {
|
if (spdk_unlikely(prp2 == 0)) {
|
||||||
SPDK_ERRLOG("no PRP2, %d remaining\n", len);
|
SPDK_ERRLOG("no PRP2, %d remaining\n", len);
|
||||||
return -1;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len <= mps) {
|
if (len <= mps) {
|
||||||
@ -4214,18 +4217,23 @@ spdk_nvme_map_prps(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs,
|
|||||||
if (spdk_unlikely(vva == NULL)) {
|
if (spdk_unlikely(vva == NULL)) {
|
||||||
SPDK_ERRLOG("no VVA for %#" PRIx64 ", len%#x\n",
|
SPDK_ERRLOG("no VVA for %#" PRIx64 ", len%#x\n",
|
||||||
prp2, len);
|
prp2, len);
|
||||||
return -1;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
iovs[1].iov_base = vva;
|
iovs[1].iov_base = vva;
|
||||||
iovs[1].iov_len = len;
|
iovs[1].iov_len = len;
|
||||||
} else {
|
} else {
|
||||||
/* PRP list used */
|
/* PRP list used */
|
||||||
nents = (len + mps - 1) / mps;
|
nents = (len + mps - 1) / mps;
|
||||||
|
if (spdk_unlikely(nents + 1 > max_iovcnt)) {
|
||||||
|
SPDK_ERRLOG("Too many page entries\n");
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
vva = gpa_to_vva(prv, prp2, nents * sizeof(*prp_list));
|
vva = gpa_to_vva(prv, prp2, nents * sizeof(*prp_list));
|
||||||
if (spdk_unlikely(vva == NULL)) {
|
if (spdk_unlikely(vva == NULL)) {
|
||||||
SPDK_ERRLOG("no VVA for %#" PRIx64 ", nents=%#x\n",
|
SPDK_ERRLOG("no VVA for %#" PRIx64 ", nents=%#x\n",
|
||||||
prp2, nents);
|
prp2, nents);
|
||||||
return -1;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
prp_list = vva;
|
prp_list = vva;
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -4235,7 +4243,7 @@ spdk_nvme_map_prps(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs,
|
|||||||
if (spdk_unlikely(vva == NULL)) {
|
if (spdk_unlikely(vva == NULL)) {
|
||||||
SPDK_ERRLOG("no VVA for %#" PRIx64 ", residue_len=%#x\n",
|
SPDK_ERRLOG("no VVA for %#" PRIx64 ", residue_len=%#x\n",
|
||||||
prp_list[i], residue_len);
|
prp_list[i], residue_len);
|
||||||
return -1;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
iovs[i + 1].iov_base = vva;
|
iovs[i + 1].iov_base = vva;
|
||||||
iovs[i + 1].iov_len = residue_len;
|
iovs[i + 1].iov_len = residue_len;
|
||||||
@ -4249,5 +4257,19 @@ spdk_nvme_map_prps(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs,
|
|||||||
iovcnt = 1;
|
iovcnt = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(iovcnt <= max_iovcnt);
|
||||||
return iovcnt;
|
return iovcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME need to specify max number of iovs */
|
||||||
|
int
|
||||||
|
spdk_nvme_map_prps(void *prv, struct spdk_nvme_cmd *cmd, struct iovec *iovs,
|
||||||
|
uint32_t len, size_t mps,
|
||||||
|
void *(*gpa_to_vva)(void *prv, uint64_t addr, uint64_t len))
|
||||||
|
{
|
||||||
|
if (cmd->psdt == SPDK_NVME_PSDT_PRP) {
|
||||||
|
return nvme_cmd_map_prps(prv, cmd, iovs, UINT32_MAX, len, mps, gpa_to_vva);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user