All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ewan Milne <emilne@redhat.com>
To: Nilesh Javali <njavali@marvell.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>,
	linux-scsi@vger.kernel.org,
	GR-QLogic-Storage-Upstream@marvell.com
Subject: Re: [PATCH v2 02/17] qla2xxx: Implement ref count for srb
Date: Thu, 3 Feb 2022 09:44:43 -0500	[thread overview]
Message-ID: <CAGtn9rkP7oUW8T8cjia6V-cq9tat=Pzifmcw+jPmi7juCpLL7g@mail.gmail.com> (raw)
In-Reply-To: <20220110050218.3958-3-njavali@marvell.com>

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@marvell.com> wrote:
>
> From: Saurav Kashyap <skashyap@marvell.com>
>
> 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@vger.kernel.org
> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
> Signed-off-by: Nilesh Javali <njavali@marvell.com>
> Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
> ---
> 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
>


  reply	other threads:[~2022-02-03 14:45 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-10  5:02 [PATCH v2 00/17] qla2xxx misc bug fixes and features Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 01/17] qla2xxx: Refactor asynchronous command initialization Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 02/17] qla2xxx: Implement ref count for srb Nilesh Javali
2022-02-03 14:44   ` Ewan Milne [this message]
2022-02-04  7:16     ` Saurav Kashyap
2022-02-08 10:59       ` Saurav Kashyap
2022-02-09 20:09         ` Ewan Milne
2022-01-10  5:02 ` [PATCH v2 03/17] qla2xxx: fix stuck session in gpdb Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 04/17] qla2xxx: Fix warning message due to adisc is being flush Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 05/17] qla2xxx: Fix premature hw access after pci error Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 06/17] qla2xxx: Fix scheduling while atomic Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 07/17] qla2xxx: add retry for exec fw Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 08/17] qla2xxx: Show wrong FDMI data for 64G adaptor Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 09/17] qla2xxx: Add ql2xnvme_queues module param to configure number of NVME queues Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 10/17] qla2xxx: Fix device reconnect in loop topology Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 11/17] qla2xxx: fix warning for missing error code Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 12/17] qla2xxx: edif: Fix clang warning Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 13/17] qla2xxx: Fix T10 PI tag escape and IP guard options for 28XX adapters Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 14/17] qla2xxx: Suppress a kernel complaint in qla_create_qpair() Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 15/17] qla2xxx: Add devid's and conditionals for 28xx Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 16/17] qla2xxx: check for firmware dump already collected Nilesh Javali
2022-01-10  5:02 ` [PATCH v2 17/17] qla2xxx: Update version to 10.02.07.300-k Nilesh Javali
2022-01-25  5:00 ` [PATCH v2 00/17] qla2xxx misc bug fixes and features Martin K. Petersen
2022-02-01  2:04 ` Martin K. Petersen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAGtn9rkP7oUW8T8cjia6V-cq9tat=Pzifmcw+jPmi7juCpLL7g@mail.gmail.com' \
    --to=emilne@redhat.com \
    --cc=GR-QLogic-Storage-Upstream@marvell.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=njavali@marvell.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.