aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEddie Wai <eddie.wai@broadcom.com>2010-11-23 18:29:21 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-12-21 13:24:10 -0500
commit8eea2f55a65b9471276e78e5c86ddd19c4c0365c (patch)
tree5b40a3401d20d6d40ce22e86307e3252a3e7b67d
parent5ee32576269f33b66c6dbc98144aead1e74a1e91 (diff)
[SCSI] bnx2i: Added fix for NOP-Out response panic from unsolicited NOP-In
The patch fixes the following situations where NOP-Out pkt is called for: - local unsolicited NOP-Out requests (requesting no NOP-In response) - local NOP-Out responses to unsolicited NOP-In requests kernel panic is observed due to double session spin_lock requests; one in the bnx2i_process_nopin_local_cmpl routine in bnx2i_hwi.c and the other in the iscsi_put_task routine in libiscsi.c The proposed fix is to export the currently static __iscsi_put_task() routine and have bnx2i call it directly instead of the iscsi_put_task() routine which holds the session spin lock. Signed-off-by: Eddie Wai <eddie.wai@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Reviewed-by: Anil Veerabhadrappa <anilgv@broadcom.com> Acked-by: Benjamin Li <benli@broadcom.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c2
-rw-r--r--drivers/scsi/libiscsi.c3
-rw-r--r--include/scsi/libiscsi.h1
3 files changed, 4 insertions, 2 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 16c76e0b2318..32cf9306ffcb 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -1513,7 +1513,7 @@ static void bnx2i_process_nopin_local_cmpl(struct iscsi_session *session,
1513 task = iscsi_itt_to_task(conn, 1513 task = iscsi_itt_to_task(conn,
1514 nop_in->itt & ISCSI_NOP_IN_MSG_INDEX); 1514 nop_in->itt & ISCSI_NOP_IN_MSG_INDEX);
1515 if (task) 1515 if (task)
1516 iscsi_put_task(task); 1516 __iscsi_put_task(task);
1517 spin_unlock(&session->lock); 1517 spin_unlock(&session->lock);
1518} 1518}
1519 1519
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index c15fde808c33..7551abe40900 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -539,11 +539,12 @@ void __iscsi_get_task(struct iscsi_task *task)
539} 539}
540EXPORT_SYMBOL_GPL(__iscsi_get_task); 540EXPORT_SYMBOL_GPL(__iscsi_get_task);
541 541
542static void __iscsi_put_task(struct iscsi_task *task) 542void __iscsi_put_task(struct iscsi_task *task)
543{ 543{
544 if (atomic_dec_and_test(&task->refcount)) 544 if (atomic_dec_and_test(&task->refcount))
545 iscsi_free_task(task); 545 iscsi_free_task(task);
546} 546}
547EXPORT_SYMBOL_GPL(__iscsi_put_task);
547 548
548void iscsi_put_task(struct iscsi_task *task) 549void iscsi_put_task(struct iscsi_task *task)
549{ 550{
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index b81d969ddc67..68e951d79f0b 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -419,6 +419,7 @@ extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
419extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t); 419extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t);
420extern void iscsi_requeue_task(struct iscsi_task *task); 420extern void iscsi_requeue_task(struct iscsi_task *task);
421extern void iscsi_put_task(struct iscsi_task *task); 421extern void iscsi_put_task(struct iscsi_task *task);
422extern void __iscsi_put_task(struct iscsi_task *task);
422extern void __iscsi_get_task(struct iscsi_task *task); 423extern void __iscsi_get_task(struct iscsi_task *task);
423extern void iscsi_complete_scsi_task(struct iscsi_task *task, 424extern void iscsi_complete_scsi_task(struct iscsi_task *task,
424 uint32_t exp_cmdsn, uint32_t max_cmdsn); 425 uint32_t exp_cmdsn, uint32_t max_cmdsn);