aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Carnuccio <joe.carnuccio@cavium.com>2017-03-15 12:48:43 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2017-03-18 20:27:56 -0400
commitc4a9b538ab2a109c5f9798bea1f8f4bf93aadfb9 (patch)
tree81394821fc6f114be2aa2bb697f3be15b53e7e04
parent7d7a743543905a8297dce53b36e793e5307da5d7 (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.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c14
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c1
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
4081struct qla27xx_image_status { 4082struct 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);