This patch adds checks for a stale connection to the passive side of
the connection protocol.  Checks on the active side are still needed.

Signed-off-by: Sean Hefty <[EMAIL PROTECTED]>

Index: infiniband/core/cm.c
===================================================================
--- infiniband/core/cm.c        (revision 1817)
+++ infiniband/core/cm.c        (working copy)
@@ -108,10 +108,11 @@ struct cm_work {
 
 struct cm_timewait_info {
        struct cm_work work;                    /* Must be first. */
-       /* struct rb_node remote_qp_node; */
+       struct rb_node remote_qp_node;
        struct rb_node remote_id_node;
        u64 remote_ca_guid;
        u32 remote_qpn;
+       u8 inserted_remote_qp;
        u8 inserted_remote_id;
 };
 
@@ -424,80 +425,35 @@ static struct cm_id_private * cm_find_id
 }
 */
 
-static void cm_remove_remote_id(struct cm_timewait_info *timewait_info)
-{
-       unsigned long flags;
-
-       timewait_info->inserted_remote_id = 0;
-       spin_lock_irqsave(&cm.lock, flags);
-       rb_erase(&timewait_info->remote_id_node, &cm.remote_id_table);
-       spin_unlock_irqrestore(&cm.lock, flags);
-}
-
-/*
-todo: add test for stale connections
-static struct cm_id_private * cm_insert_remote_qpn(struct cm_id_private
-                                                  *cm_id_priv)
+static struct cm_timewait_info * cm_insert_remote_qpn(struct cm_timewait_info
+                                                     *timewait_info)
 {
        struct rb_node **link = &cm.remote_qp_table.rb_node;
        struct rb_node *parent = NULL;
-       struct cm_id_private *cur_cm_id_priv;
-       union ib_gid *port_gid = &cm_id_priv->dgid;
-       u32 remote_qpn = cm_id_priv->remote_qpn;
+       struct cm_timewait_info *cur_timewait_info;
+       u64 remote_ca_guid = timewait_info->remote_ca_guid;
+       u32 remote_qpn = timewait_info->remote_qpn;
 
        while (*link) {
                parent = *link;
-               cur_cm_id_priv = rb_entry(parent, struct cm_id_private,
-                                         remote_qp_node);
-               if (remote_qpn < cur_cm_id_priv->remote_qpn)
+               cur_timewait_info = rb_entry(parent, struct cm_timewait_info,
+                                            remote_qp_node);
+               if (remote_qpn < cur_timewait_info->remote_qpn)
                        link = &(*link)->rb_left;
-               else if (remote_qpn > cur_cm_id_priv->remote_qpn)
+               else if (remote_qpn > cur_timewait_info->remote_qpn)
                        link = &(*link)->rb_right;
-               else {
-                       int cmp;
-                       cmp = memcmp(port_gid, &cur_cm_id_priv->dgid,
-                                    sizeof *port_gid);
-                       if (cmp < 0)
-                               link = &(*link)->rb_left;
-                       else if (cmp > 0)
-                               link = &(*link)->rb_right;
-                       else
-                               return cur_cm_id_priv;
-               }
-       }
-       rb_link_node(&cm_id_priv->remote_qp_node, parent, link);
-       rb_insert_color(&cm_id_priv->remote_qp_node, &cm.remote_qp_table);
-       return NULL;
-}
-
-static struct cm_id_private * cm_find_id_by_remote_qpn(union ib_gid *port_gid,
-                                                      u32 remote_qpn)
-{
-       struct rb_node *node = cm.remote_qp_table.rb_node;
-       struct cm_id_private *cm_id_priv;
-
-       while (node) {
-               cm_id_priv = rb_entry(node, struct cm_id_private, 
remote_qp_node);
-
-               if (remote_qpn < cm_id_priv->remote_qpn)
-                       node = node->rb_left;
-               else if (remote_qpn > cm_id_priv->remote_qpn)
-                       node = node->rb_right;
-               else {
-                       int cmp;
-                       cmp = memcmp(port_gid, &cm_id_priv->dgid,
-                                    sizeof *port_gid);
-                       if (cmp < 0)
-                               node = node->rb_left;
-                       else if (cmp > 0)
-                               node = node->rb_right;
-                       else
-                               return cm_id_priv;
-               }
+               else if (remote_ca_guid < cur_timewait_info->remote_ca_guid)
+                       link = &(*link)->rb_left;
+               else if (remote_ca_guid > cur_timewait_info->remote_ca_guid)
+                       link = &(*link)->rb_right;
+               else
+                       return cur_timewait_info;
        }
+       timewait_info->inserted_remote_qp = 1;
+       rb_link_node(&timewait_info->remote_qp_node, parent, link);
+       rb_insert_color(&timewait_info->remote_qp_node, &cm.remote_qp_table);
        return NULL;
 }
-*/
 
 static struct cm_id_private * cm_insert_remote_sidr(struct cm_id_private
                                                    *cm_id_priv)
@@ -601,13 +557,23 @@ static inline int cm_convert_to_ms(int i
 
 static void cm_cleanup_timewait(struct cm_timewait_info *timewait_info)
 {
-       if (timewait_info->inserted_remote_id)
-               cm_remove_remote_id(timewait_info);
+       unsigned long flags;
 
-       /* todo: stale connection handling
-       if (timewait_info->inserted_remote_qpn)
-               cm_remove_remote_qpn(timewait_info);
-       */
+       if (!timewait_info->inserted_remote_id &&
+           !timewait_info->inserted_remote_qp)
+           return;
+
+       spin_lock_irqsave(&cm.lock, flags);
+       if (timewait_info->inserted_remote_id) {
+               rb_erase(&timewait_info->remote_id_node, &cm.remote_id_table);
+               timewait_info->inserted_remote_id = 0;
+       }
+
+       if (timewait_info->inserted_remote_qp) {
+               rb_erase(&timewait_info->remote_qp_node, &cm.remote_qp_table);
+               timewait_info->inserted_remote_qp = 0;
+       }
+       spin_unlock_irqrestore(&cm.lock, flags);
 }
 
 static struct cm_timewait_info * cm_create_timewait_info(u32 local_id,
@@ -1088,14 +1054,13 @@ static int cm_req_handler(struct cm_work
                ret = -EINVAL;
                goto error2;
        }
-       /* todo: Check for a stale connection.
+       /* Check for a stale connection. */
        if (cm_insert_remote_qpn(cm_id_priv->timewait_info)) {
                spin_unlock_irqrestore(&cm.lock, flags);
-               todo: reject as stale
+               /* todo: reject as stale */
                ret = -EINVAL;
                goto error2;
        }
-       */
        /* Find matching listen request. */
        listen_cm_id_priv = cm_find_listen(req_msg->service_id);
        if (!listen_cm_id_priv) {
_______________________________________________
openib-general mailing list
openib-general@openib.org
http://openib.org/mailman/listinfo/openib-general

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

Reply via email to