[ofa-general] [PATCH 3/4 v2] multicast multiplexing - usage of new infrastructure, for mgid to mlid compression
Slava Strebkov
slavas at Voltaire.COM
Sun Jun 28 03:58:32 PDT 2009
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);
--
1.5.5
More information about the general
mailing list