Hi Ewan, Thanks for reporting this, the patch, "qla2xxx: Add qla2x00_async_done routine for async routines", fixes this issue and is submitted upstream. Can you test it out and let us know the results? Thanks, ~Saurav > -----Original Message----- > From: Saurav Kashyap > Sent: Friday, February 4, 2022 12:47 PM > To: Ewan Milne <emilne@xxxxxxxxxx>; Nilesh Javali <njavali@xxxxxxxxxxx> > Cc: Martin K. Petersen <martin.petersen@xxxxxxxxxx>; linux- > scsi@xxxxxxxxxxxxxxx; GR-QLogic-Storage-Upstream <GR-QLogic-Storage- > Upstream@xxxxxxxxxxx> > Subject: RE: [PATCH v2 02/17] qla2xxx: Implement ref count for srb > > Hi Ewan, > This patch have undergone extensive testing from our side and we didn't hit > any of the issues. Can you share the test case? So that we can try to reproduce > this? > > Thanks, > ~Saurav > > > -----Original Message----- > > From: Ewan Milne <emilne@xxxxxxxxxx> > > Sent: Thursday, February 3, 2022 8:15 PM > > To: Nilesh Javali <njavali@xxxxxxxxxxx> > > Cc: Martin K. Petersen <martin.petersen@xxxxxxxxxx>; linux- > > scsi@xxxxxxxxxxxxxxx; GR-QLogic-Storage-Upstream <GR-QLogic-Storage- > > Upstream@xxxxxxxxxxx> > > Subject: Re: [PATCH v2 02/17] qla2xxx: Implement ref count for srb > > > > This commit causes at least 2 of our systems with Qlogic HBAs to panic on > > boot: > > From the look of it, it is possible that a timer was left active on a > > freed object or something. > > > > [ 44.232603] general protection fault, probably for non-canonical > > address 0xdead00000000012a: 0000 [#1] PR > > [ 44.247211] CPU: 9 PID: 0 Comm: swapper/9 Tainted: G I > > 5.17.0-rc1 #4 > > [ 44.254870] Hardware name: Dell Inc. PowerEdge R440/0WKGTH, BIOS > > 1.4.8 05/22/2018 > > [ 44.262349] RIP: 0010:__run_timers.part.0+0x19c/0x260 > > [ 44.267411] Code: 00 48 8b 03 49 c7 47 08 00 00 00 00 48 85 c0 74 > > 61 48 8b 2b 49 89 6f 08 66 90 48 8b 45 > > [ 44.286156] RSP: 0018:ffffb0a7803ecef0 EFLAGS: 00010086 > > [ 44.291383] RAX: dead000000000122 RBX: ffffb0a7803ecf00 RCX: > > 0000000000000009 > > [ 44.298515] RDX: ffffb0a7803ecf00 RSI: ffff91dad1060380 RDI: > > ffff91dad10603a8 > > [ 44.305646] RBP: ffff91cfe34c8c10 R08: 0000000000000000 R09: > > 0000000000000000 > > [ 44.312780] R10: 0000000000000002 R11: 00000000000000ca R12: > > 00000000fffc1200 > > [ 44.319911] R13: dead000000000122 R14: 0000000000000001 R15: > > ffff91dad1060380 > > [ 44.327045] FS: 0000000000000000(0000) GS:ffff91dad1040000(0000) > > knlGS:0000000000000000 > > [ 44.335131] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > > [ 44.340877] CR2: 00007ff966417870 CR3: 00000002db010004 CR4: > > 00000000007706e0 > > [ 44.348010] DR0: 0000000000000000 DR1: 0000000000000000 DR2: > > 0000000000000000 > > [ 44.355143] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: > > 0000000000000400 > > [ 44.362274] PKRU: 55555554 > > [ 44.364987] Call Trace: > > [ 44.367442] <IRQ> > > [ 44.369460] ? tick_sched_timer+0x6d/0x80 > > [ 44.373472] ? _raw_spin_lock_irq+0x14/0x40 > > [ 44.377658] ? __hrtimer_run_queues+0x139/0x2c0 > > [ 44.382190] ? recalibrate_cpu_khz+0x10/0x10 > > [ 44.386464] run_timer_softirq+0x31/0x60 > > [ 44.390391] __do_softirq+0xf6/0x2fb > > [ 44.393968] __irq_exit_rcu+0xe2/0x130 > > [ 44.397720] sysvec_apic_timer_interrupt+0xa2/0xd0 > > [ 44.402514] </IRQ> > > [ 44.404619] <TASK> > > [ 44.406725] asm_sysvec_apic_timer_interrupt+0x12/0x20 > > > > > > -Ewan > > > > On Mon, Jan 10, 2022 at 12:03 AM Nilesh Javali <njavali@xxxxxxxxxxx> > wrote: > > > > > > From: Saurav Kashyap <skashyap@xxxxxxxxxxx> > > > > > > The timeout handler and done function are racing. When > > > qla2x00_async_iocb_timeout() starts to run it can be preempted by the > > > normal response path (via the firmware?). qla24xx_async_gpsc_sp_done() > > > releases the SRB unconditionally. When scheduling back to > > > qla2x00_async_iocb_timeout() qla24xx_async_abort_cmd() will access an > > > freed sp->qpair pointer: > > > > > > qla2xxx [0000:83:00.0]-2871:0: Async-gpsc timeout - hdl=63d > > portid=234500 50:06:0e:80:08:77:b6:21. > > > qla2xxx [0000:83:00.0]-2853:0: Async done-gpsc res 0, WWPN > > 50:06:0e:80:08:77:b6:21 > > > qla2xxx [0000:83:00.0]-2854:0: Async-gpsc OUT WWPN > > 20:45:00:27:f8:75:33:00 speeds=2c00 speed=0400. > > > qla2xxx [0000:83:00.0]-28d8:0: qla24xx_handle_gpsc_event > > 50:06:0e:80:08:77:b6:21 DS 7 LS 6 rc 0 login 1|1 rscn 1|0 lid 5 > > > BUG: unable to handle kernel NULL pointer dereference at > > 0000000000000004 > > > IP: qla24xx_async_abort_cmd+0x1b/0x1c0 [qla2xxx] > > > > > > Obvious solution to this is to introduce a reference counter. One > > > reference is taken for the normal code path (the 'good case') and one > > > for the timeout path. As we always race between the normal good case > > > and the timeout/abort handler we need to serialize it. Also we cannot > > > assume any order between the handlers. Since this is slow path we can > > > use proper synchronization via locks. > > > > > > When we are able to cancel a timer (del_timer returns 1) we know there > > > can't be any error handling in progress because the timeout handler > > > hasn't expired yet, thus we can safely decrement the refcounter by one. > > > > > > If we are not able to cancel the timer, we know an abort handler is > > > running. We have to make sure we call sp->done() in the abort handlers > > > before calling kref_put(). > > > > > > Cc: stable@xxxxxxxxxxxxxxx > > > Signed-off-by: Daniel Wagner <dwagner@xxxxxxx> > > > Signed-off-by: Saurav Kashyap <skashyap@xxxxxxxxxxx> > > > Signed-off-by: Nilesh Javali <njavali@xxxxxxxxxxx> > > > Reviewed-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx> > > > --- > > > v1->v2: > > > - update detailed issue description and the solution > > > > > > drivers/scsi/qla2xxx/qla_bsg.c | 6 ++- > > > drivers/scsi/qla2xxx/qla_def.h | 5 ++ > > > drivers/scsi/qla2xxx/qla_edif.c | 3 +- > > > drivers/scsi/qla2xxx/qla_gbl.h | 1 + > > > drivers/scsi/qla2xxx/qla_gs.c | 85 +++++++++++++++++++++---------- > > > drivers/scsi/qla2xxx/qla_init.c | 70 +++++++++++++++++-------- > > > drivers/scsi/qla2xxx/qla_inline.h | 2 + > > > drivers/scsi/qla2xxx/qla_iocb.c | 41 +++++++++++---- > > > drivers/scsi/qla2xxx/qla_mbx.c | 4 +- > > > drivers/scsi/qla2xxx/qla_mid.c | 4 +- > > > drivers/scsi/qla2xxx/qla_mr.c | 4 +- > > > drivers/scsi/qla2xxx/qla_os.c | 14 +++-- > > > drivers/scsi/qla2xxx/qla_target.c | 4 +- > > > 13 files changed, 173 insertions(+), 70 deletions(-) > > > > > > diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c > > > index 9da8034ccad4..c2f00f076f79 100644 > > > --- a/drivers/scsi/qla2xxx/qla_bsg.c > > > +++ b/drivers/scsi/qla2xxx/qla_bsg.c > > > @@ -29,7 +29,8 @@ void qla2x00_bsg_job_done(srb_t *sp, int res) > > > "%s: sp hdl %x, result=%x bsg ptr %p\n", > > > __func__, sp->handle, res, bsg_job); > > > > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > > > > bsg_reply->result = res; > > > bsg_job_done(bsg_job, bsg_reply->result, > > > @@ -3013,7 +3014,8 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_job) > > > > > > done: > > > spin_unlock_irqrestore(&ha->hardware_lock, flags); > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > return 0; > > > } > > > > > > diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h > > > index 9ebf4a234d9a..a5fc01b4fa96 100644 > > > --- a/drivers/scsi/qla2xxx/qla_def.h > > > +++ b/drivers/scsi/qla2xxx/qla_def.h > > > @@ -726,6 +726,11 @@ typedef struct srb { > > > * code. > > > */ > > > void (*put_fn)(struct kref *kref); > > > + > > > + /* > > > + * Report completion for asynchronous commands. > > > + */ > > > + void (*async_done)(struct srb *sp, int res); > > > } srb_t; > > > > > > #define GET_CMD_SP(sp) (sp->u.scmd.cmd) > > > diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c > > > index 53d2b8562027..c04957c363d8 100644 > > > --- a/drivers/scsi/qla2xxx/qla_edif.c > > > +++ b/drivers/scsi/qla2xxx/qla_edif.c > > > @@ -2146,7 +2146,8 @@ edif_doorbell_show(struct device *dev, struct > > device_attribute *attr, > > > > > > static void qla_noop_sp_done(srb_t *sp, int res) > > > { > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > /* > > > diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h > > > index 5056564f0d0c..3f8b8bbabe6d 100644 > > > --- a/drivers/scsi/qla2xxx/qla_gbl.h > > > +++ b/drivers/scsi/qla2xxx/qla_gbl.h > > > @@ -333,6 +333,7 @@ extern int qla24xx_get_one_block_sg(uint32_t, > > struct qla2_sgx *, uint32_t *); > > > extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *); > > > extern int qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, > > > struct qla_work_evt *e); > > > +void qla2x00_sp_release(struct kref *kref); > > > > > > /* > > > * Global Function Prototypes in qla_mbx.c source file. > > > diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c > > > index 744eb3192056..a812f4a45232 100644 > > > --- a/drivers/scsi/qla2xxx/qla_gs.c > > > +++ b/drivers/scsi/qla2xxx/qla_gs.c > > > @@ -529,7 +529,6 @@ static void qla2x00_async_sns_sp_done(srb_t *sp, > int > > rc) > > > if (!e) > > > goto err2; > > > > > > - del_timer(&sp->u.iocb_cmd.timer); > > > e->u.iosb.sp = sp; > > > qla2x00_post_work(vha, e); > > > return; > > > @@ -556,8 +555,8 @@ static void qla2x00_async_sns_sp_done(srb_t *sp, > int > > rc) > > > sp->u.iocb_cmd.u.ctarg.rsp = NULL; > > > } > > > > > > - sp->free(sp); > > > - > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > return; > > > } > > > > > > @@ -592,6 +591,7 @@ static int qla_async_rftid(scsi_qla_host_t *vha, > > port_id_t *d_id) > > > if (!vha->flags.online) > > > goto done; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -652,7 +652,8 @@ static int qla_async_rftid(scsi_qla_host_t *vha, > > port_id_t *d_id) > > > } > > > return rval; > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > return rval; > > > } > > > @@ -687,6 +688,7 @@ static int qla_async_rffid(scsi_qla_host_t *vha, > > port_id_t *d_id, > > > srb_t *sp; > > > struct ct_sns_pkt *ct_sns; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -747,7 +749,8 @@ static int qla_async_rffid(scsi_qla_host_t *vha, > > port_id_t *d_id, > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > return rval; > > > } > > > @@ -777,6 +780,7 @@ static int qla_async_rnnid(scsi_qla_host_t *vha, > > port_id_t *d_id, > > > srb_t *sp; > > > struct ct_sns_pkt *ct_sns; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -836,7 +840,8 @@ static int qla_async_rnnid(scsi_qla_host_t *vha, > > port_id_t *d_id, > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > return rval; > > > } > > > @@ -882,6 +887,7 @@ static int qla_async_rsnn_nn(scsi_qla_host_t *vha) > > > srb_t *sp; > > > struct ct_sns_pkt *ct_sns; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -947,7 +953,8 @@ static int qla_async_rsnn_nn(scsi_qla_host_t *vha) > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > return rval; > > > } > > > @@ -2887,7 +2894,8 @@ static void qla24xx_async_gpsc_sp_done(srb_t > > *sp, int res) > > > qla24xx_handle_gpsc_event(vha, &ea); > > > > > > done: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport) > > > @@ -2899,6 +2907,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, > > fc_port_t *fcport) > > > if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) > > > return rval; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -2938,7 +2947,8 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, > > fc_port_t *fcport) > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > return rval; > > > } > > > @@ -2987,7 +2997,8 @@ void qla24xx_sp_unmap(scsi_qla_host_t *vha, > > srb_t *sp) > > > break; > > > } > > > > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg > > *ea) > > > @@ -3126,13 +3137,15 @@ static void > qla2x00_async_gpnid_sp_done(srb_t > > *sp, int res) > > > if (res) { > > > if (res == QLA_FUNCTION_TIMEOUT) { > > > qla24xx_post_gpnid_work(sp->vha, &ea.id); > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > return; > > > } > > > } else if (sp->gen1) { > > > /* There was another RSCN for this Nport ID */ > > > qla24xx_post_gpnid_work(sp->vha, &ea.id); > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > return; > > > } > > > > > > @@ -3153,7 +3166,8 @@ static void qla2x00_async_gpnid_sp_done(srb_t > > *sp, int res) > > > sp->u.iocb_cmd.u.ctarg.rsp_dma); > > > sp->u.iocb_cmd.u.ctarg.rsp = NULL; > > > > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > return; > > > } > > > > > > @@ -3173,6 +3187,7 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, > > port_id_t *id) > > > if (!vha->flags.online) > > > goto done; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -3189,7 +3204,8 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, > > port_id_t *id) > > > if (tsp->u.iocb_cmd.u.ctarg.id.b24 == id->b24) { > > > tsp->gen1++; > > > spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > goto done; > > > } > > > } > > > @@ -3259,8 +3275,8 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, > > port_id_t *id) > > > sp->u.iocb_cmd.u.ctarg.rsp_dma); > > > sp->u.iocb_cmd.u.ctarg.rsp = NULL; > > > } > > > - > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > return rval; > > > } > > > @@ -3315,7 +3331,8 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int > > res) > > > ea.rc = res; > > > > > > qla24xx_handle_gffid_event(vha, &ea); > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > /* Get FC4 Feature with Nport ID. */ > > > @@ -3328,6 +3345,7 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, > > fc_port_t *fcport) > > > if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) > > > return rval; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); > > > if (!sp) > > > return rval; > > > @@ -3366,7 +3384,8 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, > > fc_port_t *fcport) > > > > > > return rval; > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > fcport->flags &= ~FCF_ASYNC_SENT; > > > return rval; > > > } > > > @@ -3753,7 +3772,6 @@ static void > > qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) > > > "Async done-%s res %x FC4Type %x\n", > > > sp->name, res, sp->gen2); > > > > > > - del_timer(&sp->u.iocb_cmd.timer); > > > sp->rc = res; > > > if (res) { > > > unsigned long flags; > > > @@ -3921,8 +3939,8 @@ static int qla24xx_async_gnnft(scsi_qla_host_t > > *vha, struct srb *sp, > > > sp->u.iocb_cmd.u.ctarg.rsp_dma); > > > sp->u.iocb_cmd.u.ctarg.rsp = NULL; > > > } > > > - > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > > > > spin_lock_irqsave(&vha->work_lock, flags); > > > vha->scan.scan_flags &= ~SF_SCANNING; > > > @@ -3974,9 +3992,12 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, > u8 > > fc4_type, srb_t *sp) > > > ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, > > > "%s: Performing FCP Scan\n", __func__); > > > > > > - if (sp) > > > - sp->free(sp); /* should not happen */ > > > + if (sp) { > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > + } > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); > > > if (!sp) { > > > spin_lock_irqsave(&vha->work_lock, flags); > > > @@ -4021,6 +4042,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, > u8 > > fc4_type, srb_t *sp) > > > sp->u.iocb_cmd.u.ctarg.req, > > > sp->u.iocb_cmd.u.ctarg.req_dma); > > > sp->u.iocb_cmd.u.ctarg.req = NULL; > > > + /* ref: INIT */ > > > qla2x00_rel_sp(sp); > > > return rval; > > > } > > > @@ -4083,7 +4105,8 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, > u8 > > fc4_type, srb_t *sp) > > > sp->u.iocb_cmd.u.ctarg.rsp = NULL; > > > } > > > > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > > > > spin_lock_irqsave(&vha->work_lock, flags); > > > vha->scan.scan_flags &= ~SF_SCANNING; > > > @@ -4147,7 +4170,8 @@ static void qla2x00_async_gnnid_sp_done(srb_t > > *sp, int res) > > > > > > qla24xx_handle_gnnid_event(vha, &ea); > > > > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport) > > > @@ -4160,6 +4184,7 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, > > fc_port_t *fcport) > > > return rval; > > > > > > qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID); > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); > > > if (!sp) > > > goto done; > > > @@ -4200,7 +4225,8 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, > > fc_port_t *fcport) > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > fcport->flags &= ~FCF_ASYNC_SENT; > > > done: > > > return rval; > > > @@ -4274,7 +4300,8 @@ static void qla2x00_async_gfpnid_sp_done(srb_t > > *sp, int res) > > > > > > qla24xx_handle_gfpnid_event(vha, &ea); > > > > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport) > > > @@ -4286,6 +4313,7 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, > > fc_port_t *fcport) > > > if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) > > > return rval; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); > > > if (!sp) > > > goto done; > > > @@ -4326,7 +4354,8 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, > > fc_port_t *fcport) > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > return rval; > > > } > > > diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c > > > index e6f13cb6fa28..38c11b75f644 100644 > > > --- a/drivers/scsi/qla2xxx/qla_init.c > > > +++ b/drivers/scsi/qla2xxx/qla_init.c > > > @@ -51,6 +51,9 @@ qla2x00_sp_timeout(struct timer_list *t) > > > WARN_ON(irqs_disabled()); > > > iocb = &sp->u.iocb_cmd; > > > iocb->timeout(sp); > > > + > > > + /* ref: TMR */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > void qla2x00_sp_free(srb_t *sp) > > > @@ -125,8 +128,13 @@ static void qla24xx_abort_iocb_timeout(void > *data) > > > } > > > spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); > > > > > > - if (sp->cmd_sp) > > > + if (sp->cmd_sp) { > > > + /* > > > + * This done function should take care of > > > + * original command ref: INIT > > > + */ > > > sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED); > > > + } > > > > > > abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT); > > > sp->done(sp, QLA_OS_TIMER_EXPIRED); > > > @@ -140,11 +148,11 @@ static void qla24xx_abort_sp_done(srb_t *sp, int > > res) > > > if (orig_sp) > > > qla_wait_nvme_release_cmd_kref(orig_sp); > > > > > > - del_timer(&sp->u.iocb_cmd.timer); > > > if (sp->flags & SRB_WAKEUP_ON_COMP) > > > complete(&abt->u.abt.comp); > > > else > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) > > > @@ -154,6 +162,7 @@ int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool > > wait) > > > srb_t *sp; > > > int rval = QLA_FUNCTION_FAILED; > > > > > > + /* ref: INIT for ABTS command */ > > > sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp- > > >fcport, > > > GFP_ATOMIC); > > > if (!sp) > > > @@ -181,7 +190,8 @@ int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool > > wait) > > > > > > rval = qla2x00_start_sp(sp); > > > if (rval != QLA_SUCCESS) { > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > return rval; > > > } > > > > > > @@ -189,7 +199,8 @@ int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool > > wait) > > > wait_for_completion(&abt_iocb->u.abt.comp); > > > rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ? > > > QLA_SUCCESS : QLA_ERR_FROM_FW; > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > return rval; > > > @@ -287,7 +298,8 @@ static void qla2x00_async_login_sp_done(srb_t *sp, > > int res) > > > qla24xx_handle_plogi_done_event(vha, &ea); > > > } > > > > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int > > > @@ -306,6 +318,7 @@ qla2x00_async_login(struct scsi_qla_host *vha, > > fc_port_t *fcport, > > > return rval; > > > } > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -354,7 +367,8 @@ qla2x00_async_login(struct scsi_qla_host *vha, > > fc_port_t *fcport, > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > fcport->flags &= ~FCF_ASYNC_SENT; > > > done: > > > fcport->flags &= ~FCF_ASYNC_ACTIVE; > > > @@ -366,7 +380,8 @@ static void qla2x00_async_logout_sp_done(srb_t > *sp, > > int res) > > > sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); > > > sp->fcport->login_gen++; > > > qlt_logo_completion_handler(sp->fcport, sp- > > >u.iocb_cmd.u.logio.data[0]); > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int > > > @@ -376,6 +391,7 @@ qla2x00_async_logout(struct scsi_qla_host *vha, > > fc_port_t *fcport) > > > int rval = QLA_FUNCTION_FAILED; > > > > > > fcport->flags |= FCF_ASYNC_SENT; > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -397,7 +413,8 @@ qla2x00_async_logout(struct scsi_qla_host *vha, > > fc_port_t *fcport) > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); > > > return rval; > > > @@ -423,7 +440,8 @@ static void qla2x00_async_prlo_sp_done(srb_t *sp, > > int res) > > > if (!test_bit(UNLOADING, &vha->dpc_flags)) > > > qla2x00_post_async_prlo_done_work(sp->fcport->vha, sp->fcport, > > > lio->u.logio.data); > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int > > > @@ -433,6 +451,7 @@ qla2x00_async_prlo(struct scsi_qla_host *vha, > > fc_port_t *fcport) > > > int rval; > > > > > > rval = QLA_FUNCTION_FAILED; > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -454,7 +473,8 @@ qla2x00_async_prlo(struct scsi_qla_host *vha, > > fc_port_t *fcport) > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > fcport->flags &= ~FCF_ASYNC_ACTIVE; > > > return rval; > > > @@ -539,8 +559,8 @@ static void qla2x00_async_adisc_sp_done(srb_t > *sp, > > int res) > > > ea.sp = sp; > > > > > > qla24xx_handle_adisc_event(vha, &ea); > > > - > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int > > > @@ -555,6 +575,7 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, > > fc_port_t *fcport, > > > return rval; > > > > > > fcport->flags |= FCF_ASYNC_SENT; > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -582,7 +603,8 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, > > fc_port_t *fcport, > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); > > > qla2x00_post_async_adisc_work(vha, fcport, data); > > > @@ -1063,7 +1085,8 @@ static void qla24xx_async_gnl_sp_done(srb_t > *sp, > > int res) > > > } > > > spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); > > > > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) > > > @@ -1093,6 +1116,7 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, > > fc_port_t *fcport) > > > vha->gnl.sent = 1; > > > spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -1125,7 +1149,8 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, > > fc_port_t *fcport) > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > fcport->flags &= ~(FCF_ASYNC_ACTIVE | FCF_ASYNC_SENT); > > > return rval; > > > @@ -1171,7 +1196,7 @@ static void qla24xx_async_gpdb_sp_done(srb_t > > *sp, int res) > > > dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, > > > sp->u.iocb_cmd.u.mbx.in_dma); > > > > > > - sp->free(sp); > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport) > > > @@ -1216,7 +1241,7 @@ static void qla2x00_async_prli_sp_done(srb_t > *sp, > > int res) > > > qla24xx_handle_prli_done_event(vha, &ea); > > > } > > > > > > - sp->free(sp); > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int > > > @@ -1274,7 +1299,8 @@ qla24xx_async_prli(struct scsi_qla_host *vha, > > fc_port_t *fcport) > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > fcport->flags &= ~FCF_ASYNC_SENT; > > > return rval; > > > } > > > @@ -1359,7 +1385,7 @@ int qla24xx_async_gpdb(struct scsi_qla_host > *vha, > > fc_port_t *fcport, u8 opt) > > > if (pd) > > > dma_pool_free(ha->s_dma_pool, pd, pd_dma); > > > > > > - sp->free(sp); > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > fcport->flags &= ~FCF_ASYNC_SENT; > > > done: > > > fcport->flags &= ~FCF_ASYNC_ACTIVE; > > > @@ -1945,6 +1971,7 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, > > uint32_t flags, uint32_t lun, > > > srb_t *sp; > > > int rval = QLA_FUNCTION_FAILED; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -1988,7 +2015,8 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, > > uint32_t flags, uint32_t lun, > > > } > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > fcport->flags &= ~FCF_ASYNC_SENT; > > > done: > > > return rval; > > > diff --git a/drivers/scsi/qla2xxx/qla_inline.h > > b/drivers/scsi/qla2xxx/qla_inline.h > > > index 5f3b7995cc8f..db17f7f410cd 100644 > > > --- a/drivers/scsi/qla2xxx/qla_inline.h > > > +++ b/drivers/scsi/qla2xxx/qla_inline.h > > > @@ -184,6 +184,8 @@ static void qla2xxx_init_sp(srb_t *sp, > scsi_qla_host_t > > *vha, > > > sp->vha = vha; > > > sp->qpair = qpair; > > > sp->cmd_type = TYPE_SRB; > > > + /* ref : INIT - normal flow */ > > > + kref_init(&sp->cmd_kref); > > > INIT_LIST_HEAD(&sp->elem); > > > } > > > > > > diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c > > > index 95aae9a9631e..7dd82214d59f 100644 > > > --- a/drivers/scsi/qla2xxx/qla_iocb.c > > > +++ b/drivers/scsi/qla2xxx/qla_iocb.c > > > @@ -2560,6 +2560,14 @@ qla24xx_tm_iocb(srb_t *sp, struct > > tsk_mgmt_entry *tsk) > > > } > > > } > > > > > > +void > > > +qla2x00_sp_release(struct kref *kref) > > > +{ > > > + struct srb *sp = container_of(kref, struct srb, cmd_kref); > > > + > > > + sp->free(sp); > > > +} > > > + > > > void > > > qla2x00_init_async_sp(srb_t *sp, unsigned long tmo, > > > void (*done)(struct srb *sp, int res)) > > > @@ -2655,7 +2663,9 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int > > els_opcode, > > > return -ENOMEM; > > > } > > > > > > - /* Alloc SRB structure */ > > > + /* Alloc SRB structure > > > + * ref: INIT > > > + */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); > > > if (!sp) { > > > kfree(fcport); > > > @@ -2687,7 +2697,8 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int > > els_opcode, > > > GFP_KERNEL); > > > > > > if (!elsio->u.els_logo.els_logo_pyld) { > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > return QLA_FUNCTION_FAILED; > > > } > > > > > > @@ -2710,7 +2721,8 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int > > els_opcode, > > > > > > rval = qla2x00_start_sp(sp); > > > if (rval != QLA_SUCCESS) { > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > return QLA_FUNCTION_FAILED; > > > } > > > > > > @@ -2721,7 +2733,8 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int > > els_opcode, > > > > > > wait_for_completion(&elsio->u.els_logo.comp); > > > > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > return rval; > > > } > > > > > > @@ -2854,7 +2867,6 @@ static void qla2x00_els_dcmd2_sp_done(srb_t > *sp, > > int res) > > > sp->name, res, sp->handle, fcport->d_id.b24, fcport->port_name); > > > > > > fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE); > > > - del_timer(&sp->u.iocb_cmd.timer); > > > > > > if (sp->flags & SRB_WAKEUP_ON_COMP) > > > complete(&lio->u.els_plogi.comp); > > > @@ -2964,7 +2976,8 @@ static void qla2x00_els_dcmd2_sp_done(srb_t > *sp, > > int res) > > > struct srb_iocb *elsio = &sp->u.iocb_cmd; > > > > > > qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi); > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > return; > > > } > > > e->u.iosb.sp = sp; > > > @@ -2982,7 +2995,9 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, > int > > els_opcode, > > > int rval = QLA_SUCCESS; > > > void *ptr, *resp_ptr; > > > > > > - /* Alloc SRB structure */ > > > + /* Alloc SRB structure > > > + * ref: INIT > > > + */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); > > > if (!sp) { > > > ql_log(ql_log_info, vha, 0x70e6, > > > @@ -3071,7 +3086,8 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, > int > > els_opcode, > > > out: > > > fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); > > > qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi); > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > return rval; > > > } > > > @@ -3882,8 +3898,15 @@ qla2x00_start_sp(srb_t *sp) > > > break; > > > } > > > > > > - if (sp->start_timer) > > > + if (sp->start_timer) { > > > + /* ref: TMR timer ref > > > + * this code should be just before start_iocbs function > > > + * This will make sure that caller function don't to do > > > + * kref_put even on failure > > > + */ > > > + kref_get(&sp->cmd_kref); > > > add_timer(&sp->u.iocb_cmd.timer); > > > + } > > > > > > wmb(); > > > qla2x00_start_iocbs(vha, qp->req); > > > diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c > > > index 2aacd3653245..38e0f02c75e1 100644 > > > --- a/drivers/scsi/qla2xxx/qla_mbx.c > > > +++ b/drivers/scsi/qla2xxx/qla_mbx.c > > > @@ -6479,6 +6479,7 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host > > *vha, mbx_cmd_t *mcp) > > > if (!vha->hw->flags.fw_started) > > > goto done; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -6524,7 +6525,8 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host > > *vha, mbx_cmd_t *mcp) > > > } > > > > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > return rval; > > > } > > > diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c > > > index c4a967c96fd6..e6b5c4ccce97 100644 > > > --- a/drivers/scsi/qla2xxx/qla_mid.c > > > +++ b/drivers/scsi/qla2xxx/qla_mid.c > > > @@ -965,6 +965,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int > > cmd) > > > if (vp_index == 0 || vp_index >= ha->max_npiv_vports) > > > return QLA_PARAMETER_ERROR; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL); > > > if (!sp) > > > return rval; > > > @@ -1007,6 +1008,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int > > cmd) > > > break; > > > } > > > done: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > return rval; > > > } > > > diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c > > > index e3ae0894c7a8..f726eb8449c5 100644 > > > --- a/drivers/scsi/qla2xxx/qla_mr.c > > > +++ b/drivers/scsi/qla2xxx/qla_mr.c > > > @@ -1787,6 +1787,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t > > *fcport, uint16_t fx_type) > > > struct register_host_info *preg_hsi; > > > struct new_utsname *p_sysid = NULL; > > > > > > + /* ref: INIT */ > > > sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); > > > if (!sp) > > > goto done; > > > @@ -1973,7 +1974,8 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t > > *fcport, uint16_t fx_type) > > > dma_free_coherent(&ha->pdev->dev, fdisc->u.fxiocb.req_len, > > > fdisc->u.fxiocb.req_addr, fdisc->u.fxiocb.req_dma_handle); > > > done_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > return rval; > > > } > > > diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c > > > index abcd30917263..0a7b00d165c7 100644 > > > --- a/drivers/scsi/qla2xxx/qla_os.c > > > +++ b/drivers/scsi/qla2xxx/qla_os.c > > > @@ -728,7 +728,8 @@ void qla2x00_sp_compl(srb_t *sp, int res) > > > struct scsi_cmnd *cmd = GET_CMD_SP(sp); > > > struct completion *comp = sp->comp; > > > > > > - sp->free(sp); > > > + /* kref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > cmd->result = res; > > > CMD_SP(cmd) = NULL; > > > scsi_done(cmd); > > > @@ -819,7 +820,8 @@ void qla2xxx_qpair_sp_compl(srb_t *sp, int res) > > > struct scsi_cmnd *cmd = GET_CMD_SP(sp); > > > struct completion *comp = sp->comp; > > > > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > cmd->result = res; > > > CMD_SP(cmd) = NULL; > > > scsi_done(cmd); > > > @@ -919,6 +921,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, > > struct scsi_cmnd *cmd) > > > goto qc24_target_busy; > > > > > > sp = scsi_cmd_priv(cmd); > > > + /* ref: INIT */ > > > qla2xxx_init_sp(sp, vha, vha->hw->base_qpair, fcport); > > > > > > sp->u.scmd.cmd = cmd; > > > @@ -938,7 +941,8 @@ qla2xxx_queuecommand(struct Scsi_Host *host, > > struct scsi_cmnd *cmd) > > > return 0; > > > > > > qc24_host_busy_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > > > > qc24_target_busy: > > > return SCSI_MLQUEUE_TARGET_BUSY; > > > @@ -1008,6 +1012,7 @@ qla2xxx_mqueuecommand(struct Scsi_Host > *host, > > struct scsi_cmnd *cmd, > > > goto qc24_target_busy; > > > > > > sp = scsi_cmd_priv(cmd); > > > + /* ref: INIT */ > > > qla2xxx_init_sp(sp, vha, qpair, fcport); > > > > > > sp->u.scmd.cmd = cmd; > > > @@ -1026,7 +1031,8 @@ qla2xxx_mqueuecommand(struct Scsi_Host > *host, > > struct scsi_cmnd *cmd, > > > return 0; > > > > > > qc24_host_busy_free_sp: > > > - sp->free(sp); > > > + /* ref: INIT */ > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > > > > qc24_target_busy: > > > return SCSI_MLQUEUE_TARGET_BUSY; > > > diff --git a/drivers/scsi/qla2xxx/qla_target.c > > b/drivers/scsi/qla2xxx/qla_target.c > > > index 83c8c55017d1..b0990f2ee91c 100644 > > > --- a/drivers/scsi/qla2xxx/qla_target.c > > > +++ b/drivers/scsi/qla2xxx/qla_target.c > > > @@ -620,7 +620,7 @@ static void qla2x00_async_nack_sp_done(srb_t *sp, > > int res) > > > } > > > spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); > > > > > > - sp->free(sp); > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > } > > > > > > int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport, > > > @@ -672,7 +672,7 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, > > fc_port_t *fcport, > > > return rval; > > > > > > done_free_sp: > > > - sp->free(sp); > > > + kref_put(&sp->cmd_kref, qla2x00_sp_release); > > > done: > > > fcport->flags &= ~FCF_ASYNC_SENT; > > > return rval; > > > -- > > > 2.23.1 > > >