[ewg] [PATCH IB/VNIC] BUG FIX for VNIC hang on CM Reject
Ramachandra Kuchimanchi
ramachandra.kuchimanchi at qlogic.com
Mon Mar 26 07:55:29 PDT 2007
From: Poornima Kamath <poornima.kamath at qlogic.com>
Signed-Off-By: Ramachandra Kuchimanchi <ramachandra.kuchimanchi at qlogic.com>
This is a fix for the VNIC hanging on stopping the service when there is a CM
Reject.
---
drivers/infiniband/ulp/vnic/vnic_ib.c | 12 ++++++------
drivers/infiniband/ulp/vnic/vnic_ib.h | 1 -
drivers/infiniband/ulp/vnic/vnic_viport.c | 4 ----
3 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/infiniband/ulp/vnic/vnic_ib.c b/drivers/infiniband/ulp/vnic/vnic_ib.c
index 56ae9f7..f3a40d1 100644
--- a/drivers/infiniband/ulp/vnic/vnic_ib.c
+++ b/drivers/infiniband/ulp/vnic/vnic_ib.c
@@ -395,6 +395,7 @@ int vnic_ib_cm_handler(struct ib_cm_id *
switch (event->event) {
case IB_CM_REQ_ERROR:
IB_ERROR("sending CM REQ failed\n");
+ err = 1;
disconn = 1;
break;
case IB_CM_REP_RECEIVED:
@@ -417,6 +418,7 @@ int vnic_ib_cm_handler(struct ib_cm_id *
printk(KERN_ERR "reason code : 0x%x\n",
event->param.rej_rcvd.reason);
+ err = 1;
disconn = 1;
break;
case IB_CM_MRA_RECEIVED:
@@ -439,17 +441,15 @@ int vnic_ib_cm_handler(struct ib_cm_id *
}
+ if (disconn)
+ viport->disconnect = 1;
+
if (err) {
ib_conn->state = IB_CONN_DISCONNECTED;
viport_failure(viport);
}
- if (disconn) {
- ib_conn->state = IB_CONN_DISCONNECTED;
- viport_disconnect(viport);
-
- }
- complete(&ib_conn->done);
+ viport_kick(viport);
return 0;
}
diff --git a/drivers/infiniband/ulp/vnic/vnic_ib.h b/drivers/infiniband/ulp/vnic/vnic_ib.h
index f009876..ad66c24 100644
--- a/drivers/infiniband/ulp/vnic/vnic_ib.h
+++ b/drivers/infiniband/ulp/vnic/vnic_ib.h
@@ -63,7 +63,6 @@ struct vnic_ib_conn {
struct ib_qp *qp;
struct ib_cq *cq;
struct ib_cm_id *cm_id;
- struct completion done;
#ifdef CONFIG_INFINIBAND_VNIC_STATS
struct {
cycles_t connection_time;
diff --git a/drivers/infiniband/ulp/vnic/vnic_viport.c b/drivers/infiniband/ulp/vnic/vnic_viport.c
index 1dee71a..a19fd4c 100644
--- a/drivers/infiniband/ulp/vnic/vnic_viport.c
+++ b/drivers/infiniband/ulp/vnic/vnic_viport.c
@@ -428,7 +428,6 @@ static int viport_handle_control_states(
do {
switch(old_state = viport->link_state) {
case LINK_CONTROLCONNECT:
- init_completion(&(viport->control.ib_conn.done));
if (vnic_ib_cm_connect(&viport->control.ib_conn))
viport->link_state = LINK_CLEANUPDATA;
else
@@ -436,7 +435,6 @@ static int viport_handle_control_states(
break;
case LINK_CONTROLCONNECTWAIT:
LINK_STATE("state LINK_CONTROLCONNECTWAIT\n");
- wait_for_completion(&(viport->control.ib_conn.done));
if (control_is_connected(&viport->control))
viport->link_state = LINK_INITVNICREQ;
if (viport->errored) {
@@ -530,7 +528,6 @@ static int viport_handle_data_states(str
break;
case LINK_DATACONNECT:
LINK_STATE("state LINK_DATACONNECT\n");
- init_completion(&viport->data.ib_conn.done);
if (data_connect(&viport->data))
viport->link_state = LINK_RESETCONTROL;
else
@@ -538,7 +535,6 @@ static int viport_handle_data_states(str
break;
case LINK_DATACONNECTWAIT:
LINK_STATE("state LINK_DATACONNECTWAIT\n");
- wait_for_completion(&viport->data.ib_conn.done);
control_process_async(&viport->control);
if (data_is_connected(&viport->data))
viport->link_state = LINK_XCHGPOOLREQ;
More information about the ewg
mailing list