> 
> > Hi Yi,
> >
> > While testing bnx2fc with latest scsi-misc tree, I found a panic during
> > driver load.  I root caused that this is happening due to the following
> > commit:
> >
> > commit 6a716a8535ea8ed7676cea1e122f1c3d02e55b6b
> > Author: Yi Zou <[email protected]>
> > Date:   Mon May 16 16:45:40 2011 -0700
> >
> >      [SCSI] libfc: release DDP context if frame_send() fails
> >
> >      In case frame_send() fails, make sure to let the underlying HW
> > release the DDP
> >      context that has already been set up before calling frame_send().
> >
> >      Signed-off-by: Yi Zou <[email protected]>
> >      Signed-off-by: Robert Love <[email protected]>
> >      Signed-off-by: James Bottomley <[email protected]>
> >
> >
> > bnx2fc does not use FCP functionality of libfc. So, fr_fsp(fp) should
> be
> > NULL for bnx2fc. However, it was panic'ing due to general protection
> > fault. This is because in frame_send, we free the skb before returning,
> > and hence fr_fsp() accesses freed memory, and hence general protection
> > fault.
> >
> > In fc_exch_seq_send(), we are not supposed to touch fp in case of
> > frame_send() failure.
> >
> I see, I really should have cached the fsp there before frame_send() to
> be able to
> release the ddp context for the corresponding fsp. The following should
> fix this since
> fc_fcp_ddp_done() does not need the frame, only the fsp. can you take a
> look?
> 
> 
> diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
> index 01ff082..5108863 100644
> --- a/drivers/scsi/libfc/fc_exch.c
> +++ b/drivers/scsi/libfc/fc_exch.c
> @@ -1962,6 +1962,7 @@ static struct fc_seq *fc_exch_seq_send(struct
> fc_lport *lport,
>         struct fc_exch *ep;
>         struct fc_seq *sp = NULL;
>         struct fc_frame_header *fh;
> +       struct fc_fcp_pkt *fsp = NULL;
>         int rc = 1;
> 
>         ep = fc_exch_alloc(lport, fp);
> @@ -1984,8 +1985,10 @@ static struct fc_seq *fc_exch_seq_send(struct
> fc_lport *lport,
>         fc_exch_setup_hdr(ep, fp, ep->f_ctl);
>         sp->cnt++;
> 
> -       if (ep->xid <= lport->lro_xid && fh->fh_r_ctl ==
> FC_RCTL_DD_UNSOL_CMD)
> +       if (ep->xid <= lport->lro_xid && fh->fh_r_ctl ==
> FC_RCTL_DD_UNSOL_CMD) {
> +               fsp = fr_fsp(fp);
>                 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
> +       }
> 
>         if (unlikely(lport->tt.frame_send(lport, fp)))
>                 goto err;
> @@ -1999,7 +2002,8 @@ static struct fc_seq *fc_exch_seq_send(struct
> fc_lport *lport,
>         spin_unlock_bh(&ep->ex_lock);
>         return sp;
>  err:
> -       fc_fcp_ddp_done(fr_fsp(fp));
> +       if (fsp)
> +               fc_fcp_ddp_done(fr_fsp(fp));

Miss this, this should be just:
                        fc_fcp_ddp_done(fsp);

thanks,
yi

>         rc = fc_exch_done_locked(ep);
>         spin_unlock_bh(&ep->ex_lock);
>         if (!rc)
> 
> 
> thanks,
> yi
> 
> > Thanks,
> > Bhanu
> 
> _______________________________________________
> devel mailing list
> [email protected]
> https://lists.open-fcoe.org/mailman/listinfo/devel
_______________________________________________
devel mailing list
[email protected]
https://lists.open-fcoe.org/mailman/listinfo/devel

Reply via email to