[no subject]

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

 



[   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