nvmet: release the sq ref on rdma read errors
authorVijay Immanuel <vijayi@attalasystems.com>
Mon, 8 May 2017 23:38:35 +0000 (16:38 -0700)
committerJens Axboe <axboe@fb.com>
Sat, 20 May 2017 16:11:34 +0000 (10:11 -0600)
On rdma read errors, release the sq ref that was taken
when the req was initialized. This avoids a hang in
nvmet_sq_destroy() when the queue is being freed.

Signed-off-by: Vijay Immanuel <vijayi@attalasystems.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
drivers/nvme/target/core.c
drivers/nvme/target/nvmet.h
drivers/nvme/target/rdma.c

index cf90713043da01ea7180d227feb2895da3653f49..eb9399ac97cff2d5bba89457f6a828238854b98a 100644 (file)
@@ -529,6 +529,12 @@ fail:
 }
 EXPORT_SYMBOL_GPL(nvmet_req_init);
 
+void nvmet_req_uninit(struct nvmet_req *req)
+{
+       percpu_ref_put(&req->sq->ref);
+}
+EXPORT_SYMBOL_GPL(nvmet_req_uninit);
+
 static inline bool nvmet_cc_en(u32 cc)
 {
        return cc & 0x1;
index 7cb77ba5993b98e0974a66a7712961c434677a7f..cfc5c7fb0ab78411f8d6e96ab7ffaaad241b6244 100644 (file)
@@ -261,6 +261,7 @@ u16 nvmet_parse_fabrics_cmd(struct nvmet_req *req);
 
 bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
                struct nvmet_sq *sq, struct nvmet_fabrics_ops *ops);
+void nvmet_req_uninit(struct nvmet_req *req);
 void nvmet_req_complete(struct nvmet_req *req, u16 status);
 
 void nvmet_cq_setup(struct nvmet_ctrl *ctrl, struct nvmet_cq *cq, u16 qid,
index 99c69018a35f4419b3dc3a14576c373c044e661a..9e45cde633767be2176770c7ebd71a90b3ca3094 100644 (file)
@@ -567,6 +567,7 @@ static void nvmet_rdma_read_data_done(struct ib_cq *cq, struct ib_wc *wc)
        rsp->n_rdma = 0;
 
        if (unlikely(wc->status != IB_WC_SUCCESS)) {
+               nvmet_req_uninit(&rsp->req);
                nvmet_rdma_release_rsp(rsp);
                if (wc->status != IB_WC_WR_FLUSH_ERR) {
                        pr_info("RDMA READ for CQE 0x%p failed with status %s (%d).\n",