nvme: add Bit Bucket SGL with READ support
When iterating SGL segment, we can use existing virt_addr parameter to return UINT64_MAX as a special value to indicate this segment need to be described as Bit Bucket SGL. Currently only READ command is supported, we can enable the WRITE and COMPARE support when necessary. Change-Id: I50aa2b226ec3449c13ed1d97b3224ee8e7de95a8 Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1467 Community-CI: Mellanox Build Bot Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
532ae9527b
commit
b55279d485
@ -2276,7 +2276,8 @@ typedef void (*spdk_nvme_req_reset_sgl_cb)(void *cb_arg, uint32_t offset);
|
||||
* The described segment must be physically contiguous.
|
||||
*
|
||||
* \param cb_arg Argument passed to readv/writev.
|
||||
* \param address Virtual address of this segment.
|
||||
* \param address Virtual address of this segment, a value of UINT64_MAX
|
||||
* means the segment should be described via Bit Bucket SGL.
|
||||
* \param length Length of this physical segment.
|
||||
*/
|
||||
typedef int (*spdk_nvme_req_next_sge_cb)(void *cb_arg, void **address, uint32_t *length);
|
||||
|
@ -2012,6 +2012,37 @@ nvme_pcie_qpair_build_hw_sgl_request(struct spdk_nvme_qpair *qpair, struct nvme_
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* Bit Bucket SGL descriptor */
|
||||
if ((uint64_t)virt_addr == UINT64_MAX) {
|
||||
/* TODO: enable WRITE and COMPARE when necessary */
|
||||
if (req->cmd.opc != SPDK_NVME_OPC_READ) {
|
||||
SPDK_ERRLOG("Only READ command can be supported\n");
|
||||
goto exit;
|
||||
}
|
||||
if (nseg >= NVME_MAX_SGL_DESCRIPTORS) {
|
||||
SPDK_ERRLOG("Too many SGL entries\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sgl->unkeyed.type = SPDK_NVME_SGL_TYPE_BIT_BUCKET;
|
||||
/* If the SGL describes a destination data buffer, the length of data
|
||||
* buffer shall be discarded by controller, and the length is included
|
||||
* in Number of Logical Blocks (NLB) parameter. Otherwise, the length
|
||||
* is not included in the NLB parameter.
|
||||
*/
|
||||
remaining_user_sge_len = spdk_min(remaining_user_sge_len, remaining_transfer_len);
|
||||
remaining_transfer_len -= remaining_user_sge_len;
|
||||
|
||||
sgl->unkeyed.length = remaining_user_sge_len;
|
||||
sgl->address = 0;
|
||||
sgl->unkeyed.subtype = 0;
|
||||
|
||||
sgl++;
|
||||
nseg++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
remaining_user_sge_len = spdk_min(remaining_user_sge_len, remaining_transfer_len);
|
||||
remaining_transfer_len -= remaining_user_sge_len;
|
||||
while (remaining_user_sge_len > 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user