[ofa-general] Re: [PATCH] opensm: multicast multiplexing many mgid to mlid
Slava Strebkov
slavas at Voltaire.COM
Sun Jun 28 04:02:12 PDT 2009
Please ignore this message - wrongly sent.
Only review numbered patches 1-4 in this thread.
Slava
Slava Strebkov wrote:
> Subject: [PATCH 3/4] Patch implements multicast multiplexing as proposed in the
> thread entitled "IPv6 and IPoIB scalability issue".
> This part (3) introduces usage of new infrastructure
> for mgid->mlid compression
> Signed-off-by: Slava Strebkov <slavas at voltaire.com>
>
> ---
> opensm/include/opensm/osm_multicast.h | 5 +-
> opensm/include/opensm/osm_sm.h | 23 ++-
> opensm/opensm/osm_drop_mgr.c | 14 +-
> opensm/opensm/osm_mcast_mgr.c | 2 +-
> opensm/opensm/osm_multicast.c | 2 +-
> opensm/opensm/osm_qos_policy.c | 360 ++++++++++++++++++--------------
> opensm/opensm/osm_sa.c | 65 ++++--
> opensm/opensm/osm_sa_mcmember_record.c | 161 ++++++++-------
> opensm/opensm/osm_sa_path_record.c | 32 +++-
> opensm/opensm/osm_sm.c | 92 +++++++--
> opensm/opensm/osm_subnet.c | 12 +-
> 11 files changed, 474 insertions(+), 294 deletions(-)
>
> diff --git a/opensm/include/opensm/osm_multicast.h b/opensm/include/opensm/osm_multicast.h
> index 9f0cd96..567a989 100644
> --- a/opensm/include/opensm/osm_multicast.h
> +++ b/opensm/include/opensm/osm_multicast.h
> @@ -331,12 +331,15 @@ osm_mgrp_t *osm_mgrp_new(IN const ib_net16_t mlid);
> *
> * SYNOPSIS
> */
> -void osm_mgrp_delete(IN osm_mgrp_t * const p_mgrp);
> +void osm_mgrp_delete_group(IN osm_subn_t * p_subn, IN osm_mgrp_t * const p_mgrp);
> /*
> * PARAMETERS
> * p_mgrp
> * [in] Pointer to an osm_mgrp_t object.
> *
> +* p_subn
> +* [in] Pointer to an osm_subn_t object.
> +*
> * RETURN VALUES
> * None.
> *
> diff --git a/opensm/include/opensm/osm_sm.h b/opensm/include/opensm/osm_sm.h
> index cc8321d..26530f3 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" {
> @@ -101,7 +102,7 @@ BEGIN_C_DECLS
> *
> * SYNOPSIS
> */
> -typedef struct osm_sm {
> + typedef struct osm_sm {
> osm_thread_state_t thread_state;
> unsigned signal_mask;
> cl_spinlock_t signal_lock;
> @@ -539,7 +540,7 @@ 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 +552,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 +575,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
> @@ -689,7 +692,7 @@ osm_sm_is_greater_than(IN const uint8_t l_priority,
> *
> * SYNOPSIS
> */
> -ib_api_status_t osm_sm_state_mgr_process(IN osm_sm_t *sm,
> +ib_api_status_t osm_sm_state_mgr_process(IN osm_sm_t * sm,
> IN osm_sm_signal_t signal);
> /*
> * PARAMETERS
> @@ -718,7 +721,7 @@ ib_api_status_t osm_sm_state_mgr_process(IN osm_sm_t *sm,
> *
> * SYNOPSIS
> */
> -void osm_sm_state_mgr_signal_master_is_alive(IN osm_sm_t *sm);
> +void osm_sm_state_mgr_signal_master_is_alive(IN osm_sm_t * sm);
> /*
> * PARAMETERS
> * sm
> @@ -743,7 +746,7 @@ void osm_sm_state_mgr_signal_master_is_alive(IN osm_sm_t *sm);
> *
> * SYNOPSIS
> */
> -ib_api_status_t osm_sm_state_mgr_check_legality(IN osm_sm_t *sm,
> +ib_api_status_t osm_sm_state_mgr_check_legality(IN osm_sm_t * sm,
> IN osm_sm_signal_t signal);
> /*
> * PARAMETERS
> @@ -762,7 +765,7 @@ ib_api_status_t osm_sm_state_mgr_check_legality(IN osm_sm_t *sm,
> * State Manager
> *********/
>
> -void osm_report_sm_state(osm_sm_t *sm);
> +void osm_report_sm_state(osm_sm_t * sm);
>
> /****f* OpenSM: SM State Manager/osm_send_trap144
> * NAME
> @@ -773,7 +776,7 @@ void osm_report_sm_state(osm_sm_t *sm);
> *
> * SYNOPSIS
> */
> -int osm_send_trap144(osm_sm_t *sm, ib_net16_t local);
> +int osm_send_trap144(osm_sm_t * sm, ib_net16_t local);
> /*
> * PARAMETERS
> * sm
> @@ -787,7 +790,7 @@ int osm_send_trap144(osm_sm_t *sm, ib_net16_t local);
> *
> *********/
>
> -void osm_set_sm_priority(osm_sm_t *sm, uint8_t priority);
> +void osm_set_sm_priority(osm_sm_t * sm, uint8_t priority);
>
> END_C_DECLS
> #endif /* _OSM_SM_H_ */
> diff --git a/opensm/opensm/osm_drop_mgr.c b/opensm/opensm/osm_drop_mgr.c
> index c9a4f33..d92fdfc 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_osm_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_osm_mgrp_holder =
> + osm_get_mgrp_holder_by_mlid(sm->p_subn, p_mcm->mlid);
> + if (p_osm_mgrp_holder) {
> + osm_mgrp_holder_remove_port(sm->p_subn, sm->p_log,
> + p_osm_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 de0a8a5..e16c2e7 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.
> diff --git a/opensm/opensm/osm_multicast.c b/opensm/opensm/osm_multicast.c
> index d2a19ea..e2e588c 100644
> --- a/opensm/opensm/osm_multicast.c
> +++ b/opensm/opensm/osm_multicast.c
> @@ -41,7 +41,7 @@
> #if HAVE_CONFIG_H
> # include <config.h>
> #endif /* HAVE_CONFIG_H */
> -
> +#include <arpa/inet.h>
> #include <stdlib.h>
> #include <string.h>
> #include <opensm/osm_sa.h>
> diff --git a/opensm/opensm/osm_qos_policy.c b/opensm/opensm/osm_qos_policy.c
> index 094fef2..07b05f5 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.
> @@ -59,11 +59,10 @@ extern osm_qos_level_t __default_simple_qos_level;
> /***************************************************
> ***************************************************/
>
> -static void
> -__build_nodebyname_hash(osm_qos_policy_t * p_qos_policy)
> +static void __build_nodebyname_hash(osm_qos_policy_t * p_qos_policy)
> {
> - osm_node_t * p_node;
> - cl_qmap_t * p_node_guid_tbl = &p_qos_policy->p_subn->node_guid_tbl;
> + osm_node_t *p_node;
> + cl_qmap_t *p_node_guid_tbl = &p_qos_policy->p_subn->node_guid_tbl;
>
> p_qos_policy->p_node_hash = st_init_strtable();
> CL_ASSERT(p_qos_policy->p_node_hash);
> @@ -75,10 +74,10 @@ __build_nodebyname_hash(osm_qos_policy_t * p_qos_policy)
> p_node != (osm_node_t *) cl_qmap_end(p_node_guid_tbl);
> p_node = (osm_node_t *) cl_qmap_next(&p_node->map_item)) {
> if (!st_lookup(p_qos_policy->p_node_hash,
> - (st_data_t)p_node->print_desc, NULL))
> + (st_data_t) p_node->print_desc, NULL))
> st_insert(p_qos_policy->p_node_hash,
> - (st_data_t)p_node->print_desc,
> - (st_data_t)p_node);
> + (st_data_t) p_node->print_desc,
> + (st_data_t) p_node);
> }
> }
>
> @@ -87,7 +86,7 @@ __build_nodebyname_hash(osm_qos_policy_t * p_qos_policy)
>
> static boolean_t
> __is_num_in_range_arr(uint64_t ** range_arr,
> - unsigned range_arr_len, uint64_t num)
> + unsigned range_arr_len, uint64_t num)
> {
> unsigned ind_1 = 0;
> unsigned ind_2 = range_arr_len - 1;
> @@ -97,22 +96,23 @@ __is_num_in_range_arr(uint64_t ** range_arr,
> return FALSE;
>
> while (ind_1 <= ind_2) {
> - if (num < range_arr[ind_1][0] || num > range_arr[ind_2][1])
> - return FALSE;
> - else if (num <= range_arr[ind_1][1] || num >= range_arr[ind_2][0])
> - return TRUE;
> -
> - ind_mid = ind_1 + (ind_2 - ind_1 + 1)/2;
> -
> - if (num < range_arr[ind_mid][0])
> - ind_2 = ind_mid;
> - else if (num > range_arr[ind_mid][1])
> - ind_1 = ind_mid;
> - else
> - return TRUE;
> -
> - ind_1++;
> - ind_2--;
> + if (num < range_arr[ind_1][0] || num > range_arr[ind_2][1])
> + return FALSE;
> + else if (num <= range_arr[ind_1][1]
> + || num >= range_arr[ind_2][0])
> + return TRUE;
> +
> + ind_mid = ind_1 + (ind_2 - ind_1 + 1) / 2;
> +
> + if (num < range_arr[ind_mid][0])
> + ind_2 = ind_mid;
> + else if (num > range_arr[ind_mid][1])
> + ind_1 = ind_mid;
> + else
> + return TRUE;
> +
> + ind_1++;
> + ind_2--;
> }
>
> return FALSE;
> @@ -130,10 +130,9 @@ static void __free_single_element(void *p_element, void *context)
> /***************************************************
> ***************************************************/
>
> -osm_qos_port_t *osm_qos_policy_port_create(osm_physp_t *p_physp)
> +osm_qos_port_t *osm_qos_policy_port_create(osm_physp_t * p_physp)
> {
> - osm_qos_port_t *p =
> - (osm_qos_port_t *) malloc(sizeof(osm_qos_port_t));
> + osm_qos_port_t *p = (osm_qos_port_t *) malloc(sizeof(osm_qos_port_t));
> if (!p)
> return NULL;
> memset(p, 0, sizeof(osm_qos_port_t));
> @@ -163,8 +162,8 @@ osm_qos_port_group_t *osm_qos_policy_port_group_create()
>
> void osm_qos_policy_port_group_destroy(osm_qos_port_group_t * p)
> {
> - osm_qos_port_t * p_port;
> - osm_qos_port_t * p_old_port;
> + osm_qos_port_t *p_port;
> + osm_qos_port_t *p_old_port;
>
> if (!p)
> return;
> @@ -175,8 +174,7 @@ void osm_qos_policy_port_group_destroy(osm_qos_port_group_t * p)
> free(p->use);
>
> p_port = (osm_qos_port_t *) cl_qmap_head(&p->port_map);
> - while (p_port != (osm_qos_port_t *) cl_qmap_end(&p->port_map))
> - {
> + while (p_port != (osm_qos_port_t *) cl_qmap_end(&p->port_map)) {
> p_old_port = p_port;
> p_port = (osm_qos_port_t *) cl_qmap_next(&p_port->map_item);
> free(p_old_port);
> @@ -424,9 +422,10 @@ void osm_qos_policy_match_rule_destroy(osm_qos_match_rule_t * p)
> /***************************************************
> ***************************************************/
>
> -osm_qos_policy_t * osm_qos_policy_create(osm_subn_t * p_subn)
> +osm_qos_policy_t *osm_qos_policy_create(osm_subn_t * p_subn)
> {
> - osm_qos_policy_t * p_qos_policy = (osm_qos_policy_t *)malloc(sizeof(osm_qos_policy_t));
> + osm_qos_policy_t *p_qos_policy =
> + (osm_qos_policy_t *) malloc(sizeof(osm_qos_policy_t));
> if (!p_qos_policy)
> return NULL;
>
> @@ -544,8 +543,8 @@ __qos_policy_is_port_in_group(osm_subn_t * p_subn,
>
> /* check whether this port's type matches any of group's types */
>
> - if ( p_port_group->node_types &
> - (((uint8_t)1)<<osm_node_get_type(p_node)) )
> + if (p_port_group->node_types &
> + (((uint8_t) 1) << osm_node_get_type(p_node)))
> return TRUE;
>
> /* check whether this port's guid is in group's port map */
> @@ -585,24 +584,33 @@ __qos_policy_is_port_in_group_list(const osm_qos_policy_t * p_qos_policy,
> /***************************************************
> ***************************************************/
>
> -static osm_qos_match_rule_t *__qos_policy_get_match_rule_by_params(
> - const osm_qos_policy_t * p_qos_policy,
> - uint64_t service_id,
> - uint16_t qos_class,
> - uint16_t pkey,
> - const osm_physp_t * p_src_physp,
> - const osm_physp_t * p_dest_physp,
> - ib_net64_t comp_mask)
> +static osm_qos_match_rule_t *__qos_policy_get_match_rule_by_params(const
> + osm_qos_policy_t
> + *
> + p_qos_policy,
> + uint64_t
> + service_id,
> + uint16_t
> + qos_class,
> + uint16_t
> + pkey,
> + const
> + osm_physp_t *
> + p_src_physp,
> + const
> + osm_physp_t *
> + p_dest_physp,
> + ib_net64_t
> + comp_mask)
> {
> osm_qos_match_rule_t *p_qos_match_rule = NULL;
> cl_list_iterator_t list_iterator;
> - osm_log_t * p_log = &p_qos_policy->p_subn->p_osm->log;
> + osm_log_t *p_log = &p_qos_policy->p_subn->p_osm->log;
>
> boolean_t matched_by_sguid = FALSE,
> - matched_by_dguid = FALSE,
> - matched_by_class = FALSE,
> - matched_by_sid = FALSE,
> - matched_by_pkey = FALSE;
> + matched_by_dguid = FALSE,
> + matched_by_class = FALSE,
> + matched_by_sid = FALSE, matched_by_pkey = FALSE;
>
> if (!cl_list_count(&p_qos_policy->qos_match_rules))
> return NULL;
> @@ -698,8 +706,7 @@ static osm_qos_match_rule_t *__qos_policy_get_match_rule_by_params(
>
> if (!__is_num_in_range_arr
> (p_qos_match_rule->pkey_range_arr,
> - p_qos_match_rule->pkey_range_len,
> - pkey & 0x7FFF)) {
> + p_qos_match_rule->pkey_range_len, pkey & 0x7FFF)) {
> list_iterator = cl_list_next(list_iterator);
> continue;
> }
> @@ -717,15 +724,14 @@ static osm_qos_match_rule_t *__qos_policy_get_match_rule_by_params(
> OSM_LOG(p_log, OSM_LOG_DEBUG,
> "request matched rule (%s) by:%s%s%s%s%s\n",
> (p_qos_match_rule->use) ?
> - p_qos_match_rule->use : "no description",
> + p_qos_match_rule->use : "no description",
> (matched_by_sguid) ? " SGUID" : "",
> (matched_by_dguid) ? " DGUID" : "",
> (matched_by_class) ? " QoS_Class" : "",
> - (matched_by_sid) ? " ServiceID" : "",
> - (matched_by_pkey) ? " PKey" : "");
> + (matched_by_sid) ? " ServiceID" : "",
> + (matched_by_pkey) ? " PKey" : "");
> else
> - OSM_LOG(p_log, OSM_LOG_DEBUG,
> - "request not matched any rule\n");
> + OSM_LOG(p_log, OSM_LOG_DEBUG, "request not matched any rule\n");
>
> OSM_LOG_EXIT(p_log);
> return p_qos_match_rule;
> @@ -734,9 +740,10 @@ static osm_qos_match_rule_t *__qos_policy_get_match_rule_by_params(
> /***************************************************
> ***************************************************/
>
> -static osm_qos_level_t *__qos_policy_get_qos_level_by_name(
> - const osm_qos_policy_t * p_qos_policy,
> - char *name)
> +static osm_qos_level_t *__qos_policy_get_qos_level_by_name(const
> + osm_qos_policy_t *
> + p_qos_policy,
> + char *name)
> {
> osm_qos_level_t *p_qos_level = NULL;
> cl_list_iterator_t list_iterator;
> @@ -760,9 +767,11 @@ static osm_qos_level_t *__qos_policy_get_qos_level_by_name(
> /***************************************************
> ***************************************************/
>
> -static osm_qos_port_group_t *__qos_policy_get_port_group_by_name(
> - const osm_qos_policy_t * p_qos_policy,
> - const char *const name)
> +static osm_qos_port_group_t *__qos_policy_get_port_group_by_name(const
> + osm_qos_policy_t
> + * p_qos_policy,
> + const char
> + *const name)
> {
> osm_qos_port_group_t *p_port_group = NULL;
> cl_list_iterator_t list_iterator;
> @@ -787,15 +796,16 @@ static osm_qos_port_group_t *__qos_policy_get_port_group_by_name(
> /***************************************************
> ***************************************************/
>
> -static void __qos_policy_validate_pkey(
> - osm_qos_policy_t * p_qos_policy,
> - osm_qos_match_rule_t * p_qos_match_rule,
> - osm_prtn_t * p_prtn)
> +static void __qos_policy_validate_pkey(osm_qos_policy_t * p_qos_policy,
> + osm_qos_match_rule_t * p_qos_match_rule,
> + osm_prtn_t * p_prtn)
> {
> uint8_t sl;
> uint32_t flow;
> uint8_t hop;
> - osm_mgrp_t * p_mgrp;
> + osm_mgrp_t *p_mgrp;
> + osm_mgrp_holder_t *p_mgrp_holder;
> + cl_fmap_item_t *p_fitem;
>
> if (!p_qos_policy || !p_qos_match_rule || !p_prtn)
> return;
> @@ -812,43 +822,49 @@ static void __qos_policy_validate_pkey(
> p_qos_match_rule->p_qos_level->sl);
> p_prtn->sl = p_qos_match_rule->p_qos_level->sl;
>
> -
> /* If this partition is an IPoIB partition, there should
> be a matching MCast group. Fix this group's SL too */
>
> 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,
> - "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_fitem = cl_fmap_head(&p_mgrp_holder->mgrp_map);
> + while (p_fitem != cl_fmap_end(&p_mgrp_holder->mgrp_map)) {
> + p_mgrp =
> + (osm_mgrp_t *) PARENT_STRUCT(p_fitem, osm_mgrp_t,
> + mgid_item);
> + p_fitem = cl_fmap_next(p_fitem);
> +
> + 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);
> + }
> }
> }
>
> /***************************************************
> ***************************************************/
>
> -int osm_qos_policy_validate(osm_qos_policy_t * p_qos_policy,
> - osm_log_t *p_log)
> +int osm_qos_policy_validate(osm_qos_policy_t * p_qos_policy, osm_log_t * p_log)
> {
> cl_list_iterator_t match_rules_list_iterator;
> cl_list_iterator_t list_iterator;
> @@ -859,22 +875,23 @@ int osm_qos_policy_validate(osm_qos_policy_t * p_qos_policy,
> int res = 0;
> uint64_t pkey_64;
> ib_net16_t pkey;
> - osm_prtn_t * p_prtn;
> + osm_prtn_t *p_prtn;
>
> OSM_LOG_ENTER(p_log);
>
> /* set default qos level */
>
> p_qos_policy->p_default_qos_level =
> - __qos_policy_get_qos_level_by_name(p_qos_policy, OSM_QOS_POLICY_DEFAULT_LEVEL_NAME);
> + __qos_policy_get_qos_level_by_name(p_qos_policy,
> + OSM_QOS_POLICY_DEFAULT_LEVEL_NAME);
> if (!p_qos_policy->p_default_qos_level) {
> /* There's no default QoS level in the usual qos-level section.
> Check whether the 'simple' default QoS level that can be
> defined in the qos-ulp section exists */
> if (__default_simple_qos_level.sl_set) {
> - p_qos_policy->p_default_qos_level = &__default_simple_qos_level;
> - }
> - else {
> + p_qos_policy->p_default_qos_level =
> + &__default_simple_qos_level;
> + } else {
> OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC10: "
> "Default qos-level (%s) not defined.\n",
> OSM_QOS_POLICY_DEFAULT_LEVEL_NAME);
> @@ -891,8 +908,7 @@ int osm_qos_policy_validate(osm_qos_policy_t * p_qos_policy,
> cl_list_head(&p_qos_policy->qos_match_rules);
> while (match_rules_list_iterator !=
> cl_list_end(&p_qos_policy->qos_match_rules)) {
> - p_qos_match_rule =
> - (osm_qos_match_rule_t *)
> + p_qos_match_rule = (osm_qos_match_rule_t *)
> cl_list_obj(match_rules_list_iterator);
> CL_ASSERT(p_qos_match_rule);
>
> @@ -900,8 +916,9 @@ int osm_qos_policy_validate(osm_qos_policy_t * p_qos_policy,
>
> if (!p_qos_match_rule->p_qos_level)
> p_qos_match_rule->p_qos_level =
> - __qos_policy_get_qos_level_by_name(p_qos_policy,
> - p_qos_match_rule->qos_level_name);
> + __qos_policy_get_qos_level_by_name(p_qos_policy,
> + p_qos_match_rule->
> + qos_level_name);
>
> if (!p_qos_match_rule->p_qos_level) {
> OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC11: "
> @@ -922,9 +939,11 @@ int osm_qos_policy_validate(osm_qos_policy_t * p_qos_policy,
> CL_ASSERT(str);
>
> p_port_group =
> - __qos_policy_get_port_group_by_name(p_qos_policy, str);
> + __qos_policy_get_port_group_by_name
> + (p_qos_policy, str);
> if (!p_port_group) {
> - OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC12: "
> + OSM_LOG(p_log, OSM_LOG_ERROR,
> + "ERR AC12: "
> "qos-match-rule num %u: source port-group '%s' not found\n",
> i, str);
> res = 1;
> @@ -951,9 +970,11 @@ int osm_qos_policy_validate(osm_qos_policy_t * p_qos_policy,
> CL_ASSERT(str);
>
> p_port_group =
> - __qos_policy_get_port_group_by_name(p_qos_policy,str);
> + __qos_policy_get_port_group_by_name
> + (p_qos_policy, str);
> if (!p_port_group) {
> - OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC13: "
> + OSM_LOG(p_log, OSM_LOG_ERROR,
> + "ERR AC13: "
> "qos-match-rule num %u: destination port-group '%s' not found\n",
> i, str);
> res = 1;
> @@ -977,24 +998,30 @@ int osm_qos_policy_validate(osm_qos_policy_t * p_qos_policy,
> */
>
> for (j = 0; j < p_qos_match_rule->pkey_range_len; j++) {
> - for ( pkey_64 = p_qos_match_rule->pkey_range_arr[j][0];
> - pkey_64 <= p_qos_match_rule->pkey_range_arr[j][1];
> - pkey_64++) {
> - pkey = cl_hton16((uint16_t)(pkey_64 & 0x7fff));
> - p_prtn = (osm_prtn_t *)cl_qmap_get(
> - &p_qos_policy->p_subn->prtn_pkey_tbl, pkey);
> -
> - if (p_prtn == (osm_prtn_t *)cl_qmap_end(
> - &p_qos_policy->p_subn->prtn_pkey_tbl))
> + for (pkey_64 = p_qos_match_rule->pkey_range_arr[j][0];
> + pkey_64 <= p_qos_match_rule->pkey_range_arr[j][1];
> + pkey_64++) {
> + pkey = cl_hton16((uint16_t) (pkey_64 & 0x7fff));
> + p_prtn =
> + (osm_prtn_t *) cl_qmap_get(&p_qos_policy->
> + p_subn->
> + prtn_pkey_tbl,
> + pkey);
> +
> + if (p_prtn ==
> + (osm_prtn_t *) cl_qmap_end(&p_qos_policy->
> + p_subn->
> + prtn_pkey_tbl))
> /* partition for this pkey not found */
> - OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC14: "
> + OSM_LOG(p_log, OSM_LOG_ERROR,
> + "ERR AC14: "
> "pkey 0x%04X in match rule - "
> "partition doesn't exist\n",
> cl_ntoh16(pkey));
> else
> __qos_policy_validate_pkey(p_qos_policy,
> - p_qos_match_rule,
> - p_prtn);
> + p_qos_match_rule,
> + p_prtn);
> }
> }
>
> @@ -1013,53 +1040,70 @@ Exit:
> /***************************************************
> ***************************************************/
>
> -static osm_qos_level_t * __qos_policy_get_qos_level_by_params(
> - IN const osm_qos_policy_t * p_qos_policy,
> - IN const osm_physp_t * p_src_physp,
> - IN const osm_physp_t * p_dest_physp,
> - IN uint64_t service_id,
> - IN uint16_t qos_class,
> - IN uint16_t pkey,
> - IN ib_net64_t comp_mask)
> +static osm_qos_level_t *__qos_policy_get_qos_level_by_params(IN const
> + osm_qos_policy_t *
> + p_qos_policy,
> + IN const
> + osm_physp_t *
> + p_src_physp,
> + IN const
> + osm_physp_t *
> + p_dest_physp,
> + IN uint64_t
> + service_id,
> + IN uint16_t
> + qos_class,
> + IN uint16_t pkey,
> + IN ib_net64_t
> + comp_mask)
> {
> osm_qos_match_rule_t *p_qos_match_rule = NULL;
>
> if (!p_qos_policy)
> return NULL;
>
> - p_qos_match_rule = __qos_policy_get_match_rule_by_params(
> - p_qos_policy, service_id, qos_class, pkey,
> - p_src_physp, p_dest_physp, comp_mask);
> + p_qos_match_rule =
> + __qos_policy_get_match_rule_by_params(p_qos_policy, service_id,
> + qos_class, pkey, p_src_physp,
> + p_dest_physp, comp_mask);
>
> return p_qos_match_rule ? p_qos_match_rule->p_qos_level :
> - p_qos_policy->p_default_qos_level;
> + p_qos_policy->p_default_qos_level;
> } /* __qos_policy_get_qos_level_by_params() */
>
> /***************************************************
> ***************************************************/
>
> -osm_qos_level_t * osm_qos_policy_get_qos_level_by_pr(
> - IN const osm_qos_policy_t * p_qos_policy,
> - IN const ib_path_rec_t * p_pr,
> - IN const osm_physp_t * p_src_physp,
> - IN const osm_physp_t * p_dest_physp,
> - IN ib_net64_t comp_mask)
> +osm_qos_level_t *osm_qos_policy_get_qos_level_by_pr(IN const osm_qos_policy_t *
> + p_qos_policy,
> + IN const ib_path_rec_t *
> + p_pr,
> + IN const osm_physp_t *
> + p_src_physp,
> + IN const osm_physp_t *
> + p_dest_physp,
> + IN ib_net64_t comp_mask)
> {
> - return __qos_policy_get_qos_level_by_params(
> - p_qos_policy, p_src_physp, p_dest_physp,
> - cl_ntoh64(p_pr->service_id), ib_path_rec_qos_class(p_pr),
> - cl_ntoh16(p_pr->pkey), comp_mask);
> + return __qos_policy_get_qos_level_by_params(p_qos_policy, p_src_physp,
> + p_dest_physp,
> + cl_ntoh64(p_pr->service_id),
> + ib_path_rec_qos_class(p_pr),
> + cl_ntoh16(p_pr->pkey),
> + comp_mask);
> }
>
> /***************************************************
> ***************************************************/
>
> -osm_qos_level_t * osm_qos_policy_get_qos_level_by_mpr(
> - IN const osm_qos_policy_t * p_qos_policy,
> - IN const ib_multipath_rec_t * p_mpr,
> - IN const osm_physp_t * p_src_physp,
> - IN const osm_physp_t * p_dest_physp,
> - IN ib_net64_t comp_mask)
> +osm_qos_level_t *osm_qos_policy_get_qos_level_by_mpr(IN const osm_qos_policy_t *
> + p_qos_policy,
> + IN const ib_multipath_rec_t
> + * p_mpr,
> + IN const osm_physp_t *
> + p_src_physp,
> + IN const osm_physp_t *
> + p_dest_physp,
> + IN ib_net64_t comp_mask)
> {
> ib_net64_t pr_comp_mask = 0;
>
> @@ -1071,20 +1115,24 @@ osm_qos_level_t * osm_qos_policy_get_qos_level_by_mpr(
> * compmask. Note that only relevant bits are set.
> */
> pr_comp_mask =
> - ((comp_mask & IB_MPR_COMPMASK_QOS_CLASS) ?
> - IB_PR_COMPMASK_QOS_CLASS : 0) |
> - ((comp_mask & IB_MPR_COMPMASK_PKEY) ?
> - IB_PR_COMPMASK_PKEY : 0) |
> - ((comp_mask & IB_MPR_COMPMASK_SERVICEID_MSB) ?
> - IB_PR_COMPMASK_SERVICEID_MSB : 0) |
> - ((comp_mask & IB_MPR_COMPMASK_SERVICEID_LSB) ?
> - IB_PR_COMPMASK_SERVICEID_LSB : 0);
> -
> - return __qos_policy_get_qos_level_by_params(
> - p_qos_policy, p_src_physp, p_dest_physp,
> - cl_ntoh64(ib_multipath_rec_service_id(p_mpr)),
> - ib_multipath_rec_qos_class(p_mpr),
> - cl_ntoh16(p_mpr->pkey), pr_comp_mask);
> + ((comp_mask & IB_MPR_COMPMASK_QOS_CLASS) ?
> + IB_PR_COMPMASK_QOS_CLASS : 0) |
> + ((comp_mask & IB_MPR_COMPMASK_PKEY) ?
> + IB_PR_COMPMASK_PKEY : 0) |
> + ((comp_mask & IB_MPR_COMPMASK_SERVICEID_MSB) ?
> + IB_PR_COMPMASK_SERVICEID_MSB : 0) |
> + ((comp_mask & IB_MPR_COMPMASK_SERVICEID_LSB) ?
> + IB_PR_COMPMASK_SERVICEID_LSB : 0);
> +
> + return __qos_policy_get_qos_level_by_params(p_qos_policy, p_src_physp,
> + p_dest_physp,
> + cl_ntoh64
> + (ib_multipath_rec_service_id
> + (p_mpr)),
> + ib_multipath_rec_qos_class
> + (p_mpr),
> + cl_ntoh16(p_mpr->pkey),
> + pr_comp_mask);
> }
>
> /***************************************************
> diff --git a/opensm/opensm/osm_sa.c b/opensm/opensm/osm_sa.c
> index fcc3f27..0c24a49 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.
> @@ -52,6 +52,7 @@
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <complib/cl_qmap.h>
> +#include <complib/cl_fleximap.h>
> #include <complib/cl_passivelock.h>
> #include <complib/cl_debug.h>
> #include <iba/ib_types.h>
> @@ -317,7 +318,7 @@ Exit:
> return (status);
> }
>
> -ib_api_status_t osm_sa_send(osm_sa_t *sa,
> +ib_api_status_t osm_sa_send(osm_sa_t * sa,
> IN osm_madw_t * const p_madw,
> IN boolean_t const resp_expected)
> {
> @@ -397,8 +398,8 @@ Exit:
> OSM_LOG_EXIT(sa->p_log);
> }
>
> -void osm_sa_respond(osm_sa_t *sa, osm_madw_t *madw, size_t attr_size,
> - cl_qlist_t *list)
> +void osm_sa_respond(osm_sa_t * sa, osm_madw_t * madw, size_t attr_size,
> + cl_qlist_t * list)
> {
> struct item_data {
> cl_list_item_t list;
> @@ -422,13 +423,13 @@ void osm_sa_respond(osm_sa_t *sa, osm_madw_t *madw, size_t attr_size,
> */
> if (sa_mad->method == IB_MAD_METHOD_GET && num_rec > 1) {
> OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C05: "
> - "Got %u records for SubnAdmGet(%s) comp_mask 0x%016" PRIx64 "\n",
> - num_rec, ib_get_sa_attr_str(sa_mad->attr_id),
> + "Got %u records for SubnAdmGet(%s) comp_mask 0x%016"
> + PRIx64 "\n", num_rec,
> + ib_get_sa_attr_str(sa_mad->attr_id),
> cl_ntoh64(sa_mad->comp_mask));
> osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
> goto Exit;
> }
> -
> #ifndef VENDOR_RMPP_SUPPORT
> trim_num_rec = (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / attr_size;
> if (trim_num_rec < num_rec) {
> @@ -564,7 +565,7 @@ static void mcast_mgr_dump_one_port(cl_map_item_t * p_map_item, void *cxt)
> p_mcm_port->scope_state, p_mcm_port->proxy_join);
> }
>
> -static void sa_dump_one_mgrp(osm_mgrp_t *p_mgrp, void *cxt)
> +static void sa_dump_one_mgrp(osm_mgrp_t * p_mgrp, void *cxt)
> {
> struct opensm_dump_context dump_context;
> osm_opensm_t *p_osm = ((struct opensm_dump_context *)cxt)->p_osm;
> @@ -706,6 +707,8 @@ static void sa_dump_all_sa(osm_opensm_t * p_osm, FILE * file)
> {
> struct opensm_dump_context dump_context;
> osm_mgrp_t *p_mgrp;
> + cl_fmap_item_t *p_fitem;
> + osm_mgrp_holder_t *p_mgrp_holder;
> int i;
>
> dump_context.p_osm = p_osm;
> @@ -714,9 +717,17 @@ static void sa_dump_all_sa(osm_opensm_t * p_osm, FILE * file)
> 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)
> + p_mgrp_holder = p_osm->subn.mgroup_holders[i];
> + if (!p_mgrp_holder)
> + continue;
> + p_fitem = cl_fmap_head(&p_mgrp_holder->mgrp_map);
> + while (p_fitem != cl_fmap_end(&p_mgrp_holder->mgrp_map)) {
> + p_mgrp =
> + (osm_mgrp_t *) PARENT_STRUCT(p_fitem, osm_mgrp_t,
> + mgid_item);
> sa_dump_one_mgrp(p_mgrp, &dump_context);
> + p_fitem = cl_fmap_next(&p_mgrp->mgid_item);
> + }
> }
> OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump inform\n");
> cl_qlist_apply_func(&p_osm->subn.sa_infr_list,
> @@ -740,25 +751,35 @@ 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_holder_t *p_mgrp_holder;
> + ib_gid_t common_mgid;
> + 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))) {
> + p_mgrp_holder = osm_get_mgrp_holder_by_mlid(&p_osm->subn, mlid);
> + if (p_mgrp_holder) {
> + p_fitem =
> + cl_fmap_get(&p_mgrp_holder->mgrp_map, &p_mcm_rec->mgid);
> + if (p_fitem != cl_fmap_end(&p_mgrp_holder->mgrp_map)) {
> 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;
> - }
>
> + osm_mgrp_holder_prepare_common_mgid(&p_mcm_rec->mgid,
> + &common_mgid);
> + if (memcmp
> + (&p_mgrp_holder->common_mgid, &common_mgid,
> + sizeof(ib_gid_t))) {
> + 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
> | IB_MCR_COMPMASK_RATE | IB_MCR_COMPMASK_RATE_SEL;
> if (osm_mcmr_rcv_find_or_create_new_mgrp(&p_osm->sa,
> diff --git a/opensm/opensm/osm_sa_mcmember_record.c b/opensm/opensm/osm_sa_mcmember_record.c
> index 5543221..23c5107 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.
> @@ -63,6 +63,7 @@
> #include <opensm/osm_pkey.h>
> #include <opensm/osm_inform.h>
> #include <opensm/osm_sa.h>
> +#include <opensm/osm_mcm_info.h>
>
> #define JOIN_MC_COMP_MASK (IB_MCR_COMPMASK_MGID | \
> IB_MCR_COMPMASK_PORT_GID | \
> @@ -121,13 +122,14 @@ 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)
> + osm_mgrp_holder_t *p_mgrp_holder =
> + (osm_mgrp_holder_t *) sa->p_subn->mgroup_holders[i];
> + if (!p_mgrp_holder || p_mgrp_holder->to_be_deleted)
> return cl_hton16(i + IB_LID_MCAST_START_HO);
> }
>
> @@ -141,14 +143,21 @@ static ib_net16_t get_new_mlid(osm_sa_t * sa, ib_net16_t requested_mlid)
> we silently drop it. Since it was an intermediate group no need to
> re-route it.
> **********************************************************************/
> -static void cleanup_mgrp(IN osm_sa_t * sa, osm_mgrp_t * mgrp)
> +static void cleanup_mgrp(IN osm_sa_t * sa, osm_mgrp_t * p_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_delete(mgrp);
> + char gid_str[INET6_ADDRSTRLEN];
> + if (cl_is_qmap_empty(&p_mgrp->mcm_port_tbl) && !p_mgrp->well_known) {
> + OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
> + "mgrp mgid %s will be deleted\n", inet_ntop(AF_INET6,
> + p_mgrp->
> + mcmember_rec.
> + mgid.raw,
> + gid_str,
> + sizeof
> + (gid_str)));
> + osm_mgrp_delete_group(sa->sm->p_subn, p_mgrp);
> }
> }
>
> @@ -202,7 +211,6 @@ static ib_api_status_t add_new_mgrp_port(osm_sa_t * sa, IN osm_mgrp_t * p_mgrp,
>
> return IB_INSUFFICIENT_MEMORY;
> }
> -
> return IB_SUCCESS;
> }
>
> @@ -806,11 +814,12 @@ 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;
> + char gid_str[INET6_ADDRSTRLEN];
> ib_gid_t *p_mgid;
> - osm_mgrp_t *p_prev_mgrp;
> + osm_mgrp_holder_t *p_mgrp_holder;
> ib_api_status_t status = IB_SUCCESS;
> ib_member_rec_t mcm_rec = *p_recvd_mcmember_rec; /* copy for modifications */
>
> @@ -823,7 +832,7 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
> zero_mgid = 0;
> break;
> }
> -
> + p_mgid = &(mcm_rec.mgid);
> /*
> we allocate a new mlid number before we might use it
> for MGID ...
> @@ -843,8 +852,6 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
> /* we need to create the new MGID if it was not defined */
> if (zero_mgid) {
> /* create a new MGID */
> - char gid_str[INET6_ADDRSTRLEN];
> -
> /* use the given scope state only if requested! */
> if (comp_mask & IB_MCR_COMPMASK_SCOPE)
> ib_member_get_scope_state(p_recvd_mcmember_rec->
> @@ -888,6 +895,13 @@ 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_mgid))) {
> + 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) {
> @@ -915,17 +929,21 @@ ib_api_status_t osm_mcmr_rcv_create_new_mgrp(IN osm_sa_t * sa,
> /* 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;
> - 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, p_mgid, mlid);
> }
> -
> - sa->p_subn->mgroups[cl_ntoh16(mlid) - IB_LID_MCAST_START_HO] = *pp_mgrp;
> + 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;
> + }
> + osm_mgrp_holder_add_mgrp(p_mgrp_holder, *pp_mgrp, sa->p_log);
>
> Exit:
> OSM_LOG_EXIT(sa->p_log);
> @@ -934,56 +952,47 @@ Exit:
>
> /**********************************************************************
> *********************************************************************/
> -static unsigned match_mgrp_by_mgid(IN osm_mgrp_t * p_mgrp, ib_gid_t * mgid)
> -{
> - /* ignore groups marked for deletion */
> - if (p_mgrp->to_be_deleted ||
> - memcmp(&p_mgrp->mcmember_rec.mgid, mgid, sizeof(ib_gid_t)))
> - return 0;
> - else
> - return 1;
> -}
> -
> -/**********************************************************************
> - **********************************************************************/
> -#define PREFIX_MASK CL_HTON64(0xff10ffff0000ffffULL)
> -#define PREFIX_SIGNATURE CL_HTON64(0xff10601b00000000ULL)
> -#define INT_ID_MASK CL_HTON64(0xfffffff1ff000000ULL)
> -#define INT_ID_SIGNATURE CL_HTON64(0x00000001ff000000ULL)
> -
> -/* Special Case IPv6 Solicited Node Multicast (SNM) addresses */
> -/* 0xff1Z601bXXXX0000 : 0x00000001ffYYYYYY */
> -/* Where Z is the scope, XXXX is the P_Key, and
> - * YYYYYY is the last 24 bits of the port guid */
> -static unsigned match_and_update_ipv6_snm_mgid(ib_gid_t * mgid)
> +static osm_mgrp_t *match_mgrp_by_mgid(IN osm_mgrp_holder_t * p_mgrp_holder,
> + ib_gid_t * p_mgid)
> {
> - if ((mgid->unicast.prefix & PREFIX_MASK) == PREFIX_SIGNATURE &&
> - (mgid->unicast.interface_id & INT_ID_MASK) == INT_ID_SIGNATURE) {
> - mgid->unicast.prefix &= PREFIX_MASK;
> - mgid->unicast.interface_id &= INT_ID_MASK;
> - return 1;
> - }
> - return 0;
> + osm_mgrp_t *p_mgrp;
> + ib_gid_t common_mgid;
> + cl_fmap_item_t *p_fitem;
> +
> + osm_mgrp_holder_prepare_common_mgid(p_mgid, &common_mgid);
> +
> + if (memcmp(&p_mgrp_holder->common_mgid, &common_mgid, sizeof(ib_gid_t)))
> + return NULL;
> + p_fitem = cl_fmap_get(&p_mgrp_holder->mgrp_map, p_mgid);
> + if (p_fitem != cl_fmap_end(&p_mgrp_holder->mgrp_map)) {
> + p_mgrp = (osm_mgrp_t *) PARENT_STRUCT(p_fitem, osm_mgrp_t,
> + mgid_item);
> + /* ignore groups marked for deletion */
> + if (p_mgrp->to_be_deleted)
> + p_mgrp = NULL;
> + } else
> + p_mgrp = NULL;
> + return p_mgrp;;
> }
>
> osm_mgrp_t *osm_get_mgrp_by_mgid(IN osm_sa_t * sa, IN ib_gid_t * p_mgid)
> {
> int i;
> -
> - if (sa->p_subn->opt.consolidate_ipv6_snm_req &&
> - match_and_update_ipv6_snm_mgid(p_mgid)) {
> - char gid_str[INET6_ADDRSTRLEN];
> - OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
> - "Special Case Solicited Node Mcast Join for MGID %s\n",
> - inet_ntop(AF_INET6, p_mgid->raw, gid_str,
> - sizeof gid_str));
> - }
> -
> + osm_mgrp_t *p_mgrp;
> for (i = 0; i <= sa->p_subn->max_mcast_lid_ho - IB_LID_MCAST_START_HO;
> - i++)
> - if (sa->p_subn->mgroups[i] &&
> - match_mgrp_by_mgid(sa->p_subn->mgroups[i], p_mgid))
> - return sa->p_subn->mgroups[i];
> + i++) {
> + if (sa->p_subn->mgroup_holders[i] &&
> + (p_mgrp =
> + match_mgrp_by_mgid(sa->p_subn->mgroup_holders[i],
> + p_mgid))) {
> + char gid_str[INET6_ADDRSTRLEN];
> + OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
> + "Found mgroup for MGID %s\n",
> + inet_ntop(AF_INET6, p_mgid->raw, gid_str,
> + sizeof gid_str));
> + return p_mgrp;
> + }
> + }
>
> return NULL;
> }
> @@ -1080,7 +1089,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");
>
> @@ -1310,7 +1319,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: "
> @@ -1555,6 +1564,8 @@ 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;
> + cl_fmap_item_t *p_fitem;
> + osm_mgrp_holder_t *p_mgrp_holder;
> int i;
>
> OSM_LOG_ENTER(sa->p_log);
> @@ -1586,10 +1597,18 @@ static void mcmr_query_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
> /* 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)
> + p_mgrp_holder = sa->p_subn->mgroup_holders[i];
> + if (!p_mgrp_holder)
> + continue;
> + p_fitem = cl_fmap_head(&p_mgrp_holder->mgrp_map);
> + while (p_fitem != cl_fmap_end(&p_mgrp_holder->mgrp_map)) {
> + p_mgrp =
> + (osm_mgrp_t *) PARENT_STRUCT(p_fitem, osm_mgrp_t,
> + mgid_item);
> mcmr_by_comp_mask(sa, p_rcvd_rec, comp_mask, p_mgrp,
> p_req_physp, trusted_req, &rec_list);
> + p_fitem = cl_fmap_next(p_fitem);
> + }
> }
>
> 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 9b50deb..3271289 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.
> @@ -1438,6 +1438,7 @@ static osm_mgrp_t *pr_get_mgrp(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_holder_t *p_mgrp_holder;
> osm_mgrp_t *mgrp = NULL;
>
> p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
> @@ -1468,11 +1469,30 @@ 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 "
> - "destination LID 0x%x\n", p_pr->dlid);
> + } else {
> + cl_fmap_item_t *p_fitem;
> + p_mgrp_holder =
> + osm_get_mgrp_holder_by_mlid(sa->p_subn, p_pr->dlid);
> + if (p_mgrp_holder) {
> + p_fitem =
> + cl_fmap_get(&p_mgrp_holder->mgrp_map,
> + &p_pr->dgid);
> + }
> + if (!p_mgrp_holder
> + || p_fitem ==
> + cl_fmap_end(&p_mgrp_holder->mgrp_map)) {
> + OSM_LOG(sa->p_log, OSM_LOG_ERROR,
> + "ERR 1F11: "
> + "No MC group found for PathRecord "
> + "destination LID 0x%x\n", p_pr->dlid);
> + } else {
> + mgrp =
> + (osm_mgrp_t *) PARENT_STRUCT(p_fitem,
> + osm_mgrp_t,
> + mgid_item);
> + }
> +
> + }
> }
>
> Exit:
> diff --git a/opensm/opensm/osm_sm.c b/opensm/opensm/osm_sm.c
> index daa60ff..459e2cc 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_fmap_item_t *p_fitem;
> + osm_mgrp_holder_t *p_mgrp_holder;
>
> OSM_LOG_ENTER(p_sm->p_log);
>
> @@ -498,8 +502,51 @@ 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 (osm_is_debug()) {
> + size_t gr_count =
> + cl_fmap_count(&p_mgrp_holder->mgrp_map);
> + OSM_LOG(p_sm->p_log, OSM_LOG_DEBUG,
> + "mlid 0x%X has %d mgroups\n", cl_ntoh16(mlid),
> + gr_count);
> + if (gr_count) {
> + p_fitem =
> + cl_fmap_head(&p_mgrp_holder->mgrp_map);
> + while (p_fitem !=
> + cl_fmap_end(&p_mgrp_holder->mgrp_map)) {
> + p_mgrp =
> + (osm_mgrp_t *)
> + PARENT_STRUCT(p_fitem, osm_mgrp_t,
> + mgid_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_fitem = cl_fmap_next(p_fitem);
> + }
> + }
> + }
> + p_fitem = cl_fmap_get(&p_mgrp_holder->mgrp_map, p_mgid);
> + if (p_fitem == cl_fmap_end(&p_mgrp_holder->mgrp_map)) {
> + 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));
> + } else {
> + p_mgrp =
> + (osm_mgrp_t *) PARENT_STRUCT(p_fitem, osm_mgrp_t,
> + mgid_item);
> + }
> + }
> + 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.
> @@ -514,7 +561,23 @@ ib_api_status_t osm_sm_mcgrp_join(IN osm_sm_t * p_sm, IN const ib_net16_t mlid,
> status = IB_NOT_FOUND;
> 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) {
> + CL_PLOCK_RELEASE(p_sm->p_lock);
> + 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
> @@ -543,9 +606,6 @@ ib_api_status_t osm_sm_mcgrp_join(IN osm_sm_t * p_sm, IN const ib_net16_t mlid,
> goto Exit;
> }
>
> - status = sm_mgrp_process(p_sm, p_mgrp);
> - CL_PLOCK_RELEASE(p_sm->p_lock);
> -
> Exit:
> OSM_LOG_EXIT(p_sm->p_log);
> return status;
> @@ -553,12 +613,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);
>
> @@ -584,8 +645,8 @@ 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.
> */
> - 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) {
> CL_PLOCK_RELEASE(p_sm->p_lock);
> OSM_LOG(p_sm->p_log, OSM_LOG_ERROR, "ERR 2E08: "
> "No multicast group for MLID 0x%X\n", cl_ntoh16(mlid));
> @@ -593,11 +654,14 @@ ib_api_status_t osm_sm_mcgrp_leave(IN osm_sm_t * p_sm, IN const ib_net16_t mlid,
> goto Exit;
> }
>
> + osm_mgrp_holder_delete_mgrp_port(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);
> CL_PLOCK_RELEASE(p_sm->p_lock);
>
> diff --git a/opensm/opensm/osm_subnet.c b/opensm/opensm/osm_subnet.c
> index ec15f8a..e6e624d 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.
> @@ -419,7 +419,7 @@ 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_osm_mgrp_holder;
> osm_infr_t *p_infr, *p_next_infr;
>
> /* it might be a good idea to de-allocate all known objects */
> @@ -464,10 +464,10 @@ void osm_subn_destroy(IN osm_subn_t * const p_subn)
>
> 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_osm_mgrp_holder = p_subn->mgroup_holders[i];
> + if (p_osm_mgrp_holder){
> + osm_mgrp_holder_delete(p_subn, p_osm_mgrp_holder->mlid);
> + }
> }
>
> p_next_infr = (osm_infr_t *) cl_qlist_head(&p_subn->sa_infr_list);
More information about the general
mailing list