[ofa-general] [PATCH 1/2 v4] opensm: Storage organization for multicast groups
Slava Strebkov
slavas at Voltaire.COM
Tue Sep 29 06:53:18 PDT 2009
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 box.
2.mgrp_box 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_box has a map of ports sharing same mlid. Ports sorted
by port guid. Port map is necessary for building spanning
tree per mgroup_box, 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_box object instead
of mgroup.
Signed-off-by: Slava Strebkov <slavas at voltaire.com>
---
opensm/include/opensm/osm_multicast.h | 130 ++++++++++++++++++++++++++++++--
opensm/include/opensm/osm_subnet.h | 49 ++++++++++---
opensm/opensm/osm_drop_mgr.c | 2 +-
opensm/opensm/osm_mcast_mgr.c | 110 +++++++++++++--------------
opensm/opensm/osm_multicast.c | 108 ++++++++++++++++++++++++--
opensm/opensm/osm_qos_policy.c | 39 ++++++----
opensm/opensm/osm_sa.c | 32 +++-----
opensm/opensm/osm_sa_mcmember_record.c | 53 ++++++++++---
opensm/opensm/osm_sa_path_record.c | 32 ++++++--
opensm/opensm/osm_subnet.c | 33 +++++++--
10 files changed, 440 insertions(+), 148 deletions(-)
diff --git a/opensm/include/opensm/osm_multicast.h b/opensm/include/opensm/osm_multicast.h
index 32bcb78..d4daf4b 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.
*
@@ -97,8 +97,8 @@ BEGIN_C_DECLS
*/
typedef struct osm_mgrp {
cl_fmap_item_t map_item;
+ cl_list_item_t box_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;
@@ -109,15 +109,13 @@ typedef struct osm_mgrp {
* map_item
* Map Item for fmap linkage. Must be first element!!
*
+* box_item
+* List Item for the group in mgroup box
+*
* mlid
* 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.
-*
* mcm_port_tbl
* Table (sorted by port GUID) of osm_mcm_port_t objects
* representing the member ports of this multicast group.
@@ -133,6 +131,71 @@ typedef struct osm_mgrp {
* SEE ALSO
*********/
+/****s* OpenSM: Multicast Group Holder/osm_mgrp_box_t
+* NAME
+* osm_mgrp_box_t
+*
+* DESCRIPTION
+* Holder for mgroups.
+*
+* The osm_mgrp_box_t object should be treated as opaque and should
+* be manipulated only through the provided functions.
+*
+* SYNOPSIS
+*/
+typedef struct osm_mgrp_box {
+ cl_qmap_t mgrp_port_map;
+ cl_qlist_t mgrp_list;
+ ib_net16_t mlid;
+ osm_mtree_node_t *p_root;
+} osm_mgrp_box_t;
+/*
+* FIELDS
+* mgrp_port_map
+* Map sorted by GUID of osm_mgrp_port_t objects represents
+* ports to be routed with same mlid
+*
+* mgrp_list
+* List of mgroups having same mlid
+*
+* mlid
+* 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.
+*
+* SEE ALSO
+*********/
+/****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;
+ unsigned num_groups;
+ osm_port_t *p_port;
+} osm_mgrp_port_t;
+/*
+* FIELDS
+* guid_item
+* Map for ports. Must be first element
+*
+* num_mgroups
+* Number of mgroups opened by this port
+*
+* p_mcm_port
+* pointer to osm_mcm_port_t object
+*
+*/
/****f* OpenSM: Multicast Group/osm_mgrp_new
* NAME
* osm_mgrp_new
@@ -382,5 +445,58 @@ void osm_mgrp_remove_port(osm_subn_t * subn, osm_log_t * log, osm_mgrp_t * mgrp,
osm_mcm_port_t * mcm_port, ib_member_rec_t * mcmr);
void osm_mgrp_cleanup(osm_subn_t * subn, osm_mgrp_t * mpgr);
+/****f* OpenSM: Multicast Group Box /osm_mgrp_box_new
+* NAME
+* osm_mgrp_box_new
+*
+* DESCRIPTION
+* Allocates and initializes a Multicast Group Box for use.
+*
+* SYNOPSIS
+*/
+osm_mgrp_box_t *osm_mgrp_box_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 box.
+*
+* RETURN VALUES
+* pointer to initialized osm_mgrp_box_t
+* or NULL, if unsuccessful
+*
+* SEE ALSO
+* Multicast Group Box, osm_mgrp_box_delete
+*********/
+/****f* OpenSM: Multicast Group Box /osm_mgrp_box_delete
+* NAME
+* osm_mgrp_box_delete
+*
+* DESCRIPTION
+* Removes entry from array of boxes
+* Removes port from mgroup port list
+*
+* SYNOPSIS
+*/
+void osm_mgrp_box_delete(IN osm_subn_t * p_subn,
+ IN ib_net16_t mlid);
+/*
+* PARAMETERS
+* p_subn
+* [in] Pointer to osm_subnet
+*
+* mlid
+* [in] box's mlid
+*
+* RETURN VALUES
+* None.
+*
+* NOTES
+*
+* SEE ALSO
+*
+*********/
END_C_DECLS
#endif /* _OSM_MULTICAST_H_ */
diff --git a/opensm/include/opensm/osm_subnet.h b/opensm/include/opensm/osm_subnet.h
index 6c20de8..fe4695f 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.
@@ -69,6 +69,7 @@ BEGIN_C_DECLS
#define OSM_SUBNET_VECTOR_CAPACITY 256
struct osm_opensm;
struct osm_qos_policy;
+struct osm_mgrp_box;
/****h* OpenSM/Subnet
* NAME
@@ -513,7 +514,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 *mboxes[IB_LID_MCAST_END_HO - IB_LID_MCAST_START_HO + 1];
} osm_subn_t;
/*
* FIELDS
@@ -634,8 +635,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.
+* mboxes
+* Array of pointers to all Multicast Group Box objects in the subnet.
* Indexed by MLID offset from base MLID.
*
* SEE ALSO
@@ -935,21 +936,21 @@ 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: Subnet/osm_get_mgrp_box_by_mlid
* NAME
-* osm_get_mgrp_by_mlid
+* osm_get_mgrp_box_by_mlid
*
* DESCRIPTION
-* The looks for the given multicast group in the subnet table by mlid.
+* The looks for the given multicast group box 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 *osm_get_mgrp_by_mlid(osm_subn_t const *p_subn, ib_net16_t mlid)
+struct osm_mgrp_box *osm_get_mgrp_box_by_mlid(osm_subn_t const *p_subn, ib_net16_t mlid)
{
- return p_subn->mgroups[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO];
+ return p_subn->mboxes[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO];
}
/*
* PARAMETERS
@@ -960,7 +961,7 @@ struct osm_mgrp *osm_get_mgrp_by_mlid(osm_subn_t const *p_subn, ib_net16_t mlid)
* [in] The multicast group mlid in network order
*
* RETURN VALUES
-* The multicast group structure pointer if found. NULL otherwise.
+* The multicast group box structure pointer if found. NULL otherwise.
*********/
/****f* OpenSM: Helper/osm_get_physp_by_mad_addr
@@ -1116,5 +1117,33 @@ int osm_subn_write_conf_file(char *file_name, IN osm_subn_opt_t * const p_opt);
*********/
int osm_subn_verify_config(osm_subn_opt_t * const p_opt);
+ib_net16_t osm_mgrp_box_get_mlid(IN struct osm_mgrp_box *p_mgrp_box);
+
+/****f* OpenSM: Subnet/osm_mgrp_box_get_mlid_by_mgid
+* NAME
+* osm_mgrp_box_get_mlid_by_mgid
+*
+* DESCRIPTION
+* The looks for multicast group by mgid. Returns mlid of found group
+* or 0 if no group found.
+* NOTE: this code is not thread safe. Need to grab the lock before
+* calling it.
+*
+* SYNOPSIS
+*/
+ib_net16_t osm_mgrp_box_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
+*
+* p_mgid
+* [in] Pointer to multicast group mgid
+*
+* RETURN VALUES
+* The multicast group mlid if found. 0 otherwise.
+*********/
+
END_C_DECLS
#endif /* _OSM_SUBNET_H_ */
diff --git a/opensm/opensm/osm_drop_mgr.c b/opensm/opensm/osm_drop_mgr.c
index 4f98cc9..c86ee72 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.
diff --git a/opensm/opensm/osm_mcast_mgr.c b/opensm/opensm/osm_mcast_mgr.c
index 3894677..4fbae91 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-2009 Mellanox Technologies LTD. All rights reserved.
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
* Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
@@ -111,14 +111,14 @@ 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_box_t * p_mgrp_box)
{
OSM_LOG_ENTER(sm->p_log);
- if (p_mgrp->p_root)
- mcast_mgr_purge_tree_node(p_mgrp->p_root);
+ if (p_mgrp_box->p_root)
+ mcast_mgr_purge_tree_node(p_mgrp_box->p_root);
- p_mgrp->p_root = NULL;
+ p_mgrp_box->p_root = NULL;
OSM_LOG_EXIT(sm->p_log);
}
@@ -126,28 +126,26 @@ 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_box_t * p_mgrp_box,
const osm_switch_t * p_sw)
{
float avg_hops = 0;
uint32_t hops = 0;
uint32_t num_ports = 0;
- const osm_mcm_port_t *p_mcm_port;
- const cl_qmap_t *p_mcm_tbl;
+ const osm_mgrp_port_t *p_box_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)) {
- hops += osm_switch_get_port_least_hops(p_sw, p_mcm_port->port);
+ for (p_box_port = (osm_mgrp_port_t *) cl_qmap_head(&p_mgrp_box->mgrp_port_map);
+ p_box_port != (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_box->mgrp_port_map);
+ p_box_port =
+ (osm_mgrp_port_t *) cl_qmap_next(&p_box_port->guid_item)) {
+ hops += osm_switch_get_port_least_hops(p_sw, p_box_port->p_port);
num_ports++;
}
@@ -168,27 +166,27 @@ 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_box_t * p_mgrp_box,
const osm_switch_t * p_sw)
{
uint32_t max_hops = 0;
uint32_t hops = 0;
- const osm_mcm_port_t *p_mcm_port;
- const cl_qmap_t *p_mcm_tbl;
+ const osm_mgrp_port_t *p_box_port;
+ const cl_qmap_t *p_box_port_tbl;
OSM_LOG_ENTER(sm->p_log);
- p_mcm_tbl = &p_mgrp->mcm_port_tbl;
+ p_box_port_tbl = &p_mgrp_box->mgrp_port_map;
/*
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)) {
- hops = osm_switch_get_port_least_hops(p_sw, p_mcm_port->port);
+ for (p_box_port = (osm_mgrp_port_t *) cl_qmap_head(p_box_port_tbl);
+ p_box_port != (osm_mgrp_port_t *) cl_qmap_end(p_box_port_tbl);
+ p_box_port =
+ (osm_mgrp_port_t *) cl_qmap_next(&p_box_port->guid_item)) {
+ hops = osm_switch_get_port_least_hops(p_sw, p_box_port->p_port);
if (hops > max_hops)
max_hops = hops;
}
@@ -210,7 +208,7 @@ 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_box_t * p_mgrp_box)
{
cl_qmap_t *p_sw_tbl;
const osm_switch_t *p_sw;
@@ -227,7 +225,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_is_empty(p_mgrp_box));
for (p_sw = (osm_switch_t *) cl_qmap_head(p_sw_tbl);
p_sw != (osm_switch_t *) cl_qmap_end(p_sw_tbl);
@@ -236,9 +234,9 @@ 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_box, 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_box, p_sw);
OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
"Switch 0x%016" PRIx64 ", hops = %f\n",
@@ -267,7 +265,7 @@ 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_box_t * p_mgrp_box)
{
const osm_switch_t *p_sw = NULL;
@@ -279,7 +277,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_box);
OSM_LOG_EXIT(sm->p_log);
return (osm_switch_t *) p_sw;
@@ -354,7 +352,7 @@ static int mcast_mgr_set_mft_block(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_box_t * p_mgrp_box,
osm_switch_t * p_sw, cl_qlist_t * p_list,
cl_qlist_t * list_array, uint8_t array_size)
{
@@ -365,7 +363,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_box_get_mlid(p_mgrp_box));
/*
For Multicast Groups, we want not to count on previous
@@ -455,7 +453,7 @@ 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_box_t * p_mgrp_box,
osm_switch_t * p_sw,
cl_qlist_t * p_list, uint8_t depth,
uint8_t upstream_port,
@@ -481,7 +479,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_box_get_mlid(p_mgrp_box));
OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
"Routing MLID 0x%X through switch 0x%" PRIx64
@@ -558,7 +556,7 @@ 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_box, p_sw, p_list, list_array, max_children);
p_tbl = osm_switch_get_mcast_tbl_ptr(p_sw);
@@ -641,7 +639,7 @@ 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,
+ mcast_mgr_branch(sm, p_mgrp_box, p_remote_node->sw,
p_port_list, depth,
osm_physp_get_port_num
(p_remote_physp), p_max_depth);
@@ -677,11 +675,10 @@ Exit:
/**********************************************************************
**********************************************************************/
static ib_api_status_t mcast_mgr_build_spanning_tree(osm_sm_t * sm,
- osm_mgrp_t * p_mgrp)
+ osm_mgrp_box_t * p_mgrp_box)
{
- const cl_qmap_t *p_mcm_tbl;
- const osm_mcm_port_t *p_mcm_port;
uint32_t num_ports;
+ const osm_mgrp_port_t *p_mgrp_port;
cl_qlist_t port_list;
osm_switch_t *p_sw;
osm_mcast_work_obj_t *p_wobj;
@@ -699,14 +696,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_box);
- p_mcm_tbl = &p_mgrp->mcm_port_tbl;
- num_ports = cl_qmap_count(p_mcm_tbl);
+ num_ports = cl_qmap_count(&p_mgrp_box->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_box_get_mlid(p_mgrp_box)));
goto Exit;
}
@@ -726,11 +722,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_box);
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_box_get_mlid(p_mgrp_box)));
status = IB_ERROR;
goto Exit;
}
@@ -738,20 +734,20 @@ 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_box->mgrp_port_map);
+ p_mgrp_port != (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_box->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_wobj = mcast_work_obj_new(p_mcm_port->port);
+ p_wobj = mcast_work_obj_new(p_mgrp_port->p_port);
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_mcm_port->port)));
+ cl_ntoh64(p_mgrp_port->p_port->guid));
continue;
}
@@ -759,12 +755,12 @@ 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,
+ p_mgrp_box->p_root = mcast_mgr_branch(sm, p_mgrp_box, 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_box_get_mlid(p_mgrp_box)), count, max_depth);
Exit:
OSM_LOG_EXIT(sm->p_log);
@@ -971,7 +967,7 @@ Exit:
static ib_api_status_t mcast_mgr_process_mlid(osm_sm_t * sm, uint16_t mlid)
{
ib_api_status_t status = IB_SUCCESS;
- osm_mgrp_t *mgrp;
+ osm_mgrp_box_t *p_mgrp_box;
OSM_LOG_ENTER(sm->p_log);
@@ -983,9 +979,9 @@ static ib_api_status_t mcast_mgr_process_mlid(osm_sm_t * sm, uint16_t mlid)
port in the group. */
mcast_mgr_clear(sm, mlid);
- mgrp = osm_get_mgrp_by_mlid(sm->p_subn, cl_hton16(mlid));
- if (mgrp) {
- status = mcast_mgr_build_spanning_tree(sm, mgrp);
+ p_mgrp_box = osm_get_mgrp_box_by_mlid(sm->p_subn, cl_hton16(mlid));
+ if (p_mgrp_box) {
+ status = mcast_mgr_build_spanning_tree(sm, p_mgrp_box);
if (status != IB_SUCCESS)
OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A17: "
"Unable to create spanning tree (%s) for mlid "
@@ -1065,7 +1061,7 @@ int osm_mcast_mgr_process(osm_sm_t * sm)
for (i = 0; i <= sm->p_subn->max_mcast_lid_ho - IB_LID_MCAST_START_HO;
i++)
- if (sm->p_subn->mgroups[i] || sm->mlids_req[i])
+ if (sm->p_subn->mboxes[i] || sm->mlids_req[i])
mcast_mgr_process_mlid(sm, i + IB_LID_MCAST_START_HO);
memset(sm->mlids_req, 0, sm->mlids_req_max);
diff --git a/opensm/opensm/osm_multicast.c b/opensm/opensm/osm_multicast.c
index 5a10003..01c90d8 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.
*
@@ -51,6 +51,18 @@
#include <opensm/osm_inform.h>
#include <opensm/osm_opensm.h>
+static osm_mgrp_port_t *osm_mgrp_port_new(osm_port_t *p_port)
+{
+ 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->p_port = p_port;
+ return p_mgrp_port;
+}
+
/**********************************************************************
**********************************************************************/
void osm_mgrp_delete(IN osm_mgrp_t * p_mgrp)
@@ -69,8 +81,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);
}
@@ -99,8 +109,6 @@ void osm_mgrp_cleanup(osm_subn_t * subn, osm_mgrp_t * mgrp)
if (mgrp->full_members)
return;
- osm_mtree_destroy(mgrp->p_root);
- mgrp->p_root = NULL;
while (cl_qmap_count(&mgrp->mcm_port_tbl)) {
mcm_port = (osm_mcm_port_t *)cl_qmap_head(&mgrp->mcm_port_tbl);
@@ -114,7 +122,6 @@ void osm_mgrp_cleanup(osm_subn_t * subn, osm_mgrp_t * mgrp)
return;
cl_fmap_remove_item(&subn->mgrp_mgid_tbl, &mgrp->map_item);
- subn->mgroups[cl_ntoh16(mgrp->mlid) - IB_LID_MCAST_START_HO] = NULL;
free(mgrp);
}
@@ -157,6 +164,7 @@ osm_mcm_port_t *osm_mgrp_add_port(IN osm_subn_t * subn, osm_log_t * log,
cl_map_item_t *prev_item;
uint8_t prev_join_state = 0, join_state = mcmr->scope_state;
uint8_t prev_scope;
+ osm_mgrp_box_t *p_mgrp_box;
if (osm_log_is_active(log, OSM_LOG_VERBOSE)) {
char gid_str[INET6_ADDRSTRLEN];
@@ -193,7 +201,20 @@ osm_mcm_port_t *osm_mgrp_add_port(IN osm_subn_t * subn, osm_log_t * log,
prev_join_state | join_state);
} else {
cl_qlist_insert_tail(&port->mcm_list, &mcm_port->list_item);
- osm_sm_reroute_mlid(&subn->p_osm->sm, mgrp->mlid);
+ p_mgrp_box = osm_get_mgrp_box_by_mlid(subn, mgrp->mlid);
+ osm_mgrp_port_t *p_mgrp_port = (osm_mgrp_port_t *)
+ cl_qmap_get(&p_mgrp_box->mgrp_port_map, ib_gid_get_guid(&mcm_port->port_gid));
+ if (p_mgrp_port ==
+ (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_box->mgrp_port_map)) {
+ /* new port to mlid */
+ p_mgrp_port = osm_mgrp_port_new(mcm_port->port);
+ if (!p_mgrp_port) {
+ return NULL;
+ }
+ cl_qmap_insert(&p_mgrp_box->mgrp_port_map,
+ ib_gid_get_guid(&mcm_port->port_gid), &p_mgrp_port->guid_item);
+ }
+ osm_sm_reroute_mlid(&subn->p_osm->sm, p_mgrp_box->mlid);
}
/* o15.0.1.11: copy the join state */
@@ -214,6 +235,7 @@ void osm_mgrp_remove_port(osm_subn_t * subn, osm_log_t * log, osm_mgrp_t * mgrp,
{
uint8_t join_state = mcmr->scope_state & 0xf;
uint8_t port_join_state, new_join_state;
+ osm_mgrp_box_t *p_mgrp_box;
/*
* according to the same o15-0.1.14 we get the stored
@@ -222,6 +244,7 @@ void osm_mgrp_remove_port(osm_subn_t * subn, osm_log_t * log, osm_mgrp_t * mgrp,
*/
port_join_state = mcm_port->scope_state & 0x0F;
new_join_state = port_join_state & ~join_state;
+ p_mgrp_box = osm_get_mgrp_box_by_mlid(subn, mgrp->mlid);
if (osm_log_is_active(log, OSM_LOG_VERBOSE)) {
char gid_str[INET6_ADDRSTRLEN];
@@ -242,14 +265,27 @@ void osm_mgrp_remove_port(osm_subn_t * subn, osm_log_t * log, osm_mgrp_t * mgrp,
port_join_state, new_join_state);
mcmr->scope_state = mcm_port->scope_state;
} else {
+ osm_mgrp_port_t *p_mgrp_port;
mcmr->scope_state = mcm_port->scope_state;
OSM_LOG(log, OSM_LOG_DEBUG, "removing port 0x%" PRIx64 "\n",
cl_ntoh64(mcm_port->port->guid));
cl_qmap_remove_item(&mgrp->mcm_port_tbl, &mcm_port->map_item);
cl_qlist_remove_item(&mcm_port->port->mcm_list,
&mcm_port->list_item);
+ p_mgrp_port = (osm_mgrp_port_t *)
+ cl_qmap_get(&p_mgrp_box->mgrp_port_map, mcm_port->port->guid);
+ if (p_mgrp_port !=
+ (osm_mgrp_port_t *) cl_qmap_end(&p_mgrp_box->mgrp_port_map)) {
+ p_mgrp_port->num_groups--;
+ if (0 == p_mgrp_port->num_groups) {
+ /* No mgroups registered on this port for current mlid */
+ cl_qmap_remove_item(&p_mgrp_box->mgrp_port_map,
+ &p_mgrp_port->guid_item);
+ free(p_mgrp_port);
+ }
+ }
osm_mcm_port_delete(mcm_port);
- osm_sm_reroute_mlid(&subn->p_osm->sm, mgrp->mlid);
+ osm_sm_reroute_mlid(&subn->p_osm->sm, p_mgrp_box->mlid);
}
/* no more full members so the group will be deleted after re-route
@@ -258,6 +294,12 @@ void osm_mgrp_remove_port(osm_subn_t * subn, osm_log_t * log, osm_mgrp_t * mgrp,
!(new_join_state & IB_JOIN_STATE_FULL) &&
--mgrp->full_members == 0) {
mgrp_send_notice(subn, log, mgrp, 67);
+ cl_qlist_remove_item(&p_mgrp_box->mgrp_list, &mgrp->box_item);
+ if (0 == cl_qlist_count(&p_mgrp_box->mgrp_list)) {
+ /* empty mgrp_box */
+ osm_mgrp_box_delete(subn,p_mgrp_box->mlid);
+ }
+
osm_mgrp_cleanup(subn, mgrp);
}
}
@@ -266,8 +308,16 @@ void osm_mgrp_delete_port(osm_subn_t * subn, osm_log_t * log, osm_mgrp_t * mgrp,
ib_net64_t port_guid)
{
ib_member_rec_t mcmrec;
- cl_map_item_t *item = cl_qmap_get(&mgrp->mcm_port_tbl, port_guid);
+ osm_mgrp_box_t *p_mgrp_box;
+ osm_mgrp_port_t *p_mgrp_port;
+ cl_map_item_t *item = cl_qmap_get(&mgrp->mcm_port_tbl, port_guid);
+ p_mgrp_box = osm_get_mgrp_box_by_mlid(subn, mgrp->mlid);
+ p_mgrp_port = (osm_mgrp_port_t *)
+ cl_qmap_remove(&p_mgrp_box->mgrp_port_map, port_guid);
+ if (p_mgrp_port != (osm_mgrp_port_t *)cl_qmap_end(&p_mgrp_box->mgrp_port_map)) {
+ free(p_mgrp_port);
+ }
if (item != cl_qmap_end(&mgrp->mcm_port_tbl)) {
mcmrec.scope_state = 0xf;
osm_mgrp_remove_port(subn, log, mgrp, (osm_mcm_port_t *) item,
@@ -296,3 +346,43 @@ boolean_t osm_mgrp_is_port_present(IN const osm_mgrp_t * p_mgrp,
*pp_mcm_port = NULL;
return FALSE;
}
+
+/**********************************************************************
+ **********************************************************************/
+osm_mgrp_box_t *osm_mgrp_box_new(IN osm_subn_t * p_subn,ib_net16_t mlid)
+{
+ osm_mgrp_box_t *p_mgrp_box;
+ p_mgrp_box =
+ p_subn->mboxes[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO] =
+ (osm_mgrp_box_t *) calloc(1,sizeof(*p_mgrp_box));
+ if (!p_mgrp_box)
+ return NULL;
+ p_mgrp_box->mlid = mlid;
+ cl_qmap_init(&p_mgrp_box->mgrp_port_map);
+ cl_qlist_init(&p_mgrp_box->mgrp_list);
+ return p_mgrp_box;
+}
+
+/**********************************************************************
+ **********************************************************************/
+void osm_mgrp_box_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_box_t *p_mgrp_box =
+ p_subn->mboxes[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO];
+ p_item = cl_qmap_head(&p_mgrp_box->mgrp_port_map);
+ /* Delete ports shared same MLID */
+ while (p_item != cl_qmap_end(&p_mgrp_box->mgrp_port_map)) {
+ p_osm_mgr_port = (osm_mgrp_port_t *) p_item;
+ cl_qmap_remove_item(&p_mgrp_box->mgrp_port_map, p_item);
+ p_item = cl_qmap_head(&p_mgrp_box->mgrp_port_map);
+ free(p_osm_mgr_port);
+ }
+ /* Remove mgrp from this MLID */
+ cl_qlist_remove_all(&p_mgrp_box->mgrp_list);
+ /* Destroy the mtree_node structure */
+ osm_mtree_destroy(p_mgrp_box->p_root);
+ p_subn->mboxes[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO] = NULL;
+ free(p_mgrp_box);
+}
diff --git a/opensm/opensm/osm_qos_policy.c b/opensm/opensm/osm_qos_policy.c
index 9b72293..6c0a1e6 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.
@@ -773,6 +773,8 @@ static void __qos_policy_validate_pkey(
uint32_t flow;
uint8_t hop;
osm_mgrp_t * p_mgrp;
+ osm_mgrp_box_t * p_mgrp_box;
+ cl_list_item_t *p_item;
if (!p_qos_policy || !p_qos_match_rule || !p_prtn)
return;
@@ -796,28 +798,33 @@ 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_box = osm_get_mgrp_box_by_mlid(p_qos_policy->p_subn, p_prtn->mlid);
+ if (!p_mgrp_box) {
OSM_LOG(&p_qos_policy->p_subn->p_osm->log, OSM_LOG_ERROR,
- "ERR AC16: MCast group for partition with "
+ "ERR AC16: MCast group box 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,
- "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 =
+ p_item = cl_qlist_head(&p_mgrp_box->mgrp_list);
+ while (p_item != cl_qlist_end(&p_mgrp_box->mgrp_list)) {
+ p_mgrp = (osm_mgrp_t *) PARENT_STRUCT(p_item, osm_mgrp_t,
+ box_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);
+ }
}
}
diff --git a/opensm/opensm/osm_sa.c b/opensm/opensm/osm_sa.c
index 02737c2..a5d8945 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,18 +706,17 @@ 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,
sa_dump_one_inform, &dump_context);
@@ -740,22 +739,15 @@ 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;
+ osm_mgrp_t *p_mgrp = NULL;
+ cl_fmap_item_t *p_fitem;
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));
- 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;
+ 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;
}
diff --git a/opensm/opensm/osm_sa_mcmember_record.c b/opensm/opensm/osm_sa_mcmember_record.c
index 8f7816b..b39f986 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,12 +121,12 @@ 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_box_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++)
- if (!sa->p_subn->mgroups[i])
+ if (!sa->p_subn->mboxes[i])
return cl_hton16(i + IB_LID_MCAST_START_HO);
return 0;
@@ -730,10 +730,11 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
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_box_t *p_mgrp_box;
ib_api_status_t status = IB_SUCCESS;
ib_member_rec_t mcm_rec = *p_recvd_mcmember_rec; /* copy for modifications */
@@ -811,6 +812,10 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
goto Exit;
}
+ /* check if there is mgrp_box matched to requested mgid */
+ if (0 != (existed_mlid = osm_mgrp_box_get_mlid_by_mgid(sa->p_subn, p_mgid))) {
+ mlid = existed_mlid;
+ }
/* create a new MC Group */
*pp_mgrp = osm_mgrp_new(mlid);
if (*pp_mgrp == NULL) {
@@ -833,11 +838,28 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
(*pp_mgrp)->mcmember_rec.pkt_life &= 0x3f;
(*pp_mgrp)->mcmember_rec.pkt_life |= 2 << 6; /* exactly */
+ /* get mgrp_box for selected mlid */
+ p_mgrp_box = osm_get_mgrp_box_by_mlid(sa->p_subn, mlid);
+ if (!p_mgrp_box) {
+ OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
+ "Creating new mgrp_box for mlid:0x%04x\n",
+ cl_ntoh16(mlid));
+ p_mgrp_box = osm_mgrp_box_new(sa->p_subn, mlid);
+ if (!p_mgrp_box) {
+ OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B08: "
+ "osm_mgrp_box_new failed\n");
+ osm_mgrp_delete(*pp_mgrp);
+ free_mlid(sa, mlid);
+ status = IB_INSUFFICIENT_MEMORY;
+ goto Exit;
+ }
+ }
+
/* Insert the new group in the data base */
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;
-
+ sa->p_subn->mboxes[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO] = p_mgrp_box;
+ cl_qlist_insert_tail(&p_mgrp_box->mgrp_list, &(*pp_mgrp)->box_item);
Exit:
OSM_LOG_EXIT(sa->p_log);
return status;
@@ -1173,6 +1195,13 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
goto Exit;
}
+ if (is_new_group) {
+ osm_mgrp_port_t *p_mgrp_port;
+ osm_mgrp_box_t *p_mgrp_box = osm_get_mgrp_box_by_mlid(sa->p_subn, p_mgrp->mlid);
+ p_mgrp_port = (osm_mgrp_port_t *)
+ cl_qmap_get(&p_mgrp_box->mgrp_port_map, portguid);
+ p_mgrp_port->num_groups++;
+ }
/* Release the lock as we don't need it. */
CL_PLOCK_RELEASE(sa->p_lock);
@@ -1386,7 +1415,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);
@@ -1415,12 +1443,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..6a63092 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.
@@ -1433,12 +1433,13 @@ static void pr_rcv_process_pair(IN osm_sa_t * sa, IN const osm_madw_t * p_madw,
/**********************************************************************
**********************************************************************/
-static osm_mgrp_t *pr_get_mgrp(IN osm_sa_t * sa, IN const osm_madw_t * p_madw)
+static osm_mgrp_box_t *pr_get_mgrp_box(IN osm_sa_t * sa, IN const osm_madw_t * p_madw)
{
ib_path_rec_t *p_pr;
const ib_sa_mad_t *p_sa_mad;
ib_net64_t comp_mask;
osm_mgrp_t *mgrp = NULL;
+ osm_mgrp_box_t *mgrp_box = NULL;
p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
p_pr = (ib_path_rec_t *) ib_sa_mad_get_payload_ptr(p_sa_mad);
@@ -1454,6 +1455,8 @@ static osm_mgrp_t *pr_get_mgrp(IN osm_sa_t * sa, IN const osm_madw_t * p_madw)
sizeof gid_str));
goto Exit;
}
+ if (mgrp)
+ mgrp_box = osm_get_mgrp_box_by_mlid(sa->p_subn, mgrp->mlid);
if (comp_mask & IB_PR_COMPMASK_DLID) {
if (mgrp) {
@@ -1465,18 +1468,18 @@ static osm_mgrp_t *pr_get_mgrp(IN osm_sa_t * sa, IN const osm_madw_t * p_madw)
"MC group MLID 0x%x does not match "
"PathRecord destination LID 0x%x\n",
mgrp->mlid, p_pr->dlid);
- mgrp = NULL;
+ mgrp_box = NULL;
goto Exit;
}
} else
- if (!(mgrp = osm_get_mgrp_by_mlid(sa->p_subn, p_pr->dlid)))
+ if (!(mgrp_box = osm_get_mgrp_box_by_mlid(sa->p_subn, p_pr->dlid)))
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:
- return mgrp;
+ return mgrp_box;
}
/**********************************************************************
@@ -1691,20 +1694,31 @@ McastDest:
OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Multicast destination requested\n");
{
osm_mgrp_t *p_mgrp = NULL;
- ib_api_status_t status;
+ ib_api_status_t status = IB_SUCCESS;
osm_pr_item_t *p_pr_item;
uint32_t flow_label;
uint8_t sl;
uint8_t hop_limit;
+ cl_list_item_t *p_item;
+ osm_mgrp_box_t *p_mgrp_box = NULL;
/* First, get the MC info */
- p_mgrp = pr_get_mgrp(sa, p_madw);
+ p_mgrp_box = pr_get_mgrp_box(sa, p_madw);
- if (!p_mgrp)
+ if (!p_mgrp_box)
goto Unlock;
/* Make sure the rest of the PathRecord matches the MC group attributes */
- status = pr_match_mgrp_attributes(sa, p_madw, p_mgrp);
+ for (p_item = cl_qlist_head(&p_mgrp_box->mgrp_list);
+ p_item != cl_qlist_end(&p_mgrp_box->mgrp_list);
+ p_item = cl_qlist_next(p_item)) {
+ p_mgrp = (osm_mgrp_t*)PARENT_STRUCT(p_item, osm_mgrp_t,
+ box_item);
+ status = pr_match_mgrp_attributes(sa, p_madw, p_mgrp);
+ if (status == IB_SUCCESS)
+ break;
+ }
+
if (status != IB_SUCCESS) {
OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1F19: "
"MC group attributes don't match PathRecord request\n");
diff --git a/opensm/opensm/osm_subnet.c b/opensm/opensm/osm_subnet.c
index 8d63a75..61d766a 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.
@@ -430,6 +430,7 @@ void osm_subn_destroy(IN osm_subn_t * const p_subn)
osm_prtn_t *p_prtn, *p_next_prtn;
osm_mgrp_t *p_mgrp;
osm_infr_t *p_infr, *p_next_infr;
+ osm_mgrp_box_t *p_mgrp_box;
/* 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,19 @@ 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_box = p_subn->mboxes[i];
+ if (p_mgrp_box)
+ osm_mgrp_box_delete(p_subn, p_mgrp_box->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);
@@ -1655,3 +1661,18 @@ int osm_subn_write_conf_file(char *file_name, IN osm_subn_opt_t *const p_opts)
return 0;
}
+
+ib_net16_t osm_mgrp_box_get_mlid(IN struct osm_mgrp_box *p_mgrp_box)
+{
+ return (p_mgrp_box->mlid);
+}
+
+ib_net16_t osm_mgrp_box_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