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 <[email protected]>
---
 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

_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to