scsi: qedf: Release RRQ reference correctly when RRQ command times out
authorChad Dupuis <chad.dupuis@cavium.com>
Wed, 25 Apr 2018 13:08:53 +0000 (06:08 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 8 May 2018 04:57:10 +0000 (00:57 -0400)
When an RRQ request times out the reference is not getting decremented
correctly as there are still ELS commands leftover when we flush any
pending I/Os during offload:

[  281.788553] [0000:21:00.3]:[qedf_cmd_timeout:58]:4: ELS timeout, xid=0x96a.
...
[  281.788553] [0000:21:00.3]:[qedf_cmd_timeout:58]:4: ELS timeout, xid=0x96a.
[  281.788772] [0000:21:00.3]:[qedf_rrq_compl:182]:4: Entered.
[  281.788774] [0000:21:00.3]:[qedf_rrq_compl:200]:4: rrq_compl: orig io = ffffc90004c556f8, orig xid = 0x81b, rrq_xid = 0x96a, refcount=1
...
[  331.448032] [0000:21:00.3]:[qedf_flush_els_req:1512]:4: Flushing ELS request xid=0x96a refcount=2.

The fix is to call kref_put on the rrq_req in case of timeout as the
timeout handler will call rrq_compl directly vs. a normal completion
where it is call from els_compl.

Signed-off-by: Chad Dupuis <chad.dupuis@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qedf/qedf_els.c

index 7024a21..816f693 100644 (file)
@@ -201,6 +201,14 @@ static void qedf_rrq_compl(struct qedf_els_cb_arg *cb_arg)
                kref_put(&orig_io_req->refcount, qedf_release_cmd);
 
 out_free:
+       /*
+        * Release a reference to the rrq request if we timed out as the
+        * rrq completion handler is called directly from the timeout handler
+        * and not from els_compl where the reference would have normally been
+        * released.
+        */
+       if (rrq_req->event == QEDF_IOREQ_EV_ELS_TMO)
+               kref_put(&rrq_req->refcount, qedf_release_cmd);
        kfree(cb_arg);
 }