scsi: qedf: Fix race betwen fipvlan request and response path
There is a race b/w fipvlan request and response path: ===== qedf_fcoe_process_vlan_resp:113]:2: VLAN response, vid=0xffd. qedf_initiate_fipvlan_req:165]:2: vlan = 0x6ffd already set. qedf_set_vlan_id:139]:2: Setting vlan_id=0ffd prio=3. ====== The request thread sees that vlan is already set and fails to call ctrl_link_up. Fix: - While setting vlan_id use local variable and before setting vlan_id. - Call fcoe_ctlr_link_up in next iteration of fipvlan request. Signed-off-by: Saurav Kashyap <skashyap@marvell.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
5797bcc897
commit
3480e7a8c8
|
@ -111,16 +111,18 @@ static struct kmem_cache *qedf_io_work_cache;
|
||||||
|
|
||||||
void qedf_set_vlan_id(struct qedf_ctx *qedf, int vlan_id)
|
void qedf_set_vlan_id(struct qedf_ctx *qedf, int vlan_id)
|
||||||
{
|
{
|
||||||
qedf->vlan_id = vlan_id;
|
int vlan_id_tmp = 0;
|
||||||
qedf->vlan_id |= qedf->prio << VLAN_PRIO_SHIFT;
|
|
||||||
QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "Setting vlan_id=%04x "
|
vlan_id_tmp = vlan_id | (qedf->prio << VLAN_PRIO_SHIFT);
|
||||||
"prio=%d.\n", vlan_id, qedf->prio);
|
qedf->vlan_id = vlan_id_tmp;
|
||||||
|
QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
|
||||||
|
"Setting vlan_id=0x%04x prio=%d.\n",
|
||||||
|
vlan_id_tmp, qedf->prio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if we have a valid vlan, false otherwise */
|
/* Returns true if we have a valid vlan, false otherwise */
|
||||||
static bool qedf_initiate_fipvlan_req(struct qedf_ctx *qedf)
|
static bool qedf_initiate_fipvlan_req(struct qedf_ctx *qedf)
|
||||||
{
|
{
|
||||||
int rc;
|
|
||||||
|
|
||||||
while (qedf->fipvlan_retries--) {
|
while (qedf->fipvlan_retries--) {
|
||||||
/* This is to catch if link goes down during fipvlan retries */
|
/* This is to catch if link goes down during fipvlan retries */
|
||||||
|
@ -136,7 +138,10 @@ static bool qedf_initiate_fipvlan_req(struct qedf_ctx *qedf)
|
||||||
|
|
||||||
if (qedf->vlan_id > 0) {
|
if (qedf->vlan_id > 0) {
|
||||||
QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
|
QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
|
||||||
"vlan = 0x%x already set.\n", qedf->vlan_id);
|
"vlan = 0x%x already set, calling ctlr_link_up.\n",
|
||||||
|
qedf->vlan_id);
|
||||||
|
if (atomic_read(&qedf->link_state) == QEDF_LINK_UP)
|
||||||
|
fcoe_ctlr_link_up(&qedf->ctlr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,13 +149,7 @@ static bool qedf_initiate_fipvlan_req(struct qedf_ctx *qedf)
|
||||||
"Retry %d.\n", qedf->fipvlan_retries);
|
"Retry %d.\n", qedf->fipvlan_retries);
|
||||||
init_completion(&qedf->fipvlan_compl);
|
init_completion(&qedf->fipvlan_compl);
|
||||||
qedf_fcoe_send_vlan_req(qedf);
|
qedf_fcoe_send_vlan_req(qedf);
|
||||||
rc = wait_for_completion_timeout(&qedf->fipvlan_compl,
|
wait_for_completion_timeout(&qedf->fipvlan_compl, 1 * HZ);
|
||||||
1 * HZ);
|
|
||||||
if (rc > 0 &&
|
|
||||||
(atomic_read(&qedf->link_state) == QEDF_LINK_UP)) {
|
|
||||||
fcoe_ctlr_link_up(&qedf->ctlr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue