aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAyush Mishra <ayush.m55@samsung.com>2024-07-02 13:32:32 +0530
committerKlaus Jensen <k.jensen@samsung.com>2024-07-22 14:36:15 +0200
commit75209c071aab4488aef63c38fb53d0e4e3aaa062 (patch)
treeeb7d9531a2169d49ff3d1f41d318f5d30876665b
parentd522aef88d42a05e46290c97602936a7f6d307e3 (diff)
downloadqemu-75209c071aab4488aef63c38fb53d0e4e3aaa062.zip
qemu-75209c071aab4488aef63c38fb53d0e4e3aaa062.tar.gz
qemu-75209c071aab4488aef63c38fb53d0e4e3aaa062.tar.bz2
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>
-rw-r--r--hw/nvme/ctrl.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 385438a..39782dd 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -1758,6 +1758,10 @@ static void nvme_aio_err(NvmeRequest *req, int ret)
break;
}
+ if (ret == -ECANCELED) {
+ status = NVME_CMD_ABORT_REQ;
+ }
+
trace_pci_nvme_err_aio(nvme_cid(req), strerror(-ret), status);
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)
{
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;
if (nvme_check_sqid(n, sqid)) {
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;
}