[ofa-general] [PATCH 1/2 v3] opensm: Storage organization for multicast groups
Slava Strebkov
slavas at Voltaire.COM
Wed Aug 5 06:47:02 PDT 2009
Subject: [PATCH 1/2] Storage organization for multicast groups
Main purpose is to prepare infrastructure for (many) mgids
to one mlid compression. Proposed the following changes:
1. Element in mlid array is now a multicast group holder.
2. mgrp_holder keeps a list of mgroups sharing same mlid.
With introduction of compression, there will be many
multicast groups per mlid. Current implementation keeps
one mgid to one mlid ratio.
3. mgrp_holder has a map of ports sharing same mlid. Ports sorted
by port guid. Port map is necessary for building spanning
tree per mgroup_holder, not just for single mgroup.
4. Element in port map keeps a list of mgroups opened by this port.
This allows quick deletion of mgroups when port changes
state to DOWN.
5. Multicast processing functions use mgroup_holder object instead
of mgroup.
Signed-off-by: Slava Strebkov <slavas at voltaire.com>
---
opensm/include/opensm/osm_multicast.h | 343 +++++++++++++++++++++++++++++---
opensm/include/opensm/osm_sm.h | 10 +-
opensm/include/opensm/osm_subnet.h | 38 ++--
opensm/opensm/osm_drop_mgr.c | 14 +-
opensm/opensm/osm_mcast_mgr.c | 228 +++++++++++++---------
opensm/opensm/osm_multicast.c | 198 +++++++++++++++++--
opensm/opensm/osm_qos_policy.c | 38 ++--
opensm/opensm/osm_sa.c | 31 +--
opensm/opensm/osm_sa_mcmember_record.c | 94 +++++----
opensm/opensm/osm_sa_path_record.c | 13 +-
opensm/opensm/osm_sm.c | 81 +++++++-
opensm/opensm/osm_subnet.c | 31 +++-
12 files changed, 855 insertions(+), 264 deletions(-)
diff --git a/opensm/include/opensm/osm_multicast.h b/opensm/include/opensm/osm_multicast.h
index 9a47de5..61d1ba6 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,82 @@ 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;
+ boolean_t to_be_deleted;
+ uint32_t last_tree_id;
+ uint32_t last_change_id;
+} osm_mgrp_holder_t;
+
+/*
+* FIELDS
+* 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
+*
+* to_be_deleted
+* Since holders are deleted when there are no mgroups in.
+*
+* last_change_id
+* a counter for the number of changes applied to the group in this holder.
+* This counter shuold be incremented on any modification
+* to the group: joining or leaving of ports.
+*
+* last_tree_id
+* the last change id used for building the current tree.
+*/
+ /****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,14 +198,13 @@ 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;
ib_member_rec_t mcmember_rec;
boolean_t well_known;
boolean_t to_be_deleted;
- uint32_t last_change_id;
- uint32_t last_tree_id;
unsigned full_members;
} osm_mgrp_t;
/*
@@ -141,10 +216,11 @@ typedef struct osm_mgrp {
* The network ordered LID of this Multicast Group (must be
* >= 0xC000).
*
-* p_root
-* Pointer to the root "tree node" in the single spanning tree
-* for this multicast group. The nodes of the tree represent
-* switches. Member ports are not represented in the tree.
+* mlid_item
+* List item for groups with same MLID
+*
+* port_item
+* List item for groups opened on same port
*
* mcm_port_tbl
* Table (sorted by port GUID) of osm_mcm_port_t objects
@@ -163,14 +239,6 @@ typedef struct osm_mgrp {
* track the fact the group is about to be deleted so we can
* track the fact a new join is actually a create request.
*
-* last_change_id
-* a counter for the number of changes applied to the group.
-* This counter shuold be incremented on any modification
-* to the group: joining or leaving of ports.
-*
-* last_tree_id
-* the last change id used for building the current tree.
-*
* SEE ALSO
*********/
@@ -456,30 +524,111 @@ osm_mgrp_delete_port(IN osm_subn_t * const p_subn,
int osm_mgrp_remove_port(osm_subn_t *subn, osm_log_t *log, osm_mgrp_t *mgrp,
osm_mcm_port_t *mcm, uint8_t join_state);
-/****f* OpenSM: Multicast Group/osm_mgrp_apply_func
+/****f* OpenSM: Multicast Group Holder /osm_mgrp_holder_new
* NAME
-* osm_mgrp_apply_func
+* osm_mgrp_holder_new
*
* DESCRIPTION
-* Calls the specified function for each element in the tree.
-* Elements are passed to the callback function in no particular order.
+* Allocates and initializes a Multicast Group Holder for use.
*
* SYNOPSIS
*/
-void
-osm_mgrp_apply_func(const osm_mgrp_t * const p_mgrp,
- osm_mgrp_func_t p_func, void *context);
+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,
+* 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 an osm_mgrp_t object.
+* (in) pointer to osm_mgrp_t
*
-* p_func
-* [in] Pointer to the users callback function.
+* RETURN VALUES
+* IB_SUCCESS or
+* IB_INSUFFICIENT_MEMORY
*
-* context
-* [in] User context passed to the callback function.
+* 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.
@@ -487,8 +636,144 @@ osm_mgrp_apply_func(const osm_mgrp_t * const p_mgrp,
* NOTES
*
* SEE ALSO
-* Multicast Group
+Multicast Group Holder,osm_holder_add_mgrp_port
+*********/
+/****f* OpenSM: Multicast Group Holder /osm_mgrp_holder_add_mgrp
+* NAME
+* osm_mgrp_holder_add_mgrp
+*
+* DESCRIPTION
+* Adds mgroup to holder according to its mgid
+*
+*
+* SYNOPSIS
+*/
+void osm_mgrp_holder_add_mgrp(IN osm_mgrp_holder_t * p_mgrp_holder,
+ IN osm_mgrp_t * p_mgrp,
+ IN osm_log_t * const p_log);
+/*
+* PARAMETERS
+*
+* p_mgrp_holder
+* [in] Pointer to an osm_mgrp_holder_t object.
+*
+* p_mgrp
+* [in] mgroup to add.
+*
+* RETURN VALUES
+* None.
+*
+* NOTES
+* Updates common_mgid when holder is being reused
+* SEE ALSO
+* Multicast Group Holder,osm_mgrp_holder_delete_mgrp
+*********/
+/****f* OpenSM: Multicast Group Holder /osm_mgrp_holder_delete_mgrp
+* NAME
+* osm_mgrp_holder_delete_mgrp
+*
+* DESCRIPTION
+* Deletes mgroup from holder according to its mgid
+*
+*
+* SYNOPSIS
+*/
+void osm_mgrp_holder_delete_mgrp(IN osm_mgrp_holder_t * p_mgrp_holder,
+ IN osm_mgrp_t * p_mgrp);
+/*
+* PARAMETERS
+*
+* p_mgrp_holder
+* [in] Pointer to an osm_mgrp_holder_t object.
+*
+* p_mgrp
+* [in] mgroup to delete.
+*
+* RETURN VALUES
+* None.
+*
+* NOTES
+*
+* SEE ALSO
+* Multicast Group Holder,osm_mgrp_holder_add_mgrp
*********/
+/****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/include/opensm/osm_sm.h b/opensm/include/opensm/osm_sm.h
index cc8321d..7f898ad 100644
--- a/opensm/include/opensm/osm_sm.h
+++ b/opensm/include/opensm/osm_sm.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.
*
@@ -61,6 +61,7 @@
#include <opensm/osm_port.h>
#include <opensm/osm_db.h>
#include <opensm/osm_remote_sm.h>
+#include <opensm/osm_multicast.h>
#ifdef __cplusplus
# define BEGIN_C_DECLS extern "C" {
@@ -539,7 +540,8 @@ osm_resp_send(IN osm_sm_t * sm,
ib_api_status_t
osm_sm_mcgrp_join(IN osm_sm_t * const p_sm,
IN const ib_net16_t mlid,
- IN const ib_net64_t port_guid);
+ IN const ib_net64_t port_guid,
+ IN const ib_gid_t * p_mgid);
/*
* PARAMETERS
* p_sm
@@ -551,6 +553,8 @@ osm_sm_mcgrp_join(IN osm_sm_t * const p_sm,
* port_guid
* [in] Port GUID to add to the group.
*
+* p_mgid
+* [in] MGID to add to the group holder.
* RETURN VALUES
* None
*
@@ -572,7 +576,7 @@ osm_sm_mcgrp_join(IN osm_sm_t * const p_sm,
*/
ib_api_status_t
osm_sm_mcgrp_leave(IN osm_sm_t * const p_sm,
- IN const ib_net16_t mlid, IN const ib_net64_t port_guid);
+ IN osm_mgrp_t * p_mgrp, IN ib_net64_t port_guid);
/*
* PARAMETERS
* p_sm
diff --git a/opensm/include/opensm/osm_subnet.h b/opensm/include/opensm/osm_subnet.h
index 6c20de8..fad8780 100644
--- a/opensm/include/opensm/osm_subnet.h
+++ b/opensm/include/opensm/osm_subnet.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-2008 Mellanox Technologies LTD. All rights reserved.
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
@@ -513,7 +513,7 @@ typedef struct osm_subn {
boolean_t coming_out_of_standby;
unsigned need_update;
cl_fmap_t mgrp_mgid_tbl;
- void *mgroups[IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO + 1];
+ void *mgroup_holders[IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO + 1];
} osm_subn_t;
/*
* FIELDS
@@ -634,8 +634,8 @@ typedef struct osm_subn {
* This flag should be on during first non-master heavy
* (including pre-master discovery stage)
*
-* mgroups
-* Array of pointers to all Multicast Group objects in the subnet.
+* mgroup_holders
+* Array of pointers to all Multicast Group Holder objects in the subnet.
* Indexed by MLID offset from base MLID.
*
* SEE ALSO
@@ -935,32 +935,34 @@ struct osm_port *osm_get_port_by_guid(IN osm_subn_t const *p_subn,
* osm_port_t
*********/
-/****f* OpenSM: Subnet/osm_get_mgrp_by_mlid
+/****f* OpenSM: Multicast Group Holder /osm_mgrp_holder_get_mlid_by_mgid
* NAME
-* osm_get_mgrp_by_mlid
+* osm_mgrp_holder_get_mlid_by_mgid
*
* 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.
+* Searches mgroup with given mgid
+* Returns mlid of the found mgroup
*
* SYNOPSIS
*/
-static inline
-struct osm_mgrp *osm_get_mgrp_by_mlid(osm_subn_t const *p_subn, ib_net16_t mlid)
-{
- return p_subn->mgroups[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO];
-}
+ib_net16_t osm_mgrp_holder_get_mlid_by_mgid(IN osm_subn_t const *p_subn,
+ IN const ib_gid_t * const p_mgid);
/*
* PARAMETERS
+*
* p_subn
-* [in] Pointer to an osm_subn_t object
+* [in] Pointer to osm_subn_t object
*
-* mlid
-* [in] The multicast group mlid in network order
+* p_mgid
+* [in] pointer to mgid
*
* RETURN VALUES
-* The multicast group structure pointer if found. NULL otherwise.
+* mlid of found holder, or zero.
+*
+* NOTES
+*
+* SEE ALSO
+*
*********/
/****f* OpenSM: Helper/osm_get_physp_by_mad_addr
diff --git a/opensm/opensm/osm_drop_mgr.c b/opensm/opensm/osm_drop_mgr.c
index c9a4f33..e1f2bd3 100644
--- a/opensm/opensm/osm_drop_mgr.c
+++ b/opensm/opensm/osm_drop_mgr.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-2008 Mellanox Technologies LTD. All rights reserved.
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
@@ -158,7 +158,6 @@ static void drop_mgr_remove_port(osm_sm_t * sm, IN osm_port_t * p_port)
osm_port_t *p_port_check;
cl_qmap_t *p_sm_guid_tbl;
osm_mcm_info_t *p_mcm;
- osm_mgrp_t *p_mgrp;
cl_ptr_vector_t *p_port_lid_tbl;
uint16_t min_lid_ho;
uint16_t max_lid_ho;
@@ -168,6 +167,7 @@ static void drop_mgr_remove_port(osm_sm_t * sm, IN osm_port_t * p_port)
ib_gid_t port_gid;
ib_mad_notice_attr_t notice;
ib_api_status_t status;
+ osm_mgrp_holder_t *p_mgrp_holder;
OSM_LOG_ENTER(sm->p_log);
@@ -212,10 +212,12 @@ static void drop_mgr_remove_port(osm_sm_t * sm, IN osm_port_t * p_port)
p_mcm = (osm_mcm_info_t *) cl_qlist_remove_head(&p_port->mcm_list);
while (p_mcm != (osm_mcm_info_t *) cl_qlist_end(&p_port->mcm_list)) {
- p_mgrp = osm_get_mgrp_by_mlid(sm->p_subn, p_mcm->mlid);
- if (p_mgrp) {
- osm_mgrp_delete_port(sm->p_subn, sm->p_log,
- p_mgrp, p_port->guid);
+ p_mgrp_holder =
+ osm_get_mgrp_holder_by_mlid(sm->p_subn, p_mcm->mlid);
+ if (p_mgrp_holder) {
+ osm_mgrp_holder_remove_port(sm->p_subn, sm->p_log,
+ p_mgrp_holder,
+ p_port->guid);
osm_mcm_info_delete((osm_mcm_info_t *) p_mcm);
}
p_mcm =
diff --git a/opensm/opensm/osm_mcast_mgr.c b/opensm/opensm/osm_mcast_mgr.c
index 4dbbaa0..f506393 100644
--- a/opensm/opensm/osm_mcast_mgr.c
+++ b/opensm/opensm/osm_mcast_mgr.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-2006 Mellanox Technologies LTD. All rights reserved.
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
@@ -55,6 +55,7 @@
#include <opensm/osm_switch.h>
#include <opensm/osm_helper.h>
#include <opensm/osm_msgdef.h>
+#include <arpa/inet.h>
/**********************************************************************
**********************************************************************/
@@ -111,14 +112,15 @@ static void mcast_mgr_purge_tree_node(IN osm_mtree_node_t * p_mtn)
/**********************************************************************
**********************************************************************/
-static void mcast_mgr_purge_tree(osm_sm_t * sm, IN osm_mgrp_t * p_mgrp)
+static void mcast_mgr_purge_tree(osm_sm_t * sm,
+ IN osm_mgrp_holder_t * p_mgrp_holder)
{
OSM_LOG_ENTER(sm->p_log);
- if (p_mgrp->p_root)
- mcast_mgr_purge_tree_node(p_mgrp->p_root);
+ if (p_mgrp_holder->p_root)
+ mcast_mgr_purge_tree_node(p_mgrp_holder->p_root);
- p_mgrp->p_root = NULL;
+ p_mgrp_holder->p_root = NULL;
OSM_LOG_EXIT(sm->p_log);
}
@@ -126,41 +128,40 @@ static void mcast_mgr_purge_tree(osm_sm_t * sm, IN osm_mgrp_t * p_mgrp)
/**********************************************************************
**********************************************************************/
static float osm_mcast_mgr_compute_avg_hops(osm_sm_t * sm,
- const osm_mgrp_t * p_mgrp,
+ const osm_mgrp_holder_t *
+ p_mgrp_holder,
const osm_switch_t * p_sw)
{
float avg_hops = 0;
uint32_t hops = 0;
uint32_t num_ports = 0;
const osm_port_t *p_port;
- const osm_mcm_port_t *p_mcm_port;
- const cl_qmap_t *p_mcm_tbl;
+ const osm_mgrp_port_t *p_holder_port;
OSM_LOG_ENTER(sm->p_log);
- p_mcm_tbl = &p_mgrp->mcm_port_tbl;
/*
For each member of the multicast group, compute the
number of hops to its base LID.
*/
- for (p_mcm_port = (osm_mcm_port_t *) cl_qmap_head(p_mcm_tbl);
- p_mcm_port != (osm_mcm_port_t *) cl_qmap_end(p_mcm_tbl);
- p_mcm_port =
- (osm_mcm_port_t *) cl_qmap_next(&p_mcm_port->map_item)) {
+ for (p_holder_port =
+ (osm_mgrp_port_t *) cl_qmap_head(&p_mgrp_holder->mgrp_port_map);
+ p_holder_port !=
+ (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_holder->mgrp_port_map);
+ p_holder_port =
+ (osm_mgrp_port_t *) cl_qmap_next(&p_holder_port->guid_item)) {
/*
Acquire the port object for this port guid, then create
the new worker object to build the list.
*/
p_port = osm_get_port_by_guid(sm->p_subn,
- ib_gid_get_guid(&p_mcm_port->
- port_gid));
+ p_holder_port->port_guid);
if (!p_port) {
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A18: "
"No port object for port 0x%016" PRIx64 "\n",
- cl_ntoh64(ib_gid_get_guid
- (&p_mcm_port->port_gid)));
+ cl_ntoh64(p_holder_port->port_guid));
continue;
}
@@ -185,40 +186,39 @@ static float osm_mcast_mgr_compute_avg_hops(osm_sm_t * sm,
of the group HCAs
**********************************************************************/
static float osm_mcast_mgr_compute_max_hops(osm_sm_t * sm,
- const osm_mgrp_t * p_mgrp,
+ const osm_mgrp_holder_t *
+ p_mgrp_holder,
const osm_switch_t * p_sw)
{
uint32_t max_hops = 0;
uint32_t hops = 0;
const osm_port_t *p_port;
- const osm_mcm_port_t *p_mcm_port;
- const cl_qmap_t *p_mcm_tbl;
+ const osm_mgrp_port_t *p_mgrp_holder_port;
OSM_LOG_ENTER(sm->p_log);
- p_mcm_tbl = &p_mgrp->mcm_port_tbl;
/*
For each member of the multicast group, compute the
number of hops to its base LID.
*/
- for (p_mcm_port = (osm_mcm_port_t *) cl_qmap_head(p_mcm_tbl);
- p_mcm_port != (osm_mcm_port_t *) cl_qmap_end(p_mcm_tbl);
- p_mcm_port =
- (osm_mcm_port_t *) cl_qmap_next(&p_mcm_port->map_item)) {
+ for (p_mgrp_holder_port =
+ (osm_mgrp_port_t *) cl_qmap_head(&p_mgrp_holder->mgrp_port_map);
+ p_mgrp_holder_port !=
+ (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_holder->mgrp_port_map);
+ p_mgrp_holder_port =
+ (osm_mgrp_port_t *) cl_qmap_next(&p_mgrp_holder_port->guid_item)) {
/*
Acquire the port object for this port guid, then create
the new worker object to build the list.
*/
p_port = osm_get_port_by_guid(sm->p_subn,
- ib_gid_get_guid(&p_mcm_port->
- port_gid));
+ p_mgrp_holder_port->port_guid);
if (!p_port) {
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A1A: "
"No port object for port 0x%016" PRIx64 "\n",
- cl_ntoh64(ib_gid_get_guid
- (&p_mcm_port->port_gid)));
+ cl_ntoh64(p_mgrp_holder_port->port_guid));
continue;
}
@@ -244,7 +244,8 @@ static float osm_mcast_mgr_compute_max_hops(osm_sm_t * sm,
of the multicast group.
**********************************************************************/
static osm_switch_t *mcast_mgr_find_optimal_switch(osm_sm_t * sm,
- const osm_mgrp_t * p_mgrp)
+ const osm_mgrp_holder_t *
+ p_mgrp_holder)
{
cl_qmap_t *p_sw_tbl;
const osm_switch_t *p_sw;
@@ -252,7 +253,7 @@ static osm_switch_t *mcast_mgr_find_optimal_switch(osm_sm_t * sm,
float hops = 0;
float best_hops = 10000; /* any big # will do */
#ifdef OSM_VENDOR_INTF_ANAFA
- boolean_t use_avg_hops = TRUE; /* anafa2 - bug hca on switch *//* use max hops for root */
+ boolean_t use_avg_hops = TRUE; /* anafa2 - bug hca on switch *//* use max hops for root */
#else
boolean_t use_avg_hops = FALSE; /* use max hops for root */
#endif
@@ -261,7 +262,7 @@ static osm_switch_t *mcast_mgr_find_optimal_switch(osm_sm_t * sm,
p_sw_tbl = &sm->p_subn->sw_guid_tbl;
- CL_ASSERT(!osm_mgrp_is_empty(p_mgrp));
+ CL_ASSERT(!osm_mgrp_holder_is_empty(p_mgrp_holder));
for (p_sw = (osm_switch_t *) cl_qmap_head(p_sw_tbl);
p_sw != (osm_switch_t *) cl_qmap_end(p_sw_tbl);
@@ -270,9 +271,13 @@ static osm_switch_t *mcast_mgr_find_optimal_switch(osm_sm_t * sm,
continue;
if (use_avg_hops)
- hops = osm_mcast_mgr_compute_avg_hops(sm, p_mgrp, p_sw);
+ hops =
+ osm_mcast_mgr_compute_avg_hops(sm, p_mgrp_holder,
+ p_sw);
else
- hops = osm_mcast_mgr_compute_max_hops(sm, p_mgrp, p_sw);
+ hops =
+ osm_mcast_mgr_compute_max_hops(sm, p_mgrp_holder,
+ p_sw);
OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
"Switch 0x%016" PRIx64 ", hops = %f\n",
@@ -301,7 +306,8 @@ static osm_switch_t *mcast_mgr_find_optimal_switch(osm_sm_t * sm,
This function returns the existing or optimal root swtich for the tree.
**********************************************************************/
static osm_switch_t *mcast_mgr_find_root_switch(osm_sm_t * sm,
- const osm_mgrp_t * p_mgrp)
+ const osm_mgrp_holder_t *
+ p_mgrp_holder)
{
const osm_switch_t *p_sw = NULL;
@@ -313,7 +319,7 @@ static osm_switch_t *mcast_mgr_find_root_switch(osm_sm_t * sm,
the root will be always on the first switch attached to it.
- Very bad ...
*/
- p_sw = mcast_mgr_find_optimal_switch(sm, p_mgrp);
+ p_sw = mcast_mgr_find_optimal_switch(sm, p_mgrp_holder);
OSM_LOG_EXIT(sm->p_log);
return (osm_switch_t *) p_sw;
@@ -393,7 +399,8 @@ static int mcast_mgr_set_tbl(osm_sm_t * sm, IN osm_switch_t * p_sw)
spanning tree that eminate from this switch. On input, the p_list
contains the group members that must be routed from this switch.
**********************************************************************/
-static void mcast_mgr_subdivide(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
+static void mcast_mgr_subdivide(osm_sm_t * sm,
+ osm_mgrp_holder_t * p_mgrp_holder,
osm_switch_t * p_sw, cl_qlist_t * p_list,
cl_qlist_t * list_array, uint8_t array_size)
{
@@ -404,7 +411,7 @@ static void mcast_mgr_subdivide(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
OSM_LOG_ENTER(sm->p_log);
- mlid_ho = cl_ntoh16(osm_mgrp_get_mlid(p_mgrp));
+ mlid_ho = cl_ntoh16(osm_mgrp_holder_get_mlid(p_mgrp_holder));
/*
For Multicast Groups, we want not to count on previous
@@ -494,7 +501,8 @@ static void mcast_mgr_purge_list(osm_sm_t * sm, cl_qlist_t * p_list)
The function returns the newly created mtree node element.
**********************************************************************/
-static osm_mtree_node_t *mcast_mgr_branch(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
+static osm_mtree_node_t *mcast_mgr_branch(osm_sm_t * sm,
+ osm_mgrp_holder_t * p_mgrp_holder,
osm_switch_t * p_sw,
cl_qlist_t * p_list, uint8_t depth,
uint8_t upstream_port,
@@ -520,7 +528,7 @@ static osm_mtree_node_t *mcast_mgr_branch(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
node_guid = osm_node_get_node_guid(p_sw->p_node);
node_guid_ho = cl_ntoh64(node_guid);
- mlid_ho = cl_ntoh16(osm_mgrp_get_mlid(p_mgrp));
+ mlid_ho = cl_ntoh16(osm_mgrp_holder_get_mlid(p_mgrp_holder));
OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
"Routing MLID 0x%X through switch 0x%" PRIx64
@@ -597,7 +605,8 @@ static osm_mtree_node_t *mcast_mgr_branch(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
for (i = 0; i < max_children; i++)
cl_qlist_init(&list_array[i]);
- mcast_mgr_subdivide(sm, p_mgrp, p_sw, p_list, list_array, max_children);
+ mcast_mgr_subdivide(sm, p_mgrp_holder, p_sw, p_list, list_array,
+ max_children);
p_tbl = osm_switch_get_mcast_tbl_ptr(p_sw);
@@ -680,8 +689,9 @@ static osm_mtree_node_t *mcast_mgr_branch(osm_sm_t * sm, osm_mgrp_t * p_mgrp,
CL_ASSERT(p_remote_physp);
p_mtn->child_array[i] =
- mcast_mgr_branch(sm, p_mgrp, p_remote_node->sw,
- p_port_list, depth,
+ mcast_mgr_branch(sm, p_mgrp_holder,
+ p_remote_node->sw, p_port_list,
+ depth,
osm_physp_get_port_num
(p_remote_physp), p_max_depth);
} else {
@@ -716,11 +726,11 @@ Exit:
/**********************************************************************
**********************************************************************/
static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
- osm_mgrp_t * p_mgrp)
+ osm_mgrp_holder_t *
+ p_mgrp_holder)
{
- const cl_qmap_t *p_mcm_tbl;
const osm_port_t *p_port;
- const osm_mcm_port_t *p_mcm_port;
+ const osm_mgrp_port_t *p_mgrp_port;
uint32_t num_ports;
cl_qlist_t port_list;
osm_switch_t *p_sw;
@@ -739,14 +749,13 @@ static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
on multicast forwarding table information if the user wants to
preserve existing multicast routes.
*/
- mcast_mgr_purge_tree(sm, p_mgrp);
+ mcast_mgr_purge_tree(sm, p_mgrp_holder);
- p_mcm_tbl = &p_mgrp->mcm_port_tbl;
- num_ports = cl_qmap_count(p_mcm_tbl);
+ num_ports = cl_qmap_count(&p_mgrp_holder->mgrp_port_map);
if (num_ports == 0) {
OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
"MLID 0x%X has no members - nothing to do\n",
- cl_ntoh16(osm_mgrp_get_mlid(p_mgrp)));
+ cl_ntoh16(osm_mgrp_holder_get_mlid(p_mgrp_holder)));
goto Exit;
}
@@ -766,11 +775,11 @@ static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
Locate the switch around which to create the spanning
tree for this multicast group.
*/
- p_sw = mcast_mgr_find_root_switch(sm, p_mgrp);
+ p_sw = mcast_mgr_find_root_switch(sm, p_mgrp_holder);
if (p_sw == NULL) {
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A08: "
"Unable to locate a suitable switch for group 0x%X\n",
- cl_ntoh16(osm_mgrp_get_mlid(p_mgrp)));
+ cl_ntoh16(osm_mgrp_holder_get_mlid(p_mgrp_holder)));
status = IB_ERROR;
goto Exit;
}
@@ -778,22 +787,22 @@ static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
/*
Build the first "subset" containing all member ports.
*/
- for (p_mcm_port = (osm_mcm_port_t *) cl_qmap_head(p_mcm_tbl);
- p_mcm_port != (osm_mcm_port_t *) cl_qmap_end(p_mcm_tbl);
- p_mcm_port =
- (osm_mcm_port_t *) cl_qmap_next(&p_mcm_port->map_item)) {
+ for (p_mgrp_port =
+ (osm_mgrp_port_t *) cl_qmap_head(&p_mgrp_holder->mgrp_port_map);
+ p_mgrp_port !=
+ (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_holder->mgrp_port_map);
+ p_mgrp_port =
+ (osm_mgrp_port_t *) cl_qmap_next(&p_mgrp_port->guid_item)) {
/*
Acquire the port object for this port guid, then create
the new worker object to build the list.
*/
- p_port = osm_get_port_by_guid(sm->p_subn,
- ib_gid_get_guid(&p_mcm_port->
- port_gid));
+ p_port =
+ osm_get_port_by_guid(sm->p_subn, p_mgrp_port->port_guid);
if (!p_port) {
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A09: "
"No port object for port 0x%016" PRIx64 "\n",
- cl_ntoh64(ib_gid_get_guid
- (&p_mcm_port->port_gid)));
+ cl_ntoh64(p_mgrp_port->port_guid));
continue;
}
@@ -801,8 +810,7 @@ static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
if (p_wobj == NULL) {
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A10: "
"Insufficient memory to route port 0x%016"
- PRIx64 "\n",
- cl_ntoh64(osm_port_get_guid(p_port)));
+ PRIx64 "\n", cl_ntoh64(p_mgrp_port->port_guid));
continue;
}
@@ -810,12 +818,14 @@ static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
}
count = cl_qlist_count(&port_list);
- p_mgrp->p_root = mcast_mgr_branch(sm, p_mgrp, p_sw, &port_list, 0, 0,
- &max_depth);
+ p_mgrp_holder->p_root =
+ mcast_mgr_branch(sm, p_mgrp_holder, p_sw, &port_list, 0, 0,
+ &max_depth);
OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
"Configured MLID 0x%X for %u ports, max tree depth = %u\n",
- cl_ntoh16(osm_mgrp_get_mlid(p_mgrp)), count, max_depth);
+ cl_ntoh16(osm_mgrp_holder_get_mlid(p_mgrp_holder)), count,
+ max_depth);
Exit:
OSM_LOG_EXIT(sm->p_log);
@@ -1023,17 +1033,20 @@ Exit:
NOTE : The lock should be held externally!
**********************************************************************/
static ib_api_status_t mcast_mgr_process_mgrp(osm_sm_t * sm,
- IN osm_mgrp_t * p_mgrp)
+ IN osm_mgrp_holder_t * p_mgrp_holder)
{
ib_api_status_t status = IB_SUCCESS;
ib_net16_t mlid;
+ osm_mgrp_t *p_mgrp;
+ cl_list_item_t *p_item;
+ unsigned has_full_members = 0;
OSM_LOG_ENTER(sm->p_log);
- mlid = osm_mgrp_get_mlid(p_mgrp);
+ mlid = osm_mgrp_holder_get_mlid(p_mgrp_holder);
OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
- "Processing multicast group 0x%X\n", cl_ntoh16(mlid));
+ "Processing multicast group_holder 0x%X\n", cl_ntoh16(mlid));
/*
Clear the multicast tables to start clean, then build
@@ -1042,27 +1055,52 @@ static ib_api_status_t mcast_mgr_process_mgrp(osm_sm_t * sm,
*/
mcast_mgr_clear(sm, cl_ntoh16(mlid));
- if (p_mgrp->full_members) {
- status = mcast_mgr_build_spanning_tree(sm, p_mgrp);
+ p_item = cl_qlist_head(&p_mgrp_holder->mgrp_list);
+ while (p_item != cl_qlist_end(&p_mgrp_holder->mgrp_list)) {
+ char gid_str[INET6_ADDRSTRLEN];
+ p_mgrp = (osm_mgrp_t *)
+ PARENT_STRUCT(p_item, osm_mgrp_t, mlid_item);
+ OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+ "MLID 0x%x has mgrp %s\n",cl_ntoh16(p_mgrp->mlid),
+ inet_ntop(AF_INET6,
+ p_mgrp->mcmember_rec.mgid.raw,
+ gid_str, sizeof(gid_str)));
+ p_item = cl_qlist_next(p_item);
+ if (p_mgrp->to_be_deleted) {
+ osm_mcm_port_t *p_mcm_port;
+ OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+ "Destroying mgrp %s with lid:0x%x\n",
+ inet_ntop(AF_INET6,
+ p_mgrp->mcmember_rec.mgid.raw,
+ gid_str, sizeof(gid_str)),
+ cl_ntoh16(p_mgrp->mlid));
+ osm_mgrp_holder_delete_mgrp(p_mgrp_holder, p_mgrp);
+ p_mcm_port = (osm_mcm_port_t *) cl_qmap_head(&p_mgrp->mcm_port_tbl);
+ while (p_mcm_port !=
+ (osm_mcm_port_t *) cl_qmap_end(&p_mgrp->mcm_port_tbl)) {
+ osm_mgrp_holder_port_delete_mgrp(p_mgrp_holder, p_mgrp,
+ p_mcm_port->port_gid.unicast.interface_id);
+ p_mcm_port =
+ (osm_mcm_port_t *) cl_qmap_next(&p_mcm_port->map_item);
+ }
+ cl_fmap_remove_item(&sm->p_subn->mgrp_mgid_tbl,
+ &p_mgrp->map_item);
+ osm_mgrp_delete(p_mgrp);
+ }
+ else if (!has_full_members)
+ has_full_members = p_mgrp->full_members;
+ }
+ if (has_full_members) {
+ status = mcast_mgr_build_spanning_tree(sm, p_mgrp_holder);
if (status != IB_SUCCESS) {
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A17: "
"Unable to create spanning tree (%s)\n",
ib_get_err_str(status));
goto Exit;
}
- } else if (p_mgrp->to_be_deleted) {
- OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
- "Destroying mgrp with lid:0x%x\n",
- cl_ntoh16(p_mgrp->mlid));
- sm->p_subn->mgroups[cl_ntoh16(p_mgrp->mlid) -
- IB_LID_MCAST_START_HO] = NULL;
- cl_fmap_remove_item(&sm->p_subn->mgrp_mgid_tbl,
- &p_mgrp->map_item);
- osm_mgrp_delete(p_mgrp);
- goto Exit;
+ p_mgrp_holder->last_tree_id = p_mgrp_holder->last_change_id;
}
- p_mgrp->last_tree_id = p_mgrp->last_change_id;
Exit:
OSM_LOG_EXIT(sm->p_log);
@@ -1076,7 +1114,7 @@ int osm_mcast_mgr_process(osm_sm_t * sm)
osm_switch_t *p_sw;
cl_qmap_t *p_sw_tbl;
cl_qlist_t *p_list = &sm->mgrp_list;
- osm_mgrp_t *p_mgrp;
+ osm_mgrp_holder_t *p_mgrp_holder;
int i, ret = 0;
OSM_LOG_ENTER(sm->p_log);
@@ -1104,9 +1142,10 @@ int osm_mcast_mgr_process(osm_sm_t * sm)
of the subnet. Not due to a specific multicast request.
So the request type is subnet_change and the port guid is 0.
*/
- p_mgrp = sm->p_subn->mgroups[i];
- if (p_mgrp)
- mcast_mgr_process_mgrp(sm, p_mgrp);
+ p_mgrp_holder = sm->p_subn->mgroup_holders[i];
+ if (p_mgrp_holder) {
+ mcast_mgr_process_mgrp(sm, p_mgrp_holder);
+ }
}
/*
@@ -1141,7 +1180,7 @@ int osm_mcast_mgr_process_mgroups(osm_sm_t * sm)
cl_qlist_t *p_list = &sm->mgrp_list;
osm_switch_t *p_sw;
cl_qmap_t *p_sw_tbl;
- osm_mgrp_t *p_mgrp;
+ osm_mgrp_holder_t *p_mgrp_holder;
ib_net16_t mlid;
osm_mcast_mgr_ctxt_t *ctx;
int ret = 0;
@@ -1169,24 +1208,25 @@ int osm_mcast_mgr_process_mgroups(osm_sm_t * sm)
/* since we delayed the execution we prefer to pass the
mlid as the mgrp identifier and then find it or abort */
- p_mgrp = osm_get_mgrp_by_mlid(sm->p_subn, mlid);
- if (!p_mgrp)
+ p_mgrp_holder = osm_get_mgrp_holder_by_mlid(sm->p_subn, mlid);
+ if (!p_mgrp_holder)
continue;
/* if there was no change from the last time
* we processed the group we can skip doing anything
*/
- if (p_mgrp->last_change_id == p_mgrp->last_tree_id) {
+ if (p_mgrp_holder->last_change_id ==
+ p_mgrp_holder->last_tree_id) {
OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
- "Skip processing mgrp with lid:0x%X change id:%u\n",
- cl_ntoh16(mlid), p_mgrp->last_change_id);
+ "Skip processing p_mgrp_holder with lid:0x%X change id:%u\n",
+ cl_ntoh16(mlid), p_mgrp_holder->last_change_id);
continue;
}
OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
"Processing mgrp with lid:0x%X change id:%u\n",
- cl_ntoh16(mlid), p_mgrp->last_change_id);
- mcast_mgr_process_mgrp(sm, p_mgrp);
+ cl_ntoh16(mlid), p_mgrp_holder->last_change_id);
+ mcast_mgr_process_mgrp(sm, p_mgrp_holder);
}
/*
diff --git a/opensm/opensm/osm_multicast.c b/opensm/opensm/osm_multicast.c
index d2733c4..072b591 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.
*
@@ -48,6 +48,7 @@
#include <opensm/osm_mcm_port.h>
#include <opensm/osm_mtree.h>
#include <opensm/osm_inform.h>
+#include <arpa/inet.h>
/**********************************************************************
**********************************************************************/
@@ -67,8 +68,6 @@ void osm_mgrp_delete(IN osm_mgrp_t * p_mgrp)
(osm_mcm_port_t *) cl_qmap_next(&p_mcm_port->map_item);
osm_mcm_port_delete(p_mcm_port);
}
- /* destroy the mtree_node structure */
- osm_mtree_destroy(p_mgrp->p_root);
free(p_mgrp);
}
@@ -86,9 +85,6 @@ osm_mgrp_t *osm_mgrp_new(IN const ib_net16_t mlid)
memset(p_mgrp, 0, sizeof(*p_mgrp));
cl_qmap_init(&p_mgrp->mcm_port_tbl);
p_mgrp->mlid = mlid;
- p_mgrp->last_change_id = 0;
- p_mgrp->last_tree_id = 0;
- p_mgrp->to_be_deleted = FALSE;
return p_mgrp;
}
@@ -133,6 +129,7 @@ osm_mcm_port_t *osm_mgrp_add_port(IN osm_subn_t * subn, osm_log_t * log,
ib_net64_t port_guid;
osm_mcm_port_t *p_mcm_port;
cl_map_item_t *prev_item;
+ osm_mgrp_holder_t *p_mgrp_holder;
uint8_t prev_join_state = 0;
uint8_t prev_scope;
@@ -167,9 +164,18 @@ osm_mcm_port_t *osm_mgrp_add_port(IN osm_subn_t * subn, osm_log_t * log,
p_mcm_port->scope_state =
ib_member_set_scope_state(prev_scope,
prev_join_state | join_state);
- } else {
- /* track the fact we modified the group ports */
- p_mgrp->last_change_id++;
+ }
+
+ p_mgrp_holder = osm_get_mgrp_holder_by_mlid(subn, p_mgrp->mlid);
+ if (! p_mgrp_holder ||
+ (IB_SUCCESS != osm_mgrp_holder_port_add_mgrp(p_mgrp_holder,
+ p_mgrp, port_guid)) ) {
+ /* if the above failed and added port is new one, remove port also from mcm_port_tbl */
+ if (! prev_join_state) {
+ cl_qmap_remove_item(&p_mgrp->mcm_port_tbl, &p_mcm_port->map_item);
+ osm_mcm_port_delete(p_mcm_port);
+ }
+ return NULL;
}
if ((join_state & IB_JOIN_STATE_FULL) &&
@@ -212,7 +218,6 @@ int osm_mgrp_remove_port(osm_subn_t * subn, osm_log_t * log, osm_mgrp_t * mgrp,
cl_ntoh64(mcm->port_gid.unicast.interface_id));
osm_mcm_port_delete(mcm);
/* track the fact we modified the group */
- mgrp->last_change_id++;
ret = 1;
}
@@ -285,16 +290,173 @@ static void mgrp_apply_func_sub(const osm_mgrp_t * p_mgrp,
/**********************************************************************
**********************************************************************/
-void osm_mgrp_apply_func(const osm_mgrp_t * p_mgrp, osm_mgrp_func_t p_func,
- void *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_mtree_node_t *p_mtn;
+ 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;
- CL_ASSERT(p_mgrp);
- CL_ASSERT(p_func);
+ 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, ib_net16_t mlid)
+{
+ 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(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_all(&p_mgrp_holder->mgrp_list);
+ /* 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);
+}
- p_mtn = p_mgrp->p_root;
+/**********************************************************************
+ **********************************************************************/
+void osm_mgrp_holder_add_mgrp(osm_mgrp_holder_t * p_mgrp_holder,
+ osm_mgrp_t * p_mgrp, osm_log_t * p_log)
+{
+ char gid_str[INET6_ADDRSTRLEN];
+
+ OSM_LOG_ENTER(p_log);
+ p_mgrp_holder->to_be_deleted = 0;
+ 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);
+}
- if (p_mtn)
- mgrp_apply_func_sub(p_mgrp, p_mtn, p_func, context);
+/**********************************************************************
+ **********************************************************************/
+void osm_mgrp_holder_delete_mgrp(osm_mgrp_holder_t * p_mgrp_holder,
+ osm_mgrp_t * p_mgrp)
+{
+ p_mgrp->to_be_deleted = 1;
+ cl_qlist_remove_item(&p_mgrp_holder->mgrp_list, &p_mgrp->mlid_item);
+ 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);
+ p_mgrp_holder->last_change_id++;
+ 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++;
+ }
}
diff --git a/opensm/opensm/osm_qos_policy.c b/opensm/opensm/osm_qos_policy.c
index 7826578..041377f 100644
--- a/opensm/opensm/osm_qos_policy.c
+++ b/opensm/opensm/osm_qos_policy.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.
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
@@ -785,7 +785,9 @@ static void __qos_policy_validate_pkey(
uint8_t sl;
uint32_t flow;
uint8_t hop;
+ osm_mgrp_holder_t * p_mgrp_holder;
osm_mgrp_t * p_mgrp;
+ cl_list_item_t *p_item;
if (!p_qos_policy || !p_qos_match_rule || !p_prtn)
return;
@@ -809,31 +811,35 @@ static void __qos_policy_validate_pkey(
if (!p_prtn->mlid)
return;
- p_mgrp = osm_get_mgrp_by_mlid(p_qos_policy->p_subn, p_prtn->mlid);
- if (!p_mgrp) {
+ p_mgrp_holder =
+ osm_get_mgrp_holder_by_mlid(p_qos_policy->p_subn, p_prtn->mlid);
+ if (!p_mgrp_holder) {
OSM_LOG(&p_qos_policy->p_subn->p_osm->log, OSM_LOG_ERROR,
- "ERR AC16: MCast group for partition with "
- "pkey 0x%04X not found\n",
- cl_ntoh16(p_prtn->pkey));
+ "ERR AC16: MCast mgrp_holder for partition with pkey 0x%04X not found\n",
+ cl_ntoh16(p_prtn->pkey));
return;
}
- CL_ASSERT((cl_ntoh16(p_mgrp->mcmember_rec.pkey) & 0x7fff) ==
- (cl_ntoh16(p_prtn->pkey) & 0x7fff));
-
- ib_member_get_sl_flow_hop(p_mgrp->mcmember_rec.sl_flow_hop,
- &sl, &flow, &hop);
- if (sl != p_prtn->sl) {
- OSM_LOG(&p_qos_policy->p_subn->p_osm->log, OSM_LOG_DEBUG,
+ p_item = cl_qlist_head(&p_mgrp_holder->mgrp_list);
+ while (p_item != cl_qlist_end(&p_mgrp_holder->mgrp_list)) {
+ p_mgrp = (osm_mgrp_t *) PARENT_STRUCT(p_item, osm_mgrp_t,
+ mlid_item);
+ p_item = cl_qlist_next(p_item);
+ CL_ASSERT((cl_ntoh16(p_mgrp->mcmember_rec.pkey) & 0x7fff) ==
+ (cl_ntoh16(p_prtn->pkey) & 0x7fff));
+ ib_member_get_sl_flow_hop(p_mgrp->mcmember_rec.sl_flow_hop,
+ &sl, &flow, &hop);
+ if (sl != p_prtn->sl) {
+ OSM_LOG(&p_qos_policy->p_subn->p_osm->log, OSM_LOG_DEBUG,
"Updating MCGroup (MLID 0x%04x) SL to "
"match partition SL (%u)\n",
cl_hton16(p_mgrp->mcmember_rec.mlid),
p_prtn->sl);
- p_mgrp->mcmember_rec.sl_flow_hop =
- ib_member_set_sl_flow_hop(p_prtn->sl, flow, hop);
+ p_mgrp->mcmember_rec.sl_flow_hop =
+ ib_member_set_sl_flow_hop(p_prtn->sl, flow, hop);
+ }
}
}
-
/***************************************************
***************************************************/
diff --git a/opensm/opensm/osm_sa.c b/opensm/opensm/osm_sa.c
index fcc3f27..22dd495 100644
--- a/opensm/opensm/osm_sa.c
+++ b/opensm/opensm/osm_sa.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.
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
@@ -706,17 +706,15 @@ static void sa_dump_all_sa(osm_opensm_t * p_osm, FILE * file)
{
struct opensm_dump_context dump_context;
osm_mgrp_t *p_mgrp;
- int i;
dump_context.p_osm = p_osm;
dump_context.file = file;
OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump multicast\n");
cl_plock_acquire(&p_osm->lock);
- for (i = 0; i <= p_osm->subn.max_mcast_lid_ho - IB_LID_MCAST_START_HO;
- i++) {
- p_mgrp = p_osm->subn.mgroups[i];
- if (p_mgrp)
- sa_dump_one_mgrp(p_mgrp, &dump_context);
+ p_mgrp = (osm_mgrp_t*)cl_fmap_head(&p_osm->subn.mgrp_mgid_tbl);
+ while (p_mgrp != (osm_mgrp_t*)cl_fmap_end(&p_osm->subn.mgrp_mgid_tbl)) {
+ sa_dump_one_mgrp(p_mgrp, &dump_context);
+ p_mgrp = (osm_mgrp_t*) cl_fmap_next(&p_mgrp->map_item);
}
OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump inform\n");
cl_qlist_apply_func(&p_osm->subn.sa_infr_list,
@@ -740,23 +738,16 @@ static osm_mgrp_t *load_mcgroup(osm_opensm_t * p_osm, ib_net16_t mlid,
unsigned well_known)
{
ib_net64_t comp_mask;
- osm_mgrp_t *p_mgrp;
+ cl_fmap_item_t *p_fitem;
+ osm_mgrp_t *p_mgrp = NULL;
cl_plock_excl_acquire(&p_osm->lock);
- p_mgrp = osm_get_mgrp_by_mlid(&p_osm->subn, mlid);
- if (p_mgrp) {
- if (!memcmp(&p_mgrp->mcmember_rec.mgid, &p_mcm_rec->mgid,
- sizeof(ib_gid_t))) {
- OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
- "mgrp %04x is already here.", cl_ntoh16(mlid));
+ p_fitem = cl_fmap_get(&p_osm->subn.mgrp_mgid_tbl, &p_mcm_rec->mgid);
+ if (p_fitem != cl_fmap_end(&p_osm->subn.mgrp_mgid_tbl)) {
+ OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
+ "mgrp %04x is already here.", cl_ntoh16(mlid));
goto _out;
- }
- OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
- "mlid %04x is already used by another MC group. Will "
- "request clients reregistration.\n", cl_ntoh16(mlid));
- p_mgrp = NULL;
- goto _out;
}
comp_mask = IB_MCR_COMPMASK_MTU | IB_MCR_COMPMASK_MTU_SEL
diff --git a/opensm/opensm/osm_sa_mcmember_record.c b/opensm/opensm/osm_sa_mcmember_record.c
index a9e0a3b..3838a08 100644
--- a/opensm/opensm/osm_sa_mcmember_record.c
+++ b/opensm/opensm/osm_sa_mcmember_record.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.
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
@@ -121,14 +121,17 @@ static ib_net16_t get_new_mlid(osm_sa_t * sa, ib_net16_t requested_mlid)
if (requested_mlid && cl_ntoh16(requested_mlid) >= IB_LID_MCAST_START_HO
&& cl_ntoh16(requested_mlid) <= p_subn->max_mcast_lid_ho
- && !osm_get_mgrp_by_mlid(p_subn, requested_mlid))
+ && !osm_get_mgrp_holder_by_mlid(p_subn, requested_mlid))
return requested_mlid;
max = p_subn->max_mcast_lid_ho - IB_LID_MCAST_START_HO + 1;
for (i = 0; i < max; i++) {
- osm_mgrp_t *p_mgrp = sa->p_subn->mgroups[i];
- if (!p_mgrp || p_mgrp->to_be_deleted)
- return cl_hton16(i + IB_LID_MCAST_START_HO);
+ osm_mgrp_holder_t *p_mgrp_holder = sa->p_subn->mgroup_holders[i];
+ if (!p_mgrp_holder || p_mgrp_holder->to_be_deleted) {
+ OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "returning mgrp_holder to_be_deleted =%d\n",
+ p_mgrp_holder ? p_mgrp_holder->to_be_deleted : 0);
+ return cl_hton16(i + IB_LID_MCAST_START_HO);
+ }
}
return 0;
@@ -146,8 +149,9 @@ static void cleanup_mgrp(IN osm_sa_t * sa, osm_mgrp_t * mgrp)
/* Remove MGRP only if osm_mcm_port_t count is 0 and
not a well known group */
if (cl_is_qmap_empty(&mgrp->mcm_port_tbl) && !mgrp->well_known) {
- sa->p_subn->mgroups[cl_ntoh16(mgrp->mlid) -
- IB_LID_MCAST_START_HO] = NULL;
+ osm_mgrp_holder_t *p_mgrp_holder =
+ osm_get_mgrp_holder_by_mlid(sa->p_subn, mgrp->mlid);
+ osm_mgrp_holder_delete_mgrp(p_mgrp_holder, mgrp);
cl_fmap_remove_item(&sa->p_subn->mgrp_mgid_tbl,
&mgrp->map_item);
osm_mgrp_delete(mgrp);
@@ -802,19 +806,19 @@ static boolean_t mgrp_request_is_realizable(IN osm_sa_t * sa,
Call this function to create a new mgrp.
**********************************************************************/
ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
- IN ib_net64_t comp_mask,
- IN const ib_member_rec_t *
- const p_recvd_mcmember_rec,
- IN const osm_physp_t * p_physp,
- OUT osm_mgrp_t ** pp_mgrp)
+ IN ib_net64_t comp_mask,
+ IN const ib_member_rec_t *
+ const p_recvd_mcmember_rec,
+ IN const osm_physp_t * p_physp,
+ OUT osm_mgrp_t ** pp_mgrp)
{
- ib_net16_t mlid;
+ ib_net16_t mlid, existed_mlid;
unsigned zero_mgid, i;
uint8_t scope;
ib_gid_t *p_mgid;
- osm_mgrp_t *p_prev_mgrp;
ib_api_status_t status = IB_SUCCESS;
ib_member_rec_t mcm_rec = *p_recvd_mcmember_rec; /* copy for modifications */
+ osm_mgrp_holder_t * p_mgrp_holder;
OSM_LOG_ENTER(sa->p_log);
@@ -890,6 +894,15 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
goto Exit;
}
+ if (0 != (existed_mlid = osm_mgrp_holder_get_mlid_by_mgid(sa->p_subn, p_mgid))) {
+ char gid_str[INET6_ADDRSTRLEN];
+ mlid = existed_mlid;
+ OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
+ "found existed mlid 0x%04x for mgid %s\n",
+ cl_ntoh16(mlid), inet_ntop(AF_INET6, p_mgid->raw,
+ gid_str, sizeof gid_str));
+ }
+
/* create a new MC Group */
*pp_mgrp = osm_mgrp_new(mlid);
if (*pp_mgrp == NULL) {
@@ -914,25 +927,26 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
/* Insert the new group in the data base */
- /* since we might have an old group by that mlid
- one whose deletion was delayed for an idle time
- we need to deallocate it first */
- p_prev_mgrp = osm_get_mgrp_by_mlid(sa->p_subn, mlid);
- if (p_prev_mgrp) {
+
+ p_mgrp_holder = osm_get_mgrp_holder_by_mlid(sa->p_subn, mlid);
+ if (!p_mgrp_holder) {
OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
- "Found previous group for mlid:0x%04x - "
- "Destroying it first\n", cl_ntoh16(mlid));
- sa->p_subn->mgroups[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO] =
- NULL;
- cl_fmap_remove_item(&sa->p_subn->mgrp_mgid_tbl,
- &p_prev_mgrp->map_item);
- osm_mgrp_delete(p_prev_mgrp);
+ "Creating new mgrp_holder for mlid:0x%04x\n",
+ cl_ntoh16(mlid));
+ p_mgrp_holder = osm_mgrp_holder_new(sa->p_subn, mlid);
}
+ if (!p_mgrp_holder) {
+ OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B08: "
+ "osm_mgrp_holder_new failed\n");
+ free_mlid(sa, mlid);
+ status = IB_INSUFFICIENT_MEMORY;
+ goto Exit;
+ }
cl_fmap_insert(&sa->p_subn->mgrp_mgid_tbl,
&(*pp_mgrp)->mcmember_rec.mgid, &(*pp_mgrp)->map_item);
- sa->p_subn->mgroups[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO] = *pp_mgrp;
+ osm_mgrp_holder_add_mgrp(p_mgrp_holder, *pp_mgrp, sa->p_log);
Exit:
OSM_LOG_EXIT(sa->p_log);
@@ -1074,7 +1088,7 @@ static void mcmr_rcv_leave_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
CL_PLOCK_RELEASE(sa->p_lock);
/* we can leave if port was deleted from MCG */
- if (removed && osm_sm_mcgrp_leave(sa->sm, mlid, portguid))
+ if (removed && osm_sm_mcgrp_leave(sa->sm, p_mgrp, portguid))
OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B09: "
"osm_sm_mcgrp_leave failed\n");
@@ -1102,6 +1116,7 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
osm_physp_t *p_request_physp;
uint8_t is_new_group; /* TRUE = there is a need to create a group */
uint8_t join_state;
+ osm_mgrp_holder_t *p_mgrp_holder;
OSM_LOG_ENTER(sa->p_log);
@@ -1275,6 +1290,8 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
goto Exit;
}
+ p_mgrp_holder = osm_get_mgrp_holder_by_mlid(sa->p_subn, mlid);
+ CL_ASSERT(p_mgrp_holder);
/* create or update existing port (join-state will be updated) */
status = add_new_mgrp_port(sa, p_mgrp, p_recvd_mcmember_rec,
osm_madw_get_mad_addr_ptr(p_madw),
@@ -1282,6 +1299,8 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
if (status != IB_SUCCESS) {
/* we fail to add the port so we might need to delete the group */
+ osm_mgrp_holder_port_delete_mgrp(p_mgrp_holder, p_mgrp,
+ p_recvd_mcmember_rec->port_gid.unicast.interface_id);
cleanup_mgrp(sa, p_mgrp);
CL_PLOCK_RELEASE(sa->p_lock);
@@ -1304,7 +1323,7 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
/* do the actual routing (actually schedule the update) */
status = osm_sm_mcgrp_join(sa->sm, mlid,
p_recvd_mcmember_rec->port_gid.unicast.
- interface_id);
+ interface_id, &p_recvd_mcmember_rec->mgid);
if (status != IB_SUCCESS) {
OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B14: "
@@ -1315,9 +1334,10 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
CL_PLOCK_EXCL_ACQUIRE(sa->p_lock);
/* the request for routing failed so we need to remove the port */
+ osm_mgrp_holder_port_delete_mgrp(p_mgrp_holder, p_mgrp,
+ p_recvd_mcmember_rec->port_gid.unicast.interface_id);
osm_mgrp_delete_port(sa->p_subn, sa->p_log, p_mgrp,
- p_recvd_mcmember_rec->port_gid.
- unicast.interface_id);
+ p_recvd_mcmember_rec->port_gid.unicast.interface_id);
cleanup_mgrp(sa, p_mgrp);
CL_PLOCK_RELEASE(sa->p_lock);
osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
@@ -1549,7 +1569,6 @@ static void mcmr_query_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
osm_physp_t *p_req_physp;
boolean_t trusted_req;
osm_mgrp_t *p_mgrp;
- int i;
OSM_LOG_ENTER(sa->p_log);
@@ -1578,12 +1597,11 @@ static void mcmr_query_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
CL_PLOCK_ACQUIRE(sa->p_lock);
/* simply go over all MCGs and match */
- for (i = 0; i <= sa->p_subn->max_mcast_lid_ho - IB_LID_MCAST_START_HO;
- i++) {
- p_mgrp = sa->p_subn->mgroups[i];
- if (p_mgrp)
- mcmr_by_comp_mask(sa, p_rcvd_rec, comp_mask, p_mgrp,
- p_req_physp, trusted_req, &rec_list);
+ p_mgrp = (osm_mgrp_t *) cl_fmap_head(&sa->p_subn->mgrp_mgid_tbl);
+ while (p_mgrp != (osm_mgrp_t *) cl_fmap_end(&sa->p_subn->mgrp_mgid_tbl)) {
+ mcmr_by_comp_mask(sa, p_rcvd_rec, comp_mask, p_mgrp,
+ p_req_physp, trusted_req, &rec_list);
+ p_mgrp = (osm_mgrp_t *) cl_fmap_next(&p_mgrp->map_item);
}
CL_PLOCK_RELEASE(sa->p_lock);
diff --git a/opensm/opensm/osm_sa_path_record.c b/opensm/opensm/osm_sa_path_record.c
index 75d9516..aa63d78 100644
--- a/opensm/opensm/osm_sa_path_record.c
+++ b/opensm/opensm/osm_sa_path_record.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-2006 Mellanox Technologies LTD. All rights reserved.
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
@@ -1468,11 +1468,14 @@ static osm_mgrp_t *pr_get_mgrp(IN osm_sa_t * sa, IN const osm_madw_t * p_madw)
mgrp = NULL;
goto Exit;
}
- } else
- if (!(mgrp = osm_get_mgrp_by_mlid(sa->p_subn, p_pr->dlid)))
- OSM_LOG(sa->p_log, OSM_LOG_ERROR,
- "ERR 1F11: " "No MC group found for PathRecord "
+ } else {
+ mgrp = osm_get_mgrp_by_mgid(sa, &p_pr->dgid);
+ if (!mgrp)
+ OSM_LOG(sa->p_log, OSM_LOG_ERROR,
+ "ERR 1F11: "
+ "No MC group found for PathRecord "
"destination LID 0x%x\n", p_pr->dlid);
+ }
}
Exit:
diff --git a/opensm/opensm/osm_sm.c b/opensm/opensm/osm_sm.c
index b3ce69a..d990450 100644
--- a/opensm/opensm/osm_sm.c
+++ b/opensm/opensm/osm_sm.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.
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
@@ -47,6 +47,7 @@
#include <stdlib.h>
#include <string.h>
+#include <arpa/inet.h>
#include <iba/ib_types.h>
#include <complib/cl_qmap.h>
#include <complib/cl_passivelock.h>
@@ -468,12 +469,15 @@ static ib_api_status_t sm_mgrp_process(IN osm_sm_t * p_sm,
/**********************************************************************
**********************************************************************/
ib_api_status_t osm_sm_mcgrp_join(IN osm_sm_t * p_sm, IN const ib_net16_t mlid,
- IN const ib_net64_t port_guid)
+ IN const ib_net64_t port_guid,
+ IN const ib_gid_t * p_mgid)
{
- osm_mgrp_t *p_mgrp;
+ osm_mgrp_t *p_mgrp = NULL;
osm_port_t *p_port;
ib_api_status_t status = IB_SUCCESS;
osm_mcm_info_t *p_mcm;
+ cl_list_item_t *p_item;
+ osm_mgrp_holder_t *p_mgrp_holder;
OSM_LOG_ENTER(p_sm->p_log);
@@ -497,8 +501,44 @@ ib_api_status_t osm_sm_mcgrp_join(IN osm_sm_t * p_sm, IN const ib_net16_t mlid,
/*
* If this multicast group does not already exist, create it.
*/
- p_mgrp = osm_get_mgrp_by_mlid(p_sm->p_subn, mlid);
- if (!p_mgrp || !osm_mgrp_is_guid(p_mgrp, port_guid)) {
+ p_mgrp_holder = osm_get_mgrp_holder_by_mlid(p_sm->p_subn, mlid);
+ if (p_mgrp_holder) {
+ char gid_str[INET6_ADDRSTRLEN];
+ if (TRUE) {
+ size_t gr_count = cl_qlist_count(&p_mgrp_holder->mgrp_list);
+ OSM_LOG(p_sm->p_log, OSM_LOG_DEBUG,
+ "mlid 0x%X has %lu mgroups\n", cl_ntoh16(mlid), gr_count);
+ if (gr_count) {
+ p_item =
+ cl_qlist_head(&p_mgrp_holder->mgrp_list);
+ while (p_item !=
+ cl_qlist_end(&p_mgrp_holder->mgrp_list)) {
+ p_mgrp = (osm_mgrp_t *)
+ PARENT_STRUCT(p_item, osm_mgrp_t,
+ mlid_item);
+ OSM_LOG(p_sm->p_log, OSM_LOG_DEBUG,
+ "mlid 0x%X has mgrp with MGID: %s\n",
+ cl_ntoh16(mlid),
+ inet_ntop(AF_INET6,
+ p_mgrp->mcmember_rec.
+ mgid.raw, gid_str,
+ sizeof gid_str));
+ p_item = cl_qlist_next(p_item);
+ }
+ }
+ }
+ p_mgrp = (osm_mgrp_t *)cl_fmap_get(&p_sm->p_subn->mgrp_mgid_tbl, p_mgid);
+ if (p_mgrp == (osm_mgrp_t *)cl_fmap_end(&p_sm->p_subn->mgrp_mgid_tbl)) {
+ p_mgrp = NULL;
+ OSM_LOG(p_sm->p_log, OSM_LOG_ERROR,
+ "group with MGID: %s not found on mlid 0x%X\n",
+ inet_ntop(AF_INET6,
+ p_mgid->raw,
+ gid_str, sizeof gid_str),
+ cl_ntoh16(mlid));
+ }
+ }
+ if (!p_mgrp_holder || !p_mgrp || !osm_mgrp_is_guid(p_mgrp, port_guid)) {
/*
* The group removed or the port is not a
* member of the group, then fail immediately.
@@ -513,6 +553,22 @@ ib_api_status_t osm_sm_mcgrp_join(IN osm_sm_t * p_sm, IN const ib_net16_t mlid,
goto Exit;
}
+ /* if there was no change from the last time
+ * we processed the group we can skip doing anything
+ */
+ if (p_mgrp_holder->last_change_id == p_mgrp_holder->last_tree_id) {
+ OSM_LOG(p_sm->p_log, OSM_LOG_VERBOSE,
+ "Skip processing mgrp holder with lid:0x%X last change id:%u\n",
+ cl_ntoh16(mlid), p_mgrp_holder->last_change_id);
+ goto Exit;
+ } else {
+ OSM_LOG(p_sm->p_log, OSM_LOG_DEBUG,
+ "processing mgrp holder with lid:0x%X port: 0x%016"
+ PRIx64 " last change id:%u tree id:%u\n",
+ cl_ntoh16(mlid), cl_ntoh64(port_guid),
+ p_mgrp_holder->last_change_id,
+ p_mgrp_holder->last_tree_id);
+ }
/*
* Check if the object (according to mlid) already exists on this port.
* If it does - then no need to update it again, and no need to
@@ -549,12 +605,13 @@ Exit:
/**********************************************************************
**********************************************************************/
-ib_api_status_t osm_sm_mcgrp_leave(IN osm_sm_t * p_sm, IN const ib_net16_t mlid,
+ib_api_status_t osm_sm_mcgrp_leave(IN osm_sm_t * p_sm, IN osm_mgrp_t * p_mgrp,
IN const ib_net64_t port_guid)
{
- osm_mgrp_t *p_mgrp;
osm_port_t *p_port;
ib_api_status_t status;
+ osm_mgrp_holder_t *p_mgrp_holder;
+ ib_net16_t mlid = p_mgrp->mlid;
OSM_LOG_ENTER(p_sm->p_log);
@@ -577,21 +634,25 @@ ib_api_status_t osm_sm_mcgrp_leave(IN osm_sm_t * p_sm, IN const ib_net16_t mlid,
}
/*
- * Get the multicast group object for this group.
+ * Get the multicast group holder object for this group.
*/
- p_mgrp = osm_get_mgrp_by_mlid(p_sm->p_subn, mlid);
- if (!p_mgrp) {
+ p_mgrp_holder = osm_get_mgrp_holder_by_mlid(p_sm->p_subn, mlid);
+ if (!p_mgrp_holder) {
OSM_LOG(p_sm->p_log, OSM_LOG_ERROR, "ERR 2E08: "
"No multicast group for MLID 0x%X\n", cl_ntoh16(mlid));
status = IB_INVALID_PARAMETER;
goto Exit;
}
+ osm_mgrp_holder_port_delete_mgrp(p_mgrp_holder, p_mgrp, port_guid);
/*
* Walk the list of ports in the group, and remove the appropriate one.
*/
osm_port_remove_mgrp(p_port, mlid);
+ OSM_LOG(p_sm->p_log, OSM_LOG_DEBUG,
+ " Calling sm_mgrp_process for mgrp with mlid = 0x%X\n",
+ cl_ntoh16(mlid));
status = sm_mgrp_process(p_sm, p_mgrp);
Exit:
CL_PLOCK_RELEASE(p_sm->p_lock);
diff --git a/opensm/opensm/osm_subnet.c b/opensm/opensm/osm_subnet.c
index 0d11811..6ed95d4 100644
--- a/opensm/opensm/osm_subnet.c
+++ b/opensm/opensm/osm_subnet.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-2008 Mellanox Technologies LTD. All rights reserved.
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
@@ -428,8 +428,9 @@ void osm_subn_destroy(IN osm_subn_t * const p_subn)
osm_switch_t *p_sw, *p_next_sw;
osm_remote_sm_t *p_rsm, *p_next_rsm;
osm_prtn_t *p_prtn, *p_next_prtn;
- osm_mgrp_t *p_mgrp;
+ osm_mgrp_holder_t *p_mgrp_holder;
osm_infr_t *p_infr, *p_next_infr;
+ osm_mgrp_t *p_mgrp;
/* it might be a good idea to de-allocate all known objects */
p_next_node = (osm_node_t *) cl_qmap_head(&p_subn->node_guid_tbl);
@@ -471,14 +472,20 @@ void osm_subn_destroy(IN osm_subn_t * const p_subn)
osm_prtn_delete(&p_prtn);
}
- cl_fmap_remove_all(&p_subn->mgrp_mgid_tbl);
for (i = 0; i <= p_subn->max_mcast_lid_ho - IB_LID_MCAST_START_HO;
i++) {
- p_mgrp = p_subn->mgroups[i];
- p_subn->mgroups[i] = NULL;
- if (p_mgrp)
- osm_mgrp_delete(p_mgrp);
+ p_mgrp_holder = p_subn->mgroup_holders[i];
+ if (p_mgrp_holder){
+ osm_mgrp_holder_delete(p_subn, p_mgrp_holder->mlid);
+ }
+ }
+
+ p_mgrp = (osm_mgrp_t*)cl_fmap_head(&p_subn->mgrp_mgid_tbl);
+ while (p_mgrp != (osm_mgrp_t*)cl_fmap_end(&p_subn->mgrp_mgid_tbl)) {
+ cl_fmap_remove_item(&p_subn->mgrp_mgid_tbl, (cl_fmap_item_t*)p_mgrp);
+ osm_mgrp_delete(p_mgrp);
+ p_mgrp = (osm_mgrp_t*)cl_fmap_head(&p_subn->mgrp_mgid_tbl);
}
p_next_infr = (osm_infr_t *) cl_qlist_head(&p_subn->sa_infr_list);
@@ -1646,3 +1653,13 @@ int osm_subn_write_conf_file(char *file_name, IN osm_subn_opt_t *const p_opts)
return 0;
}
+
+ib_net16_t osm_mgrp_holder_get_mlid_by_mgid(IN osm_subn_t const *p_subn,
+ IN const ib_gid_t * const p_mgid)
+{
+ osm_mgrp_t *p_mgrp = (osm_mgrp_t*)cl_fmap_get(&p_subn->mgrp_mgid_tbl, p_mgid);
+ if (p_mgrp != (osm_mgrp_t*)cl_fmap_end(&p_subn->mgrp_mgid_tbl)) {
+ return p_mgrp->mlid;
+ }
+ return 0;
+}
--
1.6.3.3
More information about the general
mailing list