Commit 15eea140 authored by Joe Carnuccio's avatar Joe Carnuccio Committed by Greg Kroah-Hartman

qla2xxx: Allow vref count to timeout on vport delete.

commit c4a9b538 upstream.
Signed-off-by: default avatarJoe Carnuccio <joe.carnuccio@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f7c1a6ec
...@@ -2154,8 +2154,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) ...@@ -2154,8 +2154,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
"Timer for the VP[%d] has stopped\n", vha->vp_idx); "Timer for the VP[%d] has stopped\n", vha->vp_idx);
} }
BUG_ON(atomic_read(&vha->vref_count));
qla2x00_free_fcports(vha); qla2x00_free_fcports(vha);
mutex_lock(&ha->vport_lock); mutex_lock(&ha->vport_lock);
...@@ -2163,7 +2161,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) ...@@ -2163,7 +2161,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
clear_bit(vha->vp_idx, ha->vp_idx_map); clear_bit(vha->vp_idx, ha->vp_idx_map);
mutex_unlock(&ha->vport_lock); mutex_unlock(&ha->vport_lock);
if (vha->qpair->vp_idx == vha->vp_idx) { if (vha->qpair && vha->qpair->vp_idx == vha->vp_idx) {
if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS)
ql_log(ql_log_warn, vha, 0x7087, ql_log(ql_log_warn, vha, 0x7087,
"Queue Pair delete failed.\n"); "Queue Pair delete failed.\n");
......
...@@ -3788,6 +3788,7 @@ typedef struct scsi_qla_host { ...@@ -3788,6 +3788,7 @@ typedef struct scsi_qla_host {
struct qla8044_reset_template reset_tmplt; struct qla8044_reset_template reset_tmplt;
struct qla_tgt_counters tgt_counters; struct qla_tgt_counters tgt_counters;
uint16_t bbcr; uint16_t bbcr;
wait_queue_head_t vref_waitq;
} scsi_qla_host_t; } scsi_qla_host_t;
struct qla27xx_image_status { struct qla27xx_image_status {
...@@ -3843,14 +3844,17 @@ struct qla2_sgx { ...@@ -3843,14 +3844,17 @@ struct qla2_sgx {
mb(); \ mb(); \
if (__vha->flags.delete_progress) { \ if (__vha->flags.delete_progress) { \
atomic_dec(&__vha->vref_count); \ atomic_dec(&__vha->vref_count); \
wake_up(&__vha->vref_waitq); \
__bail = 1; \ __bail = 1; \
} else { \ } else { \
__bail = 0; \ __bail = 0; \
} \ } \
} while (0) } while (0)
#define QLA_VHA_MARK_NOT_BUSY(__vha) \ #define QLA_VHA_MARK_NOT_BUSY(__vha) do { \
atomic_dec(&__vha->vref_count); \ atomic_dec(&__vha->vref_count); \
wake_up(&__vha->vref_waitq); \
} while (0) \
#define QLA_QPAIR_MARK_BUSY(__qpair, __bail) do { \ #define QLA_QPAIR_MARK_BUSY(__qpair, __bail) do { \
atomic_inc(&__qpair->ref_count); \ atomic_inc(&__qpair->ref_count); \
......
...@@ -4352,6 +4352,7 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha) ...@@ -4352,6 +4352,7 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha)
} }
} }
atomic_dec(&vha->vref_count); atomic_dec(&vha->vref_count);
wake_up(&vha->vref_waitq);
} }
spin_unlock_irqrestore(&ha->vport_slock, flags); spin_unlock_irqrestore(&ha->vport_slock, flags);
} }
......
...@@ -74,13 +74,14 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) ...@@ -74,13 +74,14 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
* ensures no active vp_list traversal while the vport is removed * ensures no active vp_list traversal while the vport is removed
* from the queue) * from the queue)
*/ */
spin_lock_irqsave(&ha->vport_slock, flags); wait_event_timeout(vha->vref_waitq, atomic_read(&vha->vref_count),
while (atomic_read(&vha->vref_count)) { 10*HZ);
spin_unlock_irqrestore(&ha->vport_slock, flags);
msleep(500);
spin_lock_irqsave(&ha->vport_slock, flags); spin_lock_irqsave(&ha->vport_slock, flags);
if (atomic_read(&vha->vref_count)) {
ql_dbg(ql_dbg_vport, vha, 0xfffa,
"vha->vref_count=%u timeout\n", vha->vref_count.counter);
vha->vref_count = (atomic_t)ATOMIC_INIT(0);
} }
list_del(&vha->list); list_del(&vha->list);
qlt_update_vp_map(vha, RESET_VP_IDX); qlt_update_vp_map(vha, RESET_VP_IDX);
...@@ -269,6 +270,7 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb) ...@@ -269,6 +270,7 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
spin_lock_irqsave(&ha->vport_slock, flags); spin_lock_irqsave(&ha->vport_slock, flags);
atomic_dec(&vha->vref_count); atomic_dec(&vha->vref_count);
wake_up(&vha->vref_waitq);
} }
i++; i++;
} }
......
...@@ -4215,6 +4215,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, ...@@ -4215,6 +4215,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
spin_lock_init(&vha->work_lock); spin_lock_init(&vha->work_lock);
spin_lock_init(&vha->cmd_list_lock); spin_lock_init(&vha->cmd_list_lock);
init_waitqueue_head(&vha->vref_waitq);
sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no);
ql_dbg(ql_dbg_init, vha, 0x0041, ql_dbg(ql_dbg_init, vha, 0x0041,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment