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 <[email protected]>
> 
> ---
>  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);

_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to