hw/nvme: actually implement abort
Abort was not implemented previously, but we can implement it for AERs and asynchrnously for I/O. Signed-off-by: Ayush Mishra <ayush.m55@samsung.com> Reviewed-by: Klaus Jensen <k.jensen@samsung.com> Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
This commit is contained in:
parent
d522aef88d
commit
75209c071a
@ -1758,6 +1758,10 @@ static void nvme_aio_err(NvmeRequest *req, int ret)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret == -ECANCELED) {
|
||||||
|
status = NVME_CMD_ABORT_REQ;
|
||||||
|
}
|
||||||
|
|
||||||
trace_pci_nvme_err_aio(nvme_cid(req), strerror(-ret), status);
|
trace_pci_nvme_err_aio(nvme_cid(req), strerror(-ret), status);
|
||||||
|
|
||||||
error_setg_errno(&local_err, -ret, "aio failed");
|
error_setg_errno(&local_err, -ret, "aio failed");
|
||||||
@ -5950,12 +5954,40 @@ static uint16_t nvme_identify(NvmeCtrl *n, NvmeRequest *req)
|
|||||||
static uint16_t nvme_abort(NvmeCtrl *n, NvmeRequest *req)
|
static uint16_t nvme_abort(NvmeCtrl *n, NvmeRequest *req)
|
||||||
{
|
{
|
||||||
uint16_t sqid = le32_to_cpu(req->cmd.cdw10) & 0xffff;
|
uint16_t sqid = le32_to_cpu(req->cmd.cdw10) & 0xffff;
|
||||||
|
uint16_t cid = (le32_to_cpu(req->cmd.cdw10) >> 16) & 0xffff;
|
||||||
|
NvmeSQueue *sq = n->sq[sqid];
|
||||||
|
NvmeRequest *r, *next;
|
||||||
|
int i;
|
||||||
|
|
||||||
req->cqe.result = 1;
|
req->cqe.result = 1;
|
||||||
if (nvme_check_sqid(n, sqid)) {
|
if (nvme_check_sqid(n, sqid)) {
|
||||||
return NVME_INVALID_FIELD | NVME_DNR;
|
return NVME_INVALID_FIELD | NVME_DNR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sqid == 0) {
|
||||||
|
for (i = 0; i < n->outstanding_aers; i++) {
|
||||||
|
NvmeRequest *re = n->aer_reqs[i];
|
||||||
|
if (re->cqe.cid == cid) {
|
||||||
|
memmove(n->aer_reqs + i, n->aer_reqs + i + 1,
|
||||||
|
(n->outstanding_aers - i - 1) * sizeof(NvmeRequest *));
|
||||||
|
n->outstanding_aers--;
|
||||||
|
re->status = NVME_CMD_ABORT_REQ;
|
||||||
|
req->cqe.result = 0;
|
||||||
|
nvme_enqueue_req_completion(&n->admin_cq, re);
|
||||||
|
return NVME_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QTAILQ_FOREACH_SAFE(r, &sq->out_req_list, entry, next) {
|
||||||
|
if (r->cqe.cid == cid) {
|
||||||
|
if (r->aiocb) {
|
||||||
|
blk_aio_cancel_async(r->aiocb);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NVME_SUCCESS;
|
return NVME_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user