[ofa-general] [PATCH 08/10] RDMA/nes: Change accept_pend_cnt to atomic

Chien Tung chien.tin.tung at intel.com
Fri Nov 21 12:50:58 PST 2008


From: Faisal Latif <faisal.latif at intel.com>

RDMA/nes: Change accept_pend_cnt to atomic

There is a race condition on accept_pend_cnt.  Change it to atomic.

Signed-off-by: Faisal Latif <faisal.latif at intel.com>
Signed-off-by: Chien Tung <chien.tin.tung at intel.com>
--
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index cc10da1..0025a7e 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -976,7 +976,7 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
 	u32 was_timer_set;
 	cm_node->accelerated = 1;
 
-	if (cm_node->accept_pend) {
+	if (atomic_dec_and_test(&cm_node->accept_pend)) {
 		BUG_ON(!cm_node->listener);
 		atomic_dec(&cm_node->listener->pend_accepts_cnt);
 		BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
@@ -1091,7 +1091,7 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
 	atomic_inc(&cm_core->node_cnt);
 	cm_node->conn_type = cm_info->conn_type;
 	cm_node->apbvt_set = 0;
-	cm_node->accept_pend = 0;
+	atomic_set(&cm_node->accept_pend, 0);
 
 	cm_node->nesvnic = nesvnic;
 	/* get some device handles, for arp lookup */
@@ -1156,7 +1156,7 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
 	spin_unlock_irqrestore(&cm_node->cm_core->ht_lock, flags);
 
 	/* if the node is destroyed before connection was accelerated */
-	if (!cm_node->accelerated && cm_node->accept_pend) {
+	if (!cm_node->accelerated && atomic_read(&cm_node->accept_pend)) {
 		BUG_ON(!cm_node->listener);
 		atomic_dec(&cm_node->listener->pend_accepts_cnt);
 		BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
@@ -1477,25 +1477,25 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
 		break;
 	case NES_CM_STATE_LISTENING:
 		/* Passive OPEN */
-		cm_node->accept_pend = 1;
-		atomic_inc(&cm_node->listener->pend_accepts_cnt);
 		if (atomic_read(&cm_node->listener->pend_accepts_cnt) >
 				cm_node->listener->backlog) {
 			nes_debug(NES_DBG_CM, "drop syn due to backlog "
 				"pressure \n");
 			cm_backlog_drops++;
-			passive_open_err(cm_node, skb, 0);
+			rem_ref_cm_node(cm_node->cm_core, cm_node);
+			dev_kfree_skb_any(skb);
 			break;
 		}
 		ret = handle_tcp_options(cm_node, tcph, skb, optionsize,
 			1);
 		if (ret) {
-			passive_open_err(cm_node, skb, 0);
-			/* drop pkt */
 			break;
 		}
 		cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
 		BUG_ON(cm_node->send_entry);
+		atomic_set(&cm_node->accept_pend, 1);
+		atomic_inc(&cm_node->listener->pend_accepts_cnt);
+
 		cm_node->state = NES_CM_STATE_SYN_RCVD;
 		send_syn(cm_node, 1, skb);
 		break;
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index fafa350..7600365 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -294,7 +294,7 @@ struct nes_cm_node {
 	enum nes_cm_conn_type     conn_type;
 	struct nes_vnic           *nesvnic;
 	int                       apbvt_set;
-	int                       accept_pend;
+	atomic_t                  accept_pend;
 	int			freed;
 	struct list_head	timer_entry;
 	struct list_head	reset_entry;



More information about the general mailing list