Re: [PATCH v2 02/17] qla2xxx: Implement ref count for srb

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thanks, that appears to have resolved the crash on boot I was seeing.

Tested-by: Ewan D. Milne <emilne@xxxxxxxxxx>

On Tue, Feb 8, 2022 at 5:59 AM Saurav Kashyap <skashyap@xxxxxxxxxxx> wrote:
>
> 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
> > > >
>




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux