diff options
| author | Joe Carnuccio <joe.carnuccio@cavium.com> | 2017-03-15 12:48:43 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-04-08 03:30:35 -0400 |
| commit | c1716f0c35cc0d8b58b4708af1f129440596edbc (patch) | |
| tree | b2b7622eb656f3454ffac7c4f86716f2b228030e /drivers/scsi | |
| parent | 5ed56ca86f961f57370e7f9603cc9897654a482a (diff) | |
qla2xxx: Allow vref count to timeout on vport delete.
commit c4a9b538ab2a109c5f9798bea1f8f4bf93aadfb9 upstream.
Signed-off-by: Joe Carnuccio <joe.carnuccio@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/scsi')
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 3 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 1 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 14 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 1 |
5 files changed, 13 insertions, 8 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index fe7469c901f7..ad33238cef17 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
| @@ -2153,8 +2153,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) | |||
| 2153 | "Timer for the VP[%d] has stopped\n", vha->vp_idx); | 2153 | "Timer for the VP[%d] has stopped\n", vha->vp_idx); |
| 2154 | } | 2154 | } |
| 2155 | 2155 | ||
| 2156 | BUG_ON(atomic_read(&vha->vref_count)); | ||
| 2157 | |||
| 2158 | qla2x00_free_fcports(vha); | 2156 | qla2x00_free_fcports(vha); |
| 2159 | 2157 | ||
| 2160 | mutex_lock(&ha->vport_lock); | 2158 | mutex_lock(&ha->vport_lock); |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 73b12e41d992..8e63a7b90277 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
| @@ -3742,6 +3742,7 @@ typedef struct scsi_qla_host { | |||
| 3742 | struct qla8044_reset_template reset_tmplt; | 3742 | struct qla8044_reset_template reset_tmplt; |
| 3743 | struct qla_tgt_counters tgt_counters; | 3743 | struct qla_tgt_counters tgt_counters; |
| 3744 | uint16_t bbcr; | 3744 | uint16_t bbcr; |
| 3745 | wait_queue_head_t vref_waitq; | ||
| 3745 | } scsi_qla_host_t; | 3746 | } scsi_qla_host_t; |
| 3746 | 3747 | ||
| 3747 | struct qla27xx_image_status { | 3748 | struct qla27xx_image_status { |
| @@ -3780,6 +3781,7 @@ struct qla_tgt_vp_map { | |||
| 3780 | mb(); \ | 3781 | mb(); \ |
| 3781 | if (__vha->flags.delete_progress) { \ | 3782 | if (__vha->flags.delete_progress) { \ |
| 3782 | atomic_dec(&__vha->vref_count); \ | 3783 | atomic_dec(&__vha->vref_count); \ |
| 3784 | wake_up(&__vha->vref_waitq); \ | ||
| 3783 | __bail = 1; \ | 3785 | __bail = 1; \ |
| 3784 | } else { \ | 3786 | } else { \ |
| 3785 | __bail = 0; \ | 3787 | __bail = 0; \ |
| @@ -3788,6 +3790,7 @@ struct qla_tgt_vp_map { | |||
| 3788 | 3790 | ||
| 3789 | #define QLA_VHA_MARK_NOT_BUSY(__vha) do { \ | 3791 | #define QLA_VHA_MARK_NOT_BUSY(__vha) do { \ |
| 3790 | atomic_dec(&__vha->vref_count); \ | 3792 | atomic_dec(&__vha->vref_count); \ |
| 3793 | wake_up(&__vha->vref_waitq); \ | ||
| 3791 | } while (0) | 3794 | } while (0) |
| 3792 | 3795 | ||
| 3793 | /* | 3796 | /* |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 5b09296b46a3..8f12f6baa6b8 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -4356,6 +4356,7 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha) | |||
| 4356 | } | 4356 | } |
| 4357 | } | 4357 | } |
| 4358 | atomic_dec(&vha->vref_count); | 4358 | atomic_dec(&vha->vref_count); |
| 4359 | wake_up(&vha->vref_waitq); | ||
| 4359 | } | 4360 | } |
| 4360 | spin_unlock_irqrestore(&ha->vport_slock, flags); | 4361 | spin_unlock_irqrestore(&ha->vport_slock, flags); |
| 4361 | } | 4362 | } |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index cf7ba52bae66..3dfb54abc874 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
| @@ -74,13 +74,14 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) | |||
| 74 | * ensures no active vp_list traversal while the vport is removed | 74 | * ensures no active vp_list traversal while the vport is removed |
| 75 | * from the queue) | 75 | * from the queue) |
| 76 | */ | 76 | */ |
| 77 | spin_lock_irqsave(&ha->vport_slock, flags); | 77 | wait_event_timeout(vha->vref_waitq, atomic_read(&vha->vref_count), |
| 78 | while (atomic_read(&vha->vref_count)) { | 78 | 10*HZ); |
| 79 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
| 80 | |||
| 81 | msleep(500); | ||
| 82 | 79 | ||
| 83 | spin_lock_irqsave(&ha->vport_slock, flags); | 80 | spin_lock_irqsave(&ha->vport_slock, flags); |
| 81 | if (atomic_read(&vha->vref_count)) { | ||
| 82 | ql_dbg(ql_dbg_vport, vha, 0xfffa, | ||
| 83 | "vha->vref_count=%u timeout\n", vha->vref_count.counter); | ||
| 84 | vha->vref_count = (atomic_t)ATOMIC_INIT(0); | ||
| 84 | } | 85 | } |
| 85 | list_del(&vha->list); | 86 | list_del(&vha->list); |
| 86 | qlt_update_vp_map(vha, RESET_VP_IDX); | 87 | qlt_update_vp_map(vha, RESET_VP_IDX); |
| @@ -269,6 +270,7 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb) | |||
| 269 | 270 | ||
| 270 | spin_lock_irqsave(&ha->vport_slock, flags); | 271 | spin_lock_irqsave(&ha->vport_slock, flags); |
| 271 | atomic_dec(&vha->vref_count); | 272 | atomic_dec(&vha->vref_count); |
| 273 | wake_up(&vha->vref_waitq); | ||
| 272 | } | 274 | } |
| 273 | i++; | 275 | i++; |
| 274 | } | 276 | } |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index bea819e5336d..4f361d8d84be 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -4045,6 +4045,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, | |||
| 4045 | 4045 | ||
| 4046 | spin_lock_init(&vha->work_lock); | 4046 | spin_lock_init(&vha->work_lock); |
| 4047 | spin_lock_init(&vha->cmd_list_lock); | 4047 | spin_lock_init(&vha->cmd_list_lock); |
| 4048 | init_waitqueue_head(&vha->vref_waitq); | ||
| 4048 | 4049 | ||
| 4049 | sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); | 4050 | sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); |
| 4050 | ql_dbg(ql_dbg_init, vha, 0x0041, | 4051 | ql_dbg(ql_dbg_init, vha, 0x0041, |
