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 <[email protected]> --- 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 _______________________________________________ general mailing list [email protected] http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general
