diff options
author | Joe Carnuccio <joe.carnuccio@cavium.com> | 2017-03-15 12:48:43 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2017-03-18 20:27:56 -0400 |
commit | c4a9b538ab2a109c5f9798bea1f8f4bf93aadfb9 (patch) | |
tree | 81394821fc6f114be2aa2bb697f3be15b53e7e04 | |
parent | 7d7a743543905a8297dce53b36e793e5307da5d7 (diff) |
qla2xxx: Allow vref count to timeout on vport delete.
Cc: <stable@vger.kernel.org>
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>
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 6 | ||||
-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, 16 insertions, 10 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index f610103994af..435ff7fd6384 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -2154,8 +2154,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) | |||
2154 | "Timer for the VP[%d] has stopped\n", vha->vp_idx); | 2154 | "Timer for the VP[%d] has stopped\n", vha->vp_idx); |
2155 | } | 2155 | } |
2156 | 2156 | ||
2157 | BUG_ON(atomic_read(&vha->vref_count)); | ||
2158 | |||
2159 | qla2x00_free_fcports(vha); | 2157 | qla2x00_free_fcports(vha); |
2160 | 2158 | ||
2161 | mutex_lock(&ha->vport_lock); | 2159 | mutex_lock(&ha->vport_lock); |
@@ -2166,7 +2164,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) | |||
2166 | dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l, | 2164 | dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l, |
2167 | vha->gnl.ldma); | 2165 | vha->gnl.ldma); |
2168 | 2166 | ||
2169 | if (vha->qpair->vp_idx == vha->vp_idx) { | 2167 | if (vha->qpair && vha->qpair->vp_idx == vha->vp_idx) { |
2170 | if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) | 2168 | if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) |
2171 | ql_log(ql_log_warn, vha, 0x7087, | 2169 | ql_log(ql_log_warn, vha, 0x7087, |
2172 | "Queue Pair delete failed.\n"); | 2170 | "Queue Pair delete failed.\n"); |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 625d438e3cce..8662ef4192db 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -4076,6 +4076,7 @@ typedef struct scsi_qla_host { | |||
4076 | /* Count of active session/fcport */ | 4076 | /* Count of active session/fcport */ |
4077 | int fcport_count; | 4077 | int fcport_count; |
4078 | wait_queue_head_t fcport_waitQ; | 4078 | wait_queue_head_t fcport_waitQ; |
4079 | wait_queue_head_t vref_waitq; | ||
4079 | } scsi_qla_host_t; | 4080 | } scsi_qla_host_t; |
4080 | 4081 | ||
4081 | struct qla27xx_image_status { | 4082 | struct qla27xx_image_status { |
@@ -4131,14 +4132,17 @@ struct qla2_sgx { | |||
4131 | mb(); \ | 4132 | mb(); \ |
4132 | if (__vha->flags.delete_progress) { \ | 4133 | if (__vha->flags.delete_progress) { \ |
4133 | atomic_dec(&__vha->vref_count); \ | 4134 | atomic_dec(&__vha->vref_count); \ |
4135 | wake_up(&__vha->vref_waitq); \ | ||
4134 | __bail = 1; \ | 4136 | __bail = 1; \ |
4135 | } else { \ | 4137 | } else { \ |
4136 | __bail = 0; \ | 4138 | __bail = 0; \ |
4137 | } \ | 4139 | } \ |
4138 | } while (0) | 4140 | } while (0) |
4139 | 4141 | ||
4140 | #define QLA_VHA_MARK_NOT_BUSY(__vha) \ | 4142 | #define QLA_VHA_MARK_NOT_BUSY(__vha) do { \ |
4141 | atomic_dec(&__vha->vref_count); \ | 4143 | atomic_dec(&__vha->vref_count); \ |
4144 | wake_up(&__vha->vref_waitq); \ | ||
4145 | } while (0) \ | ||
4142 | 4146 | ||
4143 | #define QLA_QPAIR_MARK_BUSY(__qpair, __bail) do { \ | 4147 | #define QLA_QPAIR_MARK_BUSY(__qpair, __bail) do { \ |
4144 | atomic_inc(&__qpair->ref_count); \ | 4148 | atomic_inc(&__qpair->ref_count); \ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 32fb9007f137..9f3740c68cc8 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -5148,6 +5148,7 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha) | |||
5148 | } | 5148 | } |
5149 | } | 5149 | } |
5150 | atomic_dec(&vha->vref_count); | 5150 | atomic_dec(&vha->vref_count); |
5151 | wake_up(&vha->vref_waitq); | ||
5151 | } | 5152 | } |
5152 | spin_unlock_irqrestore(&ha->vport_slock, flags); | 5153 | spin_unlock_irqrestore(&ha->vport_slock, flags); |
5153 | } | 5154 | } |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index c6d6f0d912ff..09a490c98763 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 1fed235a1b4a..54d4e802bde0 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -4268,6 +4268,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, | |||
4268 | spin_lock_init(&vha->work_lock); | 4268 | spin_lock_init(&vha->work_lock); |
4269 | spin_lock_init(&vha->cmd_list_lock); | 4269 | spin_lock_init(&vha->cmd_list_lock); |
4270 | init_waitqueue_head(&vha->fcport_waitQ); | 4270 | init_waitqueue_head(&vha->fcport_waitQ); |
4271 | init_waitqueue_head(&vha->vref_waitq); | ||
4271 | 4272 | ||
4272 | vha->gnl.size = sizeof(struct get_name_list_extended) * | 4273 | vha->gnl.size = sizeof(struct get_name_list_extended) * |
4273 | (ha->max_loop_id + 1); | 4274 | (ha->max_loop_id + 1); |