[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