>
> > 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