Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 157402
b: refs/heads/master
c: b29a4fc
h: refs/heads/master
v: v3
  • Loading branch information
Don Wood authored and Roland Dreier committed Sep 6, 2009
1 parent c117053 commit 7500188
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 51 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 320cdfd21d4a9f6ef54b74871e0d6b19a0e86fd6
refs/heads/master: b29a4fc49b028dbdab53b679826ed1eb658dde59
102 changes: 52 additions & 50 deletions trunk/drivers/infiniband/hw/nes/nes_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2493,7 +2493,12 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
u16 last_ae;
u8 original_hw_tcp_state;
u8 original_ibqp_state;
u8 issued_disconnect_reset = 0;
enum iw_cm_event_type disconn_status = IW_CM_EVENT_STATUS_OK;
int issue_disconn = 0;
int issue_close = 0;
int issue_flush = 0;
u32 flush_q = NES_CQP_FLUSH_RQ;
struct ib_event ibevent;

if (!nesqp) {
nes_debug(NES_DBG_CM, "disconnect_worker nesqp is NULL\n");
Expand All @@ -2517,24 +2522,55 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
original_ibqp_state = nesqp->ibqp_state;
last_ae = nesqp->last_aeq;

if (nesqp->term_flags) {
issue_disconn = 1;
issue_close = 1;
nesqp->cm_id = NULL;
if (nesqp->flush_issued == 0) {
nesqp->flush_issued = 1;
issue_flush = 1;
}
} else if ((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
((original_ibqp_state == IB_QPS_RTS) &&
(last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
issue_disconn = 1;
if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET)
disconn_status = IW_CM_EVENT_STATUS_RESET;
}

if (((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSED) ||
(original_hw_tcp_state == NES_AEQE_TCP_STATE_TIME_WAIT) ||
(last_ae == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) ||
(last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
issue_close = 1;
nesqp->cm_id = NULL;
if (nesqp->flush_issued == 0) {
nesqp->flush_issued = 1;
issue_flush = 1;
}
}

spin_unlock_irqrestore(&nesqp->lock, flags);

nes_debug(NES_DBG_CM, "set ibqp_state=%u\n", nesqp->ibqp_state);
if ((issue_flush) && (nesqp->destroyed == 0)) {
/* Flush the queue(s) */
if (nesqp->hw_iwarp_state >= NES_AEQE_IWARP_STATE_TERMINATE)
flush_q |= NES_CQP_FLUSH_SQ;
flush_wqes(nesvnic->nesdev, nesqp, flush_q, 1);

if ((nesqp->cm_id) && (cm_id->event_handler)) {
if ((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
((original_ibqp_state == IB_QPS_RTS) &&
(last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
if (nesqp->term_flags) {
ibevent.device = nesqp->ibqp.device;
ibevent.event = nesqp->terminate_eventtype;
ibevent.element.qp = &nesqp->ibqp;
nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
}
}

if ((cm_id) && (cm_id->event_handler)) {
if (issue_disconn) {
atomic_inc(&cm_disconnects);
cm_event.event = IW_CM_EVENT_DISCONNECT;
if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) {
cm_event.status = IW_CM_EVENT_STATUS_RESET;
nes_debug(NES_DBG_CM, "Generating a CM "
"Disconnect Event (status reset) for "
"QP%u, cm_id = %p. \n",
nesqp->hwqp.qp_id, cm_id);
} else
cm_event.status = IW_CM_EVENT_STATUS_OK;

cm_event.status = disconn_status;
cm_event.local_addr = cm_id->local_addr;
cm_event.remote_addr = cm_id->remote_addr;
cm_event.private_data = NULL;
Expand All @@ -2547,28 +2583,14 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
nesqp->hwqp.sq_tail, cm_id,
atomic_read(&nesqp->refcount));

spin_unlock_irqrestore(&nesqp->lock, flags);
ret = cm_id->event_handler(cm_id, &cm_event);
if (ret)
nes_debug(NES_DBG_CM, "OFA CM event_handler "
"returned, ret=%d\n", ret);
spin_lock_irqsave(&nesqp->lock, flags);
}

/* There might have been another AE while the lock was released */
original_hw_tcp_state = nesqp->hw_tcp_state;
original_ibqp_state = nesqp->ibqp_state;
last_ae = nesqp->last_aeq;

if ((issued_disconnect_reset == 0) && (nesqp->cm_id) &&
((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSED) ||
(original_hw_tcp_state == NES_AEQE_TCP_STATE_TIME_WAIT) ||
(last_ae == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) ||
(last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
if (issue_close) {
atomic_inc(&cm_closes);
nesqp->cm_id = NULL;
nesqp->in_disconnect = 0;
spin_unlock_irqrestore(&nesqp->lock, flags);
nes_disconnect(nesqp, 1);

cm_id->provider_data = nesqp;
Expand All @@ -2587,27 +2609,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
}

cm_id->rem_ref(cm_id);

spin_lock_irqsave(&nesqp->lock, flags);
if (nesqp->flush_issued == 0) {
nesqp->flush_issued = 1;
spin_unlock_irqrestore(&nesqp->lock, flags);
flush_wqes(nesvnic->nesdev, nesqp,
NES_CQP_FLUSH_RQ, 1);
} else
spin_unlock_irqrestore(&nesqp->lock, flags);
} else {
cm_id = nesqp->cm_id;
spin_unlock_irqrestore(&nesqp->lock, flags);
/* check to see if the inbound reset beat the outbound reset */
if ((!cm_id) && (last_ae==NES_AEQE_AEID_RESET_SENT)) {
nes_debug(NES_DBG_CM, "QP%u: Decing refcount "
"due to inbound reset beating the "
"outbound reset.\n", nesqp->hwqp.qp_id);
}
}
} else {
spin_unlock_irqrestore(&nesqp->lock, flags);
}

return 0;
Expand Down

0 comments on commit 7500188

Please sign in to comment.