diff options
author | Eddie Wai <eddie.wai@broadcom.com> | 2010-11-23 18:29:21 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-12-21 13:24:10 -0500 |
commit | 8eea2f55a65b9471276e78e5c86ddd19c4c0365c (patch) | |
tree | 5b40a3401d20d6d40ce22e86307e3252a3e7b67d | |
parent | 5ee32576269f33b66c6dbc98144aead1e74a1e91 (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.c | 2 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 3 | ||||
-rw-r--r-- | include/scsi/libiscsi.h | 1 |
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 | } |
540 | EXPORT_SYMBOL_GPL(__iscsi_get_task); | 540 | EXPORT_SYMBOL_GPL(__iscsi_get_task); |
541 | 541 | ||
542 | static void __iscsi_put_task(struct iscsi_task *task) | 542 | void __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 | } |
547 | EXPORT_SYMBOL_GPL(__iscsi_put_task); | ||
547 | 548 | ||
548 | void iscsi_put_task(struct iscsi_task *task) | 549 | void 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); | |||
419 | extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t); | 419 | extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t); |
420 | extern void iscsi_requeue_task(struct iscsi_task *task); | 420 | extern void iscsi_requeue_task(struct iscsi_task *task); |
421 | extern void iscsi_put_task(struct iscsi_task *task); | 421 | extern void iscsi_put_task(struct iscsi_task *task); |
422 | extern void __iscsi_put_task(struct iscsi_task *task); | ||
422 | extern void __iscsi_get_task(struct iscsi_task *task); | 423 | extern void __iscsi_get_task(struct iscsi_task *task); |
423 | extern void iscsi_complete_scsi_task(struct iscsi_task *task, | 424 | extern 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); |