>From 3885d8fc7edab1a74f8530b1fec6cde5601eaeef Mon Sep 17 00:00:00 2001
From: Slava Strebkov <[email protected]>
Date: Mon, 27 Jul 2009 11:09:44 +0300
Patch defines new infrastructure and functions for 
implementation of storage mgroups into mlid holder.
Signed-off-by: Slava Strebkov <[email protected]>

---
 opensm/include/opensm/osm_multicast.h |  270 ++++++++++++++++++++++++++++++++-
 opensm/opensm/osm_multicast.c         |  175 +++++++++++++++++++++-
 2 files changed, 443 insertions(+), 2 deletions(-)

diff --git a/opensm/include/opensm/osm_multicast.h 
b/opensm/include/opensm/osm_multicast.h
index 9a47de5..69ea06b 100644
--- a/opensm/include/opensm/osm_multicast.h
+++ b/opensm/include/opensm/osm_multicast.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  *
@@ -107,6 +107,72 @@ typedef struct osm_mcast_mgr_ctxt {
 *
 * SEE ALSO
 *********/
+/****s* OpenSM: Multicast Group Holder/osm_mgrp_holder_t
+* NAME
+*      osm_mgrp_holder_t
+*
+* DESCRIPTION
+*      Holder for mgroups.
+*
+*      The osm_mgrp_t object should be treated as opaque and should
+*      be manipulated only through the provided functions.
+*
+* SYNOPSIS
+*/
+
+typedef struct osm_mgrp_holder {
+       cl_qmap_t mgrp_port_map;
+       cl_qlist_t mgrp_list;
+       osm_mtree_node_t *p_root;
+       ib_net16_t mlid;
+} osm_mgrp_holder_t;
+
+/*
+* FIELDS
+*      mgrp_list
+*              Map for mgroups.  Must be first element!!
+*
+*      mgrp_port_map
+*              Map of  all ports joined same mlid
+*
+*      mgrp_list
+*              List of mgroups having same mlid
+*
+*      p_root
+*              Pointer to the root "tree node" in the single spanning tree
+*              for this multicast group holder.The nodes of the tree represent
+*              switches.  Member ports are not represented in the tree.
+*
+*      mlid
+*              mlid of current group holder
+*/
+ /****s* OpenSM: Multicast group Port /osm_mgrp_port _t
+* NAME
+*      osm_mgrp_port _t
+*
+* DESCRIPTION
+*      Holder for pointers to mgroups and port guid.
+*
+*
+* SYNOPSIS
+*/
+typedef struct _osm_mgrp_port {
+        cl_map_item_t guid_item;
+        cl_qlist_t mgroups;
+        ib_net64_t port_guid;
+} osm_mgrp_port_t;
+/*
+* FIELDS
+*      guid_item
+*              Map for ports. Must be first element
+*
+*      mgroups
+*              List  of  mgroups opened by this port.
+*
+*      portguid
+*              guid of  port representing current structure
+*/
+
 
 /****s* OpenSM: Multicast Group/osm_mgrp_t
 * NAME
@@ -122,6 +188,8 @@ typedef struct osm_mcast_mgr_ctxt {
 */
 typedef struct osm_mgrp {
        cl_fmap_item_t map_item;
+       cl_list_item_t mlid_item;
+       cl_list_item_t port_item;
        ib_net16_t mlid;
        osm_mtree_node_t *p_root;
        cl_qmap_t mcm_port_tbl;
@@ -137,6 +205,12 @@ typedef struct osm_mgrp {
 *      map_item
 *              Map Item for fmap linkage.  Must be first element!!
 *
+*      mlid_item
+*              List item for groups with same MLID
+*
+*      port_item
+*              List item for groups opened on same port
+*
 *      mlid
 *              The network ordered LID of this Multicast Group (must be
 *              >= 0xC000).
@@ -489,6 +563,200 @@ osm_mgrp_apply_func(const osm_mgrp_t * const p_mgrp,
 * SEE ALSO
 *      Multicast Group
 *********/
+/****f* OpenSM: Multicast Group Holder /osm_mgrp_holder_new
+* NAME
+*       osm_mgrp_holder_new
+*
+* DESCRIPTION
+*       Allocates and initializes a Multicast Group Holder for use.
+*
+* SYNOPSIS
+*/
+osm_mgrp_holder_t *osm_mgrp_holder_new(IN osm_subn_t * p_subn,
+                                       IN ib_net16_t mlid);
+/*
+* PARAMETERS
+*      p_subn
+*              (in) pointer to osm_subnet
+*      mlid
+*              [in] Multicast LID for this multicast group holder.
+*
+* RETURN VALUES
+*       pointer to initialized osm_mgrp_holder_t
+*       or NULL, if unsuccessful
+*
+* SEE ALSO
+*       Multicast Group Holder, osm_mgrp_holder_delete
+*********/
+/****f* OpenSM: Multicast Group Holder /osm_mgrp_holder_delete
+* NAME
+*       osm_mgrp_holder_delete
+*
+* DESCRIPTION
+*       Removes  entry from  array of holders
+*       Removes port from mgroup port list
+*
+* SYNOPSIS
+*/
+void osm_mgrp_holder_delete(IN osm_subn_t * p_subn, IN ib_net16_t mlid);
+
+/*
+* PARAMETERS
+*
+*      p_subn
+*              [in] Pointer to  osm_subnet
+*
+*      mlid
+*              [in] holder's mlid
+*
+* RETURN VALUES
+*      None.
+*
+* NOTES
+*
+* SEE ALSO
+*
+*********/
+/****f* OpenSM: Multicast Group Holder /osm_mgrp_holder_add_mgrp_port
+* NAME
+*       osm_mgrp_holder_port_add_mgrp
+*
+* DESCRIPTION
+*       Allocates  osm_mgrp_port_t for new port joined to mgroup with mlid of 
this holder,
+*       (or / and) adds mgroup to mgroup map of  existed osm_mgrp_port_t 
object.
+*
+* SYNOPSIS
+*/
+ib_api_status_t osm_mgrp_holder_port_add_mgrp(IN osm_mgrp_holder_t *
+                                              p_mgrp_holder,
+                                              IN osm_mgrp_t * p_mgrp,
+                                              IN ib_net64_t port_guid);
+
+/*
+* PARAMETERS
+*      p_mgrp_holder
+*              (in) pointer to osm_mgrp_holder_t
+*      p_mgrp
+*              (in)  pointer to  osm_mgrp_t
+*
+* RETURN VALUES
+*      IB_SUCCESS or
+*      IB_INSUFFICIENT_MEMORY
+*
+* SEE ALSO
+*       Multicast Group Holder, osm_mgrp_holder_delete_mgrp_port
+*********/
+/****f* OpenSM: Multicast Group Holder /osm_mgrp_holder_delete_mgrp_port
+* NAME
+*       osm_mgrp_holder_port_delete_mgrp
+*
+* DESCRIPTION
+*       Deletes  osm_mgrp_port_t for specified port
+*
+* SYNOPSIS
+*/
+void osm_mgrp_holder_port_delete_mgrp(IN osm_mgrp_holder_t * p_mgrp_holder,
+                                      IN osm_mgrp_t * p_mgrp,
+                                      IN ib_net64_t port_guid);
+
+/*
+* PARAMETERS
+*      p_mgrp_holder
+*              [in] Pointer to an osm_mgrp_holder_t object.
+*
+*      p_mgrp
+*              (in) Pointer to osm_mgrp_t object
+*
+*      port_guid
+*              [in] Port guid of the departing port.
+*
+* RETURN VALUES
+*      None.
+*
+* NOTES
+*
+* SEE ALSO
+        Multicast Group Holder,osm_holder_add_mgrp_port
+*********/
+/****f* OpenSM: Multicast Group Holder /osm_mgrp_holder_remove_port
+* NAME
+*       osm_mgrp_holder_remove_port
+*
+* DESCRIPTION
+*       Removes  osm_mgrp_port_t from mgrp_port_map of holder
+*       Removes port from mgroup port list
+*
+* SYNOPSIS
+*/
+void osm_mgrp_holder_remove_port(IN osm_subn_t * const p_subn,
+                                 IN osm_log_t * const p_log,
+                                 IN osm_mgrp_holder_t * const p_mgrp_holder,
+                                 IN const ib_net64_t port_guid);
+
+/*
+* PARAMETERS
+*
+*      p_subn
+*              [in] Pointer to the subnet object
+*
+*      p_log
+*              [in] The log object pointer
+*
+*      p_mgrp_holder
+*              [in] Pointer to an osm_mgrp_holder_t object.
+*
+*      port_guid
+*              [in] Port guid of the departing port.
+*
+* RETURN VALUES
+*      None.
+*
+* NOTES
+*
+* SEE ALSO
+*
+*********/
+/****f* OpenSM: Subnet/osm_get_mgrp_by_mlid
+* NAME
+*       osm_get_mgrp_by_mlid
+*
+* DESCRIPTION
+*       The looks for the given multicast group in the subnet table by mlid.
+*       NOTE: this code is not thread safe. Need to grab the lock before
+*       calling it.
+*
+* SYNOPSIS
+*/
+static inline struct osm_mgrp_holder *osm_get_mgrp_holder_by_mlid(osm_subn_t 
const
+                                                                  *p_subn,
+                                                                  ib_net16_t
+                                                                  mlid)
+{
+       return p_subn->mgroup_holders[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO];
+}
+
+/*
+* PARAMETERS
+*      p_subn
+*              [in] Pointer to an osm_subn_t object
+*
+*      mlid
+*              [in] The multicast group mlid in network order
+*
+* RETURN VALUES
+*       The multicast group structure pointer if found. NULL otherwise.
+*********/
+static inline ib_net16_t osm_mgrp_holder_get_mlid(IN osm_mgrp_holder_t *
+                                                  const p_mgrp_holder)
+{
+       return (p_mgrp_holder->mlid);
+}
+
+static inline boolean_t osm_mgrp_holder_is_empty(IN const osm_mgrp_holder_t *
+                                                 const p_mgrp_holder)
+{
+       return (cl_qmap_count(&p_mgrp_holder->mgrp_port_map) == 0);
+}
 
 END_C_DECLS
 #endif                         /* _OSM_MULTICAST_H_ */
diff --git a/opensm/opensm/osm_multicast.c b/opensm/opensm/osm_multicast.c
index d2733c4..2106a63 100644
--- a/opensm/opensm/osm_multicast.c
+++ b/opensm/opensm/osm_multicast.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  *
@@ -298,3 +298,176 @@ void osm_mgrp_apply_func(const osm_mgrp_t * p_mgrp, 
osm_mgrp_func_t p_func,
        if (p_mtn)
                mgrp_apply_func_sub(p_mgrp, p_mtn, p_func, context);
 }
+
+/**********************************************************************
+ **********************************************************************/
+static osm_mgrp_port_t *osm_mgrp_port_new(ib_net64_t port_guid)
+{
+       osm_mgrp_port_t *p_mgrp_port =
+       (osm_mgrp_port_t *) malloc(sizeof(osm_mgrp_port_t));
+       if (!p_mgrp_port) {
+               return NULL;
+       }
+       memset(p_mgrp_port, 0, sizeof(*p_mgrp_port));
+       p_mgrp_port->port_guid = port_guid;
+       cl_qlist_init(&p_mgrp_port->mgroups);
+       return p_mgrp_port;
+}
+
+/**********************************************************************
+ **********************************************************************/
+osm_mgrp_holder_t *osm_mgrp_holder_new(IN osm_subn_t * p_subn,
+                                       ib_net16_t mlid)
+{
+       osm_mgrp_holder_t *p_mgrp_holder;
+       p_mgrp_holder =
+               p_subn->mgroup_holders[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO] 
=
+               (osm_mgrp_holder_t *) malloc(sizeof(*p_mgrp_holder));
+       if (!p_mgrp_holder)
+               return NULL;
+
+       memset(p_mgrp_holder, 0, sizeof(*p_mgrp_holder));
+       p_mgrp_holder->mlid = mlid;
+       cl_qmap_init(&p_mgrp_holder->mgrp_port_map);
+       cl_qlist_init(&p_mgrp_holder->mgrp_list);
+       return p_mgrp_holder;
+}
+
+/**********************************************************************
+ **********************************************************************/
+void osm_mgrp_holder_delete(IN osm_subn_t *p_subn, osm_mgrp_t *p_mgrp)
+{
+       osm_mgrp_port_t *p_osm_mgr_port;
+       cl_map_item_t *p_item;
+
+       osm_mgrp_holder_t *p_mgrp_holder =
+               p_subn->mgroup_holders[cl_ntoh16(p_mgrp->mlid) - 
IB_LID_MCAST_START_HO];
+       p_item = cl_qmap_head(&p_mgrp_holder->mgrp_port_map);
+       /* Delete ports shared same MLID */
+       while (p_item != cl_qmap_end(&p_mgrp_holder->mgrp_port_map)) {
+               p_osm_mgr_port = (osm_mgrp_port_t *) p_item;
+               cl_qlist_remove_all(&p_osm_mgr_port->mgroups);
+               cl_qmap_remove_item(&p_mgrp_holder->mgrp_port_map, p_item);
+               p_item = cl_qmap_head(&p_mgrp_holder->mgrp_port_map);
+               free(p_osm_mgr_port);
+       }
+       /* Remove mgrp from this MLID */
+       cl_qlist_remove_item(&p_mgrp_holder->mgrp_list,&p_mgrp->mlid_item);
+       /* Destroy the mtree_node structure */
+       osm_mtree_destroy(p_mgrp_holder->p_root);
+       p_subn->mgroup_holders[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO] = NULL;
+       free(p_mgrp_holder);
+}
+
+/**********************************************************************
+ **********************************************************************/
+void osm_mgrp_holder_remove_port(osm_subn_t * subn, osm_log_t * p_log,
+                               osm_mgrp_holder_t * p_mgrp_holder,
+                               ib_net64_t port_guid)
+{
+       osm_mgrp_t *p_mgrp;
+       cl_list_item_t *p_item;
+
+       OSM_LOG_ENTER(p_log);
+
+       osm_mgrp_port_t *p_mgrp_port = (osm_mgrp_port_t *)
+               cl_qmap_remove(&p_mgrp_holder->mgrp_port_map, port_guid);
+       if (p_mgrp_port !=
+               (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_holder->mgrp_port_map)) 
{
+               char gid_str[INET6_ADDRSTRLEN];
+               OSM_LOG(p_log, OSM_LOG_DEBUG,
+               "port  0x%" PRIx64 " removed from  mlid 0x%X\n",
+               port_guid, cl_ntoh16(p_mgrp_holder->mlid));
+               while ((p_item =
+                       cl_qlist_remove_head(&p_mgrp_port->mgroups)) !=
+                       cl_qlist_end(&p_mgrp_port->mgroups)) {
+                       p_mgrp = (osm_mgrp_t *)
+                               PARENT_STRUCT(p_item, osm_mgrp_t,port_item);
+                       OSM_LOG(p_log, OSM_LOG_DEBUG,
+                               "removing mgrp mgid %s from port  0x%" 
PRIx64"\n",
+                                
inet_ntop(AF_INET6,p_mgrp->mcmember_rec.mgid.raw,
+                                       gid_str, sizeof(gid_str)),
+                                       cl_ntoh64(port_guid));
+                       osm_mgrp_delete_port(subn, p_log, p_mgrp, port_guid);
+               }
+               free(p_mgrp_port);
+       }
+       OSM_LOG_EXIT(p_log);
+}
+
+/**********************************************************************
+ **********************************************************************/
+void osm_mgrp_holder_add_mgrp(osm_mgrp_holder_t * p_mgrp_holder,
+                             osm_mgrp_t * p_mgrp)
+{
+       char gid_str[INET6_ADDRSTRLEN];
+
+       OSM_LOG_ENTER(p_log);
+       cl_qlist_insert_tail(&p_mgrp_holder->mgrp_list, &p_mgrp->mlid_item);
+       OSM_LOG(p_log, OSM_LOG_DEBUG,
+               "mgrp with MGID:%s added to holder with mlid = 0x%X\n",
+               inet_ntop(AF_INET6, p_mgrp->mcmember_rec.mgid.raw, gid_str,
+               sizeof(gid_str)), cl_ntoh16(p_mgrp_holder->mlid));
+       p_mgrp_holder->last_change_id++;
+       OSM_LOG_EXIT(p_log);
+}
+
+/**********************************************************************
+ **********************************************************************/
+void osm_mgrp_holder_delete_mgrp(osm_mgrp_holder_t * p_mgrp_holder,
+                                osm_mgrp_t * p_mgrp)
+{
+       p_mgrp->to_be_deleted = 1;
+       if (0 == cl_qlist_count(&p_mgrp_holder->mgrp_list)) {
+               /* No more mgroups on this mlid */
+               p_mgrp_holder->to_be_deleted = 1;
+               p_mgrp_holder->last_tree_id = 0;
+               p_mgrp_holder->last_change_id = 0;
+       }
+}
+
+/**********************************************************************
+ **********************************************************************/
+ib_api_status_t osm_mgrp_holder_port_add_mgrp(osm_mgrp_holder_t * 
p_mgrp_holder,
+                                             osm_mgrp_t * p_mgrp,
+                                             ib_net64_t port_guid)
+{
+       osm_mgrp_port_t *p_mgrp_port = (osm_mgrp_port_t *)
+               cl_qmap_get(&p_mgrp_holder->mgrp_port_map, port_guid);
+       if (p_mgrp_port ==
+               (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_holder->mgrp_port_map)) 
{
+               /* new port to mlid */
+               p_mgrp_port = osm_mgrp_port_new(port_guid);
+               if (!p_mgrp_port) {
+                       return IB_INSUFFICIENT_MEMORY;
+               }
+               cl_qmap_insert(&p_mgrp_holder->mgrp_port_map,
+                       p_mgrp_port->port_guid, &p_mgrp_port->guid_item);
+               cl_qlist_insert_tail(&p_mgrp_port->mgroups, &p_mgrp->port_item);
+       } else {
+               cl_qlist_insert_tail(&p_mgrp_port->mgroups, &p_mgrp->port_item);
+       }
+        return IB_SUCCESS;
+}
+
+/**********************************************************************
+ **********************************************************************/
+void osm_mgrp_holder_port_delete_mgrp(osm_mgrp_holder_t * p_mgrp_holder,
+                                     osm_mgrp_t * p_mgrp,
+                                     ib_net64_t port_guid)
+{
+       osm_mgrp_port_t *p_mgrp_port = (osm_mgrp_port_t *)
+       cl_qmap_get(&p_mgrp_holder->mgrp_port_map, port_guid);
+       if (p_mgrp_port !=
+               (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_holder->mgrp_port_map)) 
{
+               cl_qlist_remove_item(&p_mgrp_port->mgroups, &p_mgrp->port_item);
+               if (0 == cl_qlist_count(&p_mgrp_port->mgroups)) {
+                       /* No mgroups registered on this port for current mlid 
*/
+                       cl_qmap_remove_item(&p_mgrp_holder->mgrp_port_map,
+                       &p_mgrp_port->guid_item);
+                       free(p_mgrp_port);
+               }
+       p_mgrp_holder->last_change_id++;
+       }
+}
+
-- 
1.5.5

_______________________________________________
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