Added fc_fcp_pkt_destory() and used this as exch destructor callback.
Added extra fsp pkt hold when sending fsp with new exchange and
later same hold is released by fc_fcp_pkt_destory() to free fsp pkt
along with exch free.
I've done some testing with this patch. The fsp pkt tracking is
looking good in my testing but in some cases I couldn't unload fcoe stack.
This could be un-related to this patch but will ensure that this is not
due to this patch with some more testing before committing this patch.
Signed-off-by: Vasu Dev <[EMAIL PROTECTED]>
---
drivers/scsi/libfc/fc_fcp.c | 34 +++++++++++++++++++++++-----------
1 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 358a26b..0201cfe 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -232,6 +232,23 @@ static void fc_fcp_pkt_hold(struct fc_fcp_pkt *sp)
}
/**
+ * fc_fcp_pkt_destory - release hold on scsi_pkt packet
+ *
+ * @sp: exchange sequence
+ * @fsp: fcp packet struct
+ *
+ * Release hold on scsi_pkt packet set to keep scsi_pkt
+ * till EM layer exch resource is not freed.
+ * Context : called from from EM layer.
+ * no locking required
+ */
+static void fc_fcp_pkt_destroy(struct fc_seq *sp, void *arg)
+{
+ struct fc_fcp_pkt *fsp = arg;
+ fc_fcp_pkt_release(fsp);
+}
+
+/**
* fc_fcp_lock_pkt - lock a packet and get a ref to it.
* @fsp: fcp packet
*
@@ -1023,7 +1040,8 @@ static int fc_fcp_send_cmd(struct fc_fcp_pkt *fsp)
fsp->max_payload = rport->maxframe_size;
rp = rport->dd_data;
sp = lp->tt.exch_seq_send(lp, fp,
- fc_fcp_recv, NULL,
+ fc_fcp_recv,
+ fc_fcp_pkt_destroy,
fsp, 0,
rp->local_port->fid,
rport->port_id,
@@ -1034,6 +1052,7 @@ static int fc_fcp_send_cmd(struct fc_fcp_pkt *fsp)
goto unlock;
}
fsp->seq_ptr = sp;
+ fc_fcp_pkt_hold(fsp); /* hold for fc_fcp_pkt_destroy */
setup_timer(&fsp->timer, fc_fcp_timeout, (unsigned long)fsp);
fc_fcp_timer_set(fsp,
@@ -1129,7 +1148,8 @@ static void fc_lun_reset_send(unsigned long data)
rport = fsp->rport;
rp = rport->dd_data;
sp = lp->tt.exch_seq_send(lp, fp,
- fc_tm_done, NULL,
+ fc_tm_done,
+ fc_fcp_pkt_destroy,
fsp, 0,
rp->local_port->fid,
rport->port_id,
@@ -1137,6 +1157,7 @@ static void fc_lun_reset_send(unsigned long data)
if (sp) {
fsp->seq_ptr = sp;
+ fc_fcp_pkt_hold(fsp); /* hold for fc_fcp_pkt_destroy */
goto unlock;
}
/*
@@ -1182,12 +1203,6 @@ static int fc_lun_reset(struct fc_lport *lp, struct
fc_fcp_pkt *fsp,
spin_lock_bh(&fsp->scsi_pkt_lock);
if (fsp->seq_ptr) {
- /* TODO:
- * if the exch resp function is running and trying to grab
- * the scsi_pkt_lock, this could free the exch from under
- * it and it could allow the fsp to be freed from under
- * fc_tm_done.
- */
lp->tt.exch_done(fsp->seq_ptr);
fsp->seq_ptr = NULL;
}
@@ -1230,9 +1245,6 @@ static void fc_tm_done(struct fc_seq *sp, struct fc_frame
*fp, void *arg)
/*
* raced with eh timeout handler.
- *
- * TODO: If this happens we could be freeing the fsp right now and
- * would oops. Next patches will fix this race.
*/
if ((fsp->state & FC_SRB_COMPL) || !fsp->seq_ptr ||
!fsp->wait_for_comp) {
_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel