[openib-general] [PATCH] separate listens from peer to peer requests
Sean Hefty
mshefty at ichips.intel.com
Thu Jan 20 16:51:33 PST 2005
Patch separates listen requests from peer-to-peer connection requests.
Peer-to-peer requests are disabled as a result (they were broken).
Listen requests were slightly optimized.
signed-off-by: Sean Hefty <sean.hefty at intel.com>
Index: core/cm.c
===================================================================
--- core/cm.c (revision 1607)
+++ core/cm.c (working copy)
@@ -60,7 +60,8 @@ static struct ib_client cm_client = {
static struct ib_cm {
spinlock_t lock;
- struct rb_root service_table;
+ struct rb_root listen_service_table;
+ /* struct rb_root peer_service_table; todo: fix peer to peer */
struct rb_root remote_qp_table;
struct rb_root remote_id_table;
struct rb_root remote_sidr_table;
@@ -109,6 +110,7 @@ struct cm_id_private {
int timeout_ms;
u8 max_cm_retries;
u8 passive;
+ u8 peer_to_peer;
};
struct cm_recv_work {
@@ -270,9 +272,9 @@ static struct cm_id_private * cm_acquire
return cm_id_priv;
}
-static void cm_insert_service(struct cm_id_private *cm_id_priv)
+static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv)
{
- struct rb_node **link = &cm.service_table.rb_node;
+ struct rb_node **link = &cm.listen_service_table.rb_node;
struct rb_node *parent = NULL;
struct cm_id_private *cur_cm_id_priv;
u64 service_id = cm_id_priv->id.service_id;
@@ -281,18 +283,23 @@ static void cm_insert_service(struct cm_
parent = *link;
cur_cm_id_priv = rb_entry(parent, struct cm_id_private,
service_node);
+ if ((cur_cm_id_priv->id.service_mask & service_id) ==
+ (cur_cm_id_priv->id.service_mask &
+ cur_cm_id_priv->id.service_id))
+ return cm_id_priv;
if (service_id < cur_cm_id_priv->id.service_id)
link = &(*link)->rb_left;
else
link = &(*link)->rb_right;
}
rb_link_node(&cm_id_priv->service_node, parent, link);
- rb_insert_color(&cm_id_priv->service_node, &cm.service_table);
+ rb_insert_color(&cm_id_priv->service_node, &cm.listen_service_table);
+ return NULL;
}
-static struct cm_id_private * cm_find_service(u64 service_id)
+static struct cm_id_private * cm_find_listen(u64 service_id)
{
- struct rb_node *node = cm.service_table.rb_node;
+ struct rb_node *node = cm.listen_service_table.rb_node;
struct cm_id_private *cm_id_priv;
while (node) {
@@ -300,7 +307,6 @@ static struct cm_id_private * cm_find_se
if ((cm_id_priv->id.service_mask & service_id) ==
(cm_id_priv->id.service_mask & cm_id_priv->id.service_id))
return cm_id_priv;
-
if (service_id < cm_id_priv->id.service_id)
node = node->rb_left;
else
@@ -521,7 +527,7 @@ retest:
cm_id->state = IB_CM_IDLE;
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
spin_lock_irqsave(&cm.lock, flags);
- rb_erase(&cm_id_priv->service_node, &cm.service_table);
+ rb_erase(&cm_id_priv->service_node, &cm.listen_service_table);
spin_unlock_irqrestore(&cm.lock, flags);
break;
case IB_CM_SIDR_REQ_SENT:
@@ -578,23 +584,25 @@ int ib_cm_listen(struct ib_cm_id *cm_id,
u64 service_id,
u64 service_mask)
{
- struct cm_id_private *cm_id_priv;
+ struct cm_id_private *cm_id_priv, *cur_cm_id_priv;
unsigned long flags;
int ret = 0;
cm_id_priv = container_of(cm_id, struct cm_id_private, id);
BUG_ON(cm_id->state != IB_CM_IDLE);
+ cm_id->state = IB_CM_LISTEN;
cm_id->service_id = service_id;
cm_id->service_mask = service_mask ? service_mask : ~0ULL;
spin_lock_irqsave(&cm.lock, flags);
- if (!cm_find_service(service_id)) {
- cm_id->state = IB_CM_LISTEN;
- cm_insert_service(cm_id_priv);
- } else
- ret = -EBUSY;
+ cur_cm_id_priv = cm_insert_listen(cm_id_priv);
spin_unlock_irqrestore(&cm.lock, flags);
+
+ if (cur_cm_id_priv) {
+ cm_id->state = IB_CM_IDLE;
+ ret = -EBUSY;
+ }
return ret;
}
EXPORT_SYMBOL(ib_cm_listen);
@@ -736,6 +744,8 @@ int ib_send_cm_req(struct ib_cm_id *cm_i
if (ret)
goto out;
+ cm_id->service_id = param->service_id;
+ cm_id->service_mask = ~0ULL;
cm_id_priv->timeout_ms = cm_convert_to_ms(
param->primary_path->packet_life_time) * 2 +
cm_convert_to_ms(
@@ -759,9 +769,8 @@ int ib_send_cm_req(struct ib_cm_id *cm_i
* simplifies error recovery if the send fails.
*/
if (param->peer_to_peer) {
- spin_lock_irqsave(&cm.lock, flags);
- cm_insert_service(cm_id_priv);
- spin_unlock_irqrestore(&cm.lock, flags);
+ ret = -EINVAL;
+ goto out;
}
spin_lock_irqsave(&cm_id_priv->lock, flags);
@@ -770,11 +779,9 @@ int ib_send_cm_req(struct ib_cm_id *cm_i
if (ret) {
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
- if (param->peer_to_peer) {
- spin_lock_irqsave(&cm.lock, flags);
- rb_erase(&cm_id_priv->service_node, &cm.service_table);
- spin_unlock_irqrestore(&cm.lock, flags);
- }
+ /* if (param->peer_to_peer) {
+ cleanup peer_service_table
+ } */
cm_free_msg(cm_id_priv->msg);
goto out;
}
@@ -842,7 +849,7 @@ static void cm_req_handler(struct cm_rec
struct ib_cm_id *cm_id;
struct cm_id_private *cm_id_priv, *cur_cm_id_priv;
struct cm_req_msg *req_msg;
- unsigned long flags, flags2;
+ unsigned long flags;
struct ib_cm_req_event_param *param;
struct ib_wc *wc;
int ret;
@@ -865,18 +872,10 @@ static void cm_req_handler(struct cm_rec
spin_unlock_irqrestore(&cm.lock, flags);
goto out; /* Duplicate message. */
}
- /* Find matching listen/peer request. */
- cur_cm_id_priv = cm_find_service(req_msg->service_id);
- if (!cur_cm_id_priv) {
- spin_unlock_irqrestore(&cm.lock, flags);
- /* todo: reject with no match */
- goto out; /* No match. */
- }
- spin_lock_irqsave(&cur_cm_id_priv->lock, flags2);
- switch (cur_cm_id_priv->id.state) {
- case IB_CM_LISTEN:
+ /* Find matching listen request. */
+ cur_cm_id_priv = cm_find_listen(req_msg->service_id);
+ if (cur_cm_id_priv) {
atomic_inc(&cur_cm_id_priv->refcount);
- spin_unlock_irqrestore(&cur_cm_id_priv->lock, flags2);
cm_insert_remote_id(cm_id_priv);
spin_unlock_irqrestore(&cm.lock, flags);
@@ -885,9 +884,14 @@ static void cm_req_handler(struct cm_rec
cm_id_priv->id.service_id = req_msg->service_id;
cm_id_priv->id.service_mask = ~0ULL;
cm_id_priv->id.state = IB_CM_REQ_RCVD;
- break;
- case IB_CM_REQ_SENT:
- /* Process peer requests. */
+ } else {
+ /* Search for a peer request. */
+ /* todo: fix peer-to-peer */
+ if (!cur_cm_id_priv) {
+ spin_unlock_irqrestore(&cm.lock, flags);
+ /* todo: reject with no match */
+ goto out;
+ }
if (cm_is_active_peer(recv_work->port->ca_guid,
req_msg->local_ca_guid,
cur_cm_id_priv->local_qpn,
@@ -897,22 +901,17 @@ static void cm_req_handler(struct cm_rec
}
atomic_inc(&cur_cm_id_priv->refcount);
cur_cm_id_priv->id.state = IB_CM_REQ_RCVD;
- spin_unlock_irqrestore(&cur_cm_id_priv->lock, flags2);
- rb_erase(&cur_cm_id_priv->service_node, &cm.service_table);
+ /*rb_erase(&cur_cm_id_priv->service_node, &cm.service_table);*/
+ cur_cm_id_priv->peer_to_peer = 0;
cur_cm_id_priv->remote_ca_guid = req_msg->local_ca_guid;
cur_cm_id_priv->id.remote_id = req_msg->local_comm_id;
cm_insert_remote_id(cur_cm_id_priv);
spin_unlock_irqrestore(&cm.lock, flags);
ib_cancel_mad(recv_work->port->mad_agent,
- (unsigned long) cur_cm_id_priv->msg);
+ (unsigned long) cur_cm_id_priv->msg);
ib_destroy_cm_id(&cm_id_priv->id);
cm_id_priv = cur_cm_id_priv;
- break;
- default:
- spin_unlock_irqrestore(&cm.lock, flags);
- /* todo: reject with no match */
- goto out; /* No match. */
}
cm_id_priv->port = recv_work->port;
cm_id_priv->timeout_ms = cm_convert_to_ms(
@@ -1151,6 +1150,15 @@ static void cm_rep_handler(struct cm_rec
ib_cancel_mad(recv_work->port->mad_agent,
(unsigned long) cm_id_priv->msg);
+ /* todo: handle peer_to_peer
+ if (cm_id_priv->peer_to_peer) {
+ cm_id_priv->peer_to_peer = 0;
+ spin_lock_irqsave(&cm.lock, flags);
+ rb_erase(&cm_id_priv->service_node, &cm.service_table);
+ spin_unlock_irqrestore(&cm.lock, flags);
+ }
+ */
+
cm_id_priv->id.remote_id = rep_msg->local_comm_id;
cm_id_priv->remote_ca_guid = rep_msg->local_ca_guid;
cm_id_priv->remote_qpn = cm_rep_get_local_qpn(rep_msg);
@@ -1917,6 +1925,8 @@ int ib_send_cm_sidr_req(struct ib_cm_id
if (ret)
goto out;
+ cm_id->service_id = param->service_id;
+ cm_id->service_mask = ~0ULL;
cm_id_priv->timeout_ms = param->timeout_ms;
cm_id_priv->max_cm_retries = param->max_cm_retries;
cm_set_ah_attr(&cm_id_priv->ah_attr, cm_id_priv->port->port_num,
@@ -1980,8 +1990,8 @@ static void cm_sidr_req_handler(struct c
spin_unlock_irqrestore(&cm.lock, flags);
goto out; /* Duplicate message. */
}
- cur_cm_id_priv = cm_find_service(sidr_req_msg->service_id);
- if (!cur_cm_id_priv || cur_cm_id_priv->id.state != IB_CM_LISTEN) {
+ cur_cm_id_priv = cm_find_listen(sidr_req_msg->service_id);
+ if (!cur_cm_id_priv) {
rb_erase(&cm_id_priv->remote_id_node, &cm.remote_sidr_table);
spin_unlock_irqrestore(&cm.lock, flags);
/* todo: reject with no match */
@@ -2405,7 +2415,7 @@ static int __init ib_cm_init(void)
memset(&cm, 0, sizeof cm);
spin_lock_init(&cm.lock);
- cm.service_table = RB_ROOT;
+ cm.listen_service_table = RB_ROOT;
cm.remote_id_table = RB_ROOT;
cm.remote_qp_table = RB_ROOT;
cm.remote_sidr_table = RB_ROOT;
More information about the general
mailing list