[ofa-general] [PATCH] RDMA:nes: improve cm_id reference count handling
Faisal Latif
faisal.latif at intel.com
Tue Apr 14 14:20:18 PDT 2009
We are now calling cm_id's ref count increment from only connect, accept,
reject, and listen. The ref count will only be derecremented when
cm_node is freed.
Couple of error handling improvements while doing the cm_id reference count
enhancement are also included.
Signed-off-by: Faisal Latif <faisal.latif at intel.com>
---
drivers/infiniband/hw/nes/nes_cm.c | 41 +++++++++++++++-----------------
drivers/infiniband/hw/nes/nes_hw.c | 1 -
drivers/infiniband/hw/nes/nes_verbs.c | 2 -
3 files changed, 19 insertions(+), 25 deletions(-)
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 61da9d3..57d867e 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -490,7 +490,6 @@ static void nes_retrans_expired(struct nes_cm_node *cm_node)
static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node)
{
struct nes_timer_entry *recv_entry = cm_node->recv_entry;
- struct iw_cm_id *cm_id = cm_node->cm_id;
struct nes_qp *nesqp;
unsigned long qplockflags;
@@ -522,8 +521,6 @@ static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node)
/* TIME_WAIT state */
rem_ref_cm_node(cm_node->cm_core, cm_node);
}
- if (cm_node->cm_id)
- cm_id->rem_ref(cm_id);
kfree(recv_entry);
cm_node->recv_entry = NULL;
}
@@ -994,8 +991,6 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
event.cm_info.cm_id = cm_node->cm_id;
cm_event_reset(&event);
- rem_ref_cm_node(cm_node->cm_core,
- cm_node);
}
}
@@ -1219,6 +1214,7 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
{
unsigned long flags;
struct nes_qp *nesqp;
+ struct iw_cm_id *cm_id = cm_node->cm_id;
if (!cm_node)
return -EINVAL;
@@ -1260,6 +1256,14 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
nes_rem_ref(&nesqp->ibqp);
cm_node->nesqp = NULL;
}
+ if (cm_id) {
+ if (cm_node->listener) {
+ if (cm_node->cm_id != cm_node->listener->cm_id)
+ cm_id->rem_ref(cm_id);
+ } else {
+ cm_id->rem_ref(cm_id);
+ }
+ }
kfree(cm_node);
return 0;
@@ -1410,14 +1414,10 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
drop_packet(skb);
break;
case NES_CM_STATE_LAST_ACK:
- cm_node->cm_id->rem_ref(cm_node->cm_id);
+ case NES_CM_STATE_FIN_WAIT1:
case NES_CM_STATE_TIME_WAIT:
- cm_node->state = NES_CM_STATE_CLOSED;
- rem_ref_cm_node(cm_node->cm_core, cm_node);
- drop_packet(skb);
+ passive_open_err(cm_node, skb, reset);
break;
- case NES_CM_STATE_FIN_WAIT1:
- nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__);
default:
drop_packet(skb);
break;
@@ -1721,7 +1721,6 @@ static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
case NES_CM_STATE_CLOSING:
cleanup_retrans_entry(cm_node);
cm_node->state = NES_CM_STATE_CLOSED;
- cm_node->cm_id->rem_ref(cm_node->cm_id);
rem_ref_cm_node(cm_node->cm_core, cm_node);
drop_packet(skb);
break;
@@ -2101,6 +2100,7 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
passive_state = atomic_add_return(1, &cm_node->passive_state);
if (passive_state == NES_SEND_RESET_EVENT) {
cm_node->state = NES_CM_STATE_CLOSED;
+ cm_id->add_ref(cm_id);
rem_ref_cm_node(cm_core, cm_node);
} else {
ret = send_mpa_reject(cm_node);
@@ -2126,7 +2126,6 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
cm_id = loopback->cm_id;
rem_ref_cm_node(cm_core, loopback);
- cm_id->rem_ref(cm_id);
}
return ret;
@@ -2588,7 +2587,6 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
}
- cm_id->rem_ref(cm_id);
spin_lock_irqsave(&nesqp->lock, flags);
if (nesqp->flush_issued == 0) {
@@ -2708,7 +2706,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
/* associate the node with the QP */
nesqp->cm_node = (void *)cm_node;
cm_node->nesqp = nesqp;
- nes_add_ref(&nesqp->ibqp);
nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n",
nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener);
@@ -2761,6 +2758,9 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
nes_debug(NES_DBG_CM, "Unable to register memory region"
"for lSMM for cm_node = %p \n",
cm_node);
+ pci_free_consistent(nesdev->pcidev,
+ nesqp->private_data_len+sizeof(struct ietf_mpa_frame),
+ nesqp->ietf_frame, nesqp->ietf_frame_pbase);
return -ENOMEM;
}
@@ -2797,6 +2797,8 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
/* Cache the cm_id in the qp */
+ nes_add_ref(&nesqp->ibqp);
+ cm_id->add_ref(cm_id);
nesqp->cm_id = cm_id;
cm_node->cm_id = cm_id;
@@ -2875,8 +2877,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
sizeof(struct ietf_mpa_frame));
- /* notify OF layer that accept event was successful */
- cm_id->add_ref(cm_id);
+ /* notify OF layer that accept event was successfull */
cm_event.event = IW_CM_EVENT_ESTABLISHED;
cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED;
@@ -3360,7 +3361,6 @@ static void cm_event_connect_error(struct nes_cm_event *event)
if (ret)
printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
"ret=%d\n", __func__, __LINE__, ret);
- cm_id->rem_ref(cm_id);
rem_ref_cm_node(event->cm_node->cm_core, event->cm_node);
return;
@@ -3400,7 +3400,6 @@ static void cm_event_reset(struct nes_cm_event *event)
cm_event.private_data_len = 0;
ret = cm_id->event_handler(cm_id, &cm_event);
- cm_id->add_ref(cm_id);
atomic_inc(&cm_closes);
cm_event.event = IW_CM_EVENT_CLOSE;
cm_event.status = IW_CM_EVENT_STATUS_OK;
@@ -3416,7 +3415,7 @@ static void cm_event_reset(struct nes_cm_event *event)
/* notify OF layer about this connection error event */
- cm_id->rem_ref(cm_id);
+ rem_ref_cm_node(event->cm_node->cm_core, event->cm_node);
return;
}
@@ -3518,7 +3517,6 @@ static int nes_cm_post_event(struct nes_cm_event *event)
{
atomic_inc(&event->cm_node->cm_core->events_posted);
add_ref_cm_node(event->cm_node);
- event->cm_info.cm_id->add_ref(event->cm_info.cm_id);
INIT_WORK(&event->event_work, nes_cm_event_handler);
nes_debug(NES_DBG_CM, "cm_node=%p queue_work, event=%p\n",
event->cm_node, event);
@@ -3590,7 +3588,6 @@ static void nes_cm_event_handler(struct work_struct *work)
}
atomic_dec(&cm_core->events_posted);
- event->cm_info.cm_id->rem_ref(event->cm_info.cm_id);
rem_ref_cm_node(cm_core, event->cm_node);
kfree(event);
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index d6fc9ae..9c9e4ff 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -2944,7 +2944,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
case NES_AEQE_AEID_LLP_FIN_RECEIVED:
nesqp = *((struct nes_qp **)&context);
if (atomic_inc_return(&nesqp->close_timer_started) == 1) {
- nesqp->cm_id->add_ref(nesqp->cm_id);
schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp,
NES_TIMER_TYPE_CLOSE, 1, 0);
nes_debug(NES_DBG_AEQ, "QP%u Not decrementing QP refcount (%d),"
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index dab7e2f..ad9c1f5 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -1542,7 +1542,6 @@ static int nes_destroy_qp(struct ib_qp *ibqp)
"QP%u. cm_id = %p, refcount = %u. \n",
nesqp->hwqp.qp_id, cm_id, atomic_read(&nesqp->refcount));
- cm_id->rem_ref(cm_id);
ret = cm_id->event_handler(cm_id, &cm_event);
if (ret)
nes_debug(NES_DBG_QP, "OFA CM event_handler returned, ret=%d\n", ret);
@@ -3178,7 +3177,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
if (nesqp->cm_id) {
/* These two are for the timer thread */
if (atomic_inc_return(&nesqp->close_timer_started) == 1) {
- nesqp->cm_id->add_ref(nesqp->cm_id);
nes_debug(NES_DBG_MOD_QP, "QP%u Not decrementing QP refcount (%d),"
" need ae to finish up, original_last_aeq = 0x%04X."
" last_aeq = 0x%04X, scheduling timer.\n",
--
1.5.3.3
More information about the general
mailing list