[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] hw/block/nvme: drain namespaces on sq deletion
From: |
Klaus Jensen |
Subject: |
Re: [PATCH] hw/block/nvme: drain namespaces on sq deletion |
Date: |
Wed, 10 Feb 2021 21:58:09 +0100 |
On Jan 27 14:15, Klaus Jensen wrote:
> From: Klaus Jensen <k.jensen@samsung.com>
>
> For most commands, when issuing an AIO, the BlockAIOCB is stored in the
> NvmeRequest aiocb pointer when the AIO is issued. The purpose of storing
> this is to allow the AIO to be cancelled when deleting submission
> queues (it is currently not used for Abort).
>
> Since the addition of the Dataset Management command and Zoned
> Namespaces, NvmeRequests may involve more than one AIO and the AIOs are
> issued without saving a reference to the BlockAIOCB. This is a problem
> since nvme_del_sq will attempt to cancel outstanding AIOs, potentially
> with an invalid BlockAIOCB.
>
> Fix this by instead of explicitly cancelling the requests, just allow
> the AIOs to complete by draining the namespace blockdevs.
>
> Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
> ---
> hw/block/nvme.c | 18 +++++++++++++-----
> 1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index 316858fd8adf..91f6fb6da1e2 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -403,6 +403,7 @@ static void nvme_req_clear(NvmeRequest *req)
> {
> req->ns = NULL;
> req->opaque = NULL;
> + req->aiocb = NULL;
> memset(&req->cqe, 0x0, sizeof(req->cqe));
> req->status = NVME_SUCCESS;
> }
> @@ -2396,6 +2397,7 @@ static uint16_t nvme_del_sq(NvmeCtrl *n, NvmeRequest
> *req)
> NvmeSQueue *sq;
> NvmeCQueue *cq;
> uint16_t qid = le16_to_cpu(c->qid);
> + int i;
>
> if (unlikely(!qid || nvme_check_sqid(n, qid))) {
> trace_pci_nvme_err_invalid_del_sq(qid);
> @@ -2404,12 +2406,18 @@ static uint16_t nvme_del_sq(NvmeCtrl *n, NvmeRequest
> *req)
>
> trace_pci_nvme_del_sq(qid);
>
> - sq = n->sq[qid];
> - while (!QTAILQ_EMPTY(&sq->out_req_list)) {
> - r = QTAILQ_FIRST(&sq->out_req_list);
> - assert(r->aiocb);
> - blk_aio_cancel(r->aiocb);
> + for (i = 1; i <= n->num_namespaces; i++) {
> + NvmeNamespace *ns = nvme_ns(n, i);
> + if (!ns) {
> + continue;
> + }
> +
> + nvme_ns_drain(ns);
> }
> +
> + sq = n->sq[qid];
> + assert(QTAILQ_EMPTY(&sq->out_req_list));
> +
> if (!nvme_check_cqid(n, sq->cqid)) {
> cq = n->cq[sq->cqid];
> QTAILQ_REMOVE(&cq->sq_list, sq, entry);
> --
> 2.30.0
>
Ping on this.
signature.asc
Description: PGP signature
- Re: [PATCH] hw/block/nvme: drain namespaces on sq deletion,
Klaus Jensen <=