nvme/pcie: pass dword aligned requirement based on controller flag
We only set the flag to false when the controller reports SGL supported and can use byte contiguous buffer. Also check the data block's alignment for hardware SGL. Change-Id: Id936c49823963000d0543fc95fbb6edba3118feb Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1352 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
parent
121aca0bc6
commit
8065ab2c27
@ -1837,7 +1837,7 @@ nvme_pcie_prp_list_append(struct nvme_tracker *tr, uint32_t *prp_index, void *vi
|
||||
|
||||
static int
|
||||
nvme_pcie_qpair_build_request_invalid(struct spdk_nvme_qpair *qpair,
|
||||
struct nvme_request *req, struct nvme_tracker *tr)
|
||||
struct nvme_request *req, struct nvme_tracker *tr, bool dword_aligned)
|
||||
{
|
||||
assert(0);
|
||||
nvme_pcie_fail_request_bad_vtophys(qpair, tr);
|
||||
@ -1849,7 +1849,7 @@ nvme_pcie_qpair_build_request_invalid(struct spdk_nvme_qpair *qpair,
|
||||
*/
|
||||
static int
|
||||
nvme_pcie_qpair_build_contig_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req,
|
||||
struct nvme_tracker *tr)
|
||||
struct nvme_tracker *tr, bool dword_aligned)
|
||||
{
|
||||
uint32_t prp_index = 0;
|
||||
int rc;
|
||||
@ -1871,7 +1871,7 @@ nvme_pcie_qpair_build_contig_request(struct spdk_nvme_qpair *qpair, struct nvme_
|
||||
*/
|
||||
static int
|
||||
nvme_pcie_qpair_build_contig_hw_sgl_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req,
|
||||
struct nvme_tracker *tr)
|
||||
struct nvme_tracker *tr, bool dword_aligned)
|
||||
{
|
||||
void *virt_addr;
|
||||
uint64_t phys_addr, mapping_length;
|
||||
@ -1896,6 +1896,12 @@ nvme_pcie_qpair_build_contig_hw_sgl_request(struct spdk_nvme_qpair *qpair, struc
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (dword_aligned && ((uintptr_t)virt_addr & 3)) {
|
||||
SPDK_ERRLOG("virt_addr %p not dword aligned\n", virt_addr);
|
||||
nvme_pcie_fail_request_bad_vtophys(qpair, tr);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
phys_addr = spdk_vtophys(virt_addr, &mapping_length);
|
||||
if (phys_addr == SPDK_VTOPHYS_ERROR) {
|
||||
nvme_pcie_fail_request_bad_vtophys(qpair, tr);
|
||||
@ -1943,7 +1949,7 @@ nvme_pcie_qpair_build_contig_hw_sgl_request(struct spdk_nvme_qpair *qpair, struc
|
||||
*/
|
||||
static int
|
||||
nvme_pcie_qpair_build_hw_sgl_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req,
|
||||
struct nvme_tracker *tr)
|
||||
struct nvme_tracker *tr, bool dword_aligned)
|
||||
{
|
||||
int rc;
|
||||
void *virt_addr;
|
||||
@ -1979,14 +1985,18 @@ nvme_pcie_qpair_build_hw_sgl_request(struct spdk_nvme_qpair *qpair, struct nvme_
|
||||
remaining_transfer_len -= remaining_user_sge_len;
|
||||
while (remaining_user_sge_len > 0) {
|
||||
if (nseg >= NVME_MAX_SGL_DESCRIPTORS) {
|
||||
nvme_pcie_fail_request_bad_vtophys(qpair, tr);
|
||||
return -EFAULT;
|
||||
SPDK_ERRLOG("Too many SGL entries\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (dword_aligned && ((uintptr_t)virt_addr & 3)) {
|
||||
SPDK_ERRLOG("virt_addr %p not dword aligned\n", virt_addr);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
phys_addr = spdk_vtophys(virt_addr, NULL);
|
||||
if (phys_addr == SPDK_VTOPHYS_ERROR) {
|
||||
nvme_pcie_fail_request_bad_vtophys(qpair, tr);
|
||||
return -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
length = spdk_min(remaining_user_sge_len, VALUE_2MB - _2MB_OFFSET(virt_addr));
|
||||
@ -2030,6 +2040,10 @@ nvme_pcie_qpair_build_hw_sgl_request(struct spdk_nvme_qpair *qpair, struct nvme_
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
nvme_pcie_fail_request_bad_vtophys(qpair, tr);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2037,7 +2051,7 @@ nvme_pcie_qpair_build_hw_sgl_request(struct spdk_nvme_qpair *qpair, struct nvme_
|
||||
*/
|
||||
static int
|
||||
nvme_pcie_qpair_build_prps_sgl_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req,
|
||||
struct nvme_tracker *tr)
|
||||
struct nvme_tracker *tr, bool dword_aligned)
|
||||
{
|
||||
int rc;
|
||||
void *virt_addr;
|
||||
@ -2084,7 +2098,8 @@ nvme_pcie_qpair_build_prps_sgl_request(struct spdk_nvme_qpair *qpair, struct nvm
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef int(*build_req_fn)(struct spdk_nvme_qpair *, struct nvme_request *, struct nvme_tracker *);
|
||||
typedef int(*build_req_fn)(struct spdk_nvme_qpair *, struct nvme_request *, struct nvme_tracker *,
|
||||
bool);
|
||||
|
||||
static build_req_fn const g_nvme_pcie_build_req_table[][2] = {
|
||||
[NVME_PAYLOAD_TYPE_INVALID] = {
|
||||
@ -2111,6 +2126,7 @@ nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_reques
|
||||
struct nvme_pcie_qpair *pqpair = nvme_pcie_qpair(qpair);
|
||||
enum nvme_payload_type payload_type;
|
||||
bool sgl_supported;
|
||||
bool dword_aligned = true;
|
||||
|
||||
if (spdk_unlikely(nvme_qpair_is_admin_queue(qpair))) {
|
||||
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
|
||||
@ -2151,7 +2167,11 @@ nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_reques
|
||||
*/
|
||||
sgl_supported = (ctrlr->flags & SPDK_NVME_CTRLR_SGL_SUPPORTED) != 0 &&
|
||||
!nvme_qpair_is_admin_queue(qpair);
|
||||
rc = g_nvme_pcie_build_req_table[payload_type][sgl_supported](qpair, req, tr);
|
||||
|
||||
if (sgl_supported && !(ctrlr->flags & SPDK_NVME_CTRLR_SGL_REQUIRES_DWORD_ALIGNMENT)) {
|
||||
dword_aligned = false;
|
||||
}
|
||||
rc = g_nvme_pcie_build_req_table[payload_type][sgl_supported](qpair, req, tr, dword_aligned);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
|
@ -418,7 +418,7 @@ test_build_contig_hw_sgl_request(void)
|
||||
g_vtophys_size = 100;
|
||||
MOCK_SET(spdk_vtophys, 0xDEADBEEF);
|
||||
|
||||
rc = nvme_pcie_qpair_build_contig_hw_sgl_request(&qpair, &req, &tr);
|
||||
rc = nvme_pcie_qpair_build_contig_hw_sgl_request(&qpair, &req, &tr, 0);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
|
||||
CU_ASSERT(req.cmd.dptr.sgl1.address == 0xDEADBEEF);
|
||||
@ -437,7 +437,7 @@ test_build_contig_hw_sgl_request(void)
|
||||
g_vtophys_size = 1000;
|
||||
MOCK_SET(spdk_vtophys, 0xDEADBEEF);
|
||||
|
||||
rc = nvme_pcie_qpair_build_contig_hw_sgl_request(&qpair, &req, &tr);
|
||||
rc = nvme_pcie_qpair_build_contig_hw_sgl_request(&qpair, &req, &tr, 0);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
|
||||
CU_ASSERT(req.cmd.dptr.sgl1.address == 0xDEADBEEF);
|
||||
@ -456,7 +456,7 @@ test_build_contig_hw_sgl_request(void)
|
||||
tr.prp_sgl_bus_addr = 0xFF0FF;
|
||||
MOCK_SET(spdk_vtophys, 0xDEADBEEF);
|
||||
|
||||
rc = nvme_pcie_qpair_build_contig_hw_sgl_request(&qpair, &req, &tr);
|
||||
rc = nvme_pcie_qpair_build_contig_hw_sgl_request(&qpair, &req, &tr, 0);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_LAST_SEGMENT);
|
||||
CU_ASSERT(req.cmd.dptr.sgl1.address == tr.prp_sgl_bus_addr);
|
||||
|
Loading…
Reference in New Issue
Block a user