[openib-general] [PATCH 5/10] osm: QoS in OpenSM
Yevgeny Kliteynik
kliteyn at dev.mellanox.co.il
Tue Jan 30 07:31:42 PST 2007
QoS policy file parser C file with auxiliary functions
Signed-off-by: Yevgeny Kliteynik <kliteyn at dev.mellanox.co.il>
---
osm/opensm/osm_qos_parser.c | 548 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 548 insertions(+), 0 deletions(-)
diff --git a/osm/opensm/osm_qos_parser.c b/osm/opensm/osm_qos_parser.c
new file mode 100644
index 0000000..690535a
--- /dev/null
+++ b/osm/opensm/osm_qos_parser.c
@@ -0,0 +1,548 @@
+/*
+ * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+/*
+ * Abstract:
+ * OSM QoS parser functions.
+ *
+ * Environment:
+ * Linux User Mode
+ *
+ * Author:
+ * Yevgeny Kliteynik, Mellanox
+ */
+
+#include <opensm/osm_qos_parser.h>
+#include <opensm/osm_qos_parser_y.h>
+#include <opensm/osm_partition.h>
+
+/**********************************************************************
+ **********************************************************************/
+
+boolean_t osm_qos_parser_is_port_in_group(
+ IN const osm_pr_rcv_t * const p_rcv,
+ IN osm_physp_t * p_physp,
+ IN osm_qos_port_group_t * p_port_group)
+{
+ uint16_t i;
+ osm_node_t * p_node = osm_physp_get_node_ptr(p_physp);
+ osm_qos_uint8_vector_item_t * p_uint8_vector_item = NULL;
+ osm_qos_uint64_vector_item_t * p_uint64_vector_item = NULL;
+ osm_qos_string_vector_item_t * p_string_vector_item = NULL;
+ osm_prtn_t * p_prtn = NULL;
+ ib_net64_t port_guid = osm_physp_get_port_guid(p_physp);
+ uint64_t port_guid_ho = cl_ntoh64(port_guid);
+ uint8_t node_type = osm_node_get_type(p_node);
+ char desc[IB_NODE_DESCRIPTION_SIZE + 1];
+
+ for (i = 0; i < cl_ptr_vector_get_size(&p_port_group->port_guids); i++)
+ {
+ cl_ptr_vector_at(&p_port_group->port_guids, i, (void **)&p_uint64_vector_item);
+ if ( memcmp(&p_uint64_vector_item->value, &port_guid_ho, sizeof(uint64_t)) == 0 )
+ return TRUE;
+ }
+
+ for (i = 0; i < cl_ptr_vector_get_size(&p_port_group->node_types); i++)
+ {
+ cl_ptr_vector_at(&p_port_group->node_types, i, (void **)&p_uint8_vector_item);
+ if (p_uint8_vector_item->value == node_type)
+ return TRUE;
+ }
+
+ for (i = 0; i < cl_ptr_vector_get_size(&p_port_group->partitions); i++)
+ {
+ cl_ptr_vector_at(&p_port_group->partitions, i, (void **)&p_string_vector_item);
+ p_prtn = osm_prtn_find_by_name(p_rcv->p_subn, p_string_vector_item->str);
+ if (!p_prtn)
+ continue;
+ if (osm_prtn_is_guid(p_prtn, port_guid))
+ return TRUE;
+ }
+
+ memcpy(desc, p_node->node_desc.description, IB_NODE_DESCRIPTION_SIZE);
+ desc[IB_NODE_DESCRIPTION_SIZE] = '\0';
+ printf("Description: <%s>\n\n",desc);
+
+ for (i = 0; i < cl_ptr_vector_get_size(&p_port_group->port_names); i++)
+ {
+ cl_ptr_vector_at(&p_port_group->port_names, i, (void **)&p_string_vector_item);
+ //p_string_vector_item->str;
+ }
+
+ /*
+ * TODO: //cl_ptr_vector_t port_names; (vector of string)
+ *
+ * <!-- using names obtained by concatenation of first
+ * 2 words of NodeDescription and port number -->
+ * <port-name>vs1/HCA-1/P1</port-name>
+ * <port-name>vs3/HCA-1/P1</port-name>
+ */
+
+ return FALSE;
+}
+
+/**********************************************************************
+ **********************************************************************/
+
+void osm_qos_parser_get_qos_level_by_pr(
+ IN const osm_pr_rcv_t * const p_rcv,
+ IN const ib_path_rec_t * const p_pr,
+ IN const osm_port_t* const p_src_port,
+ IN const osm_port_t* const p_dest_port,
+ IN const uint16_t dest_lid_ho,
+ IN const ib_net64_t comp_mask,
+ OUT osm_qos_level_t ** pp_qos_level)
+{
+ osm_qos_port_group_t * p_port_group = NULL;
+ osm_qos_match_rule_t * p_qos_match_rule = NULL;
+ osm_qos_level_t * p_qos_level = NULL;
+ osm_node_t * p_src_node;
+ osm_node_t * p_dest_node;
+ osm_physp_t * p_src_physp;
+ osm_physp_t * p_dest_physp;
+ uint8_t i;
+
+ OSM_LOG_ENTER( p_rcv->p_log, osm_qos_parser_get_qos_level_by_pr );
+
+ *pp_qos_level = NULL;
+ if (!p_qos_parse_tree)
+ goto Exit;
+
+ p_src_physp = osm_port_get_default_phys_ptr( p_src_port );
+ p_dest_physp = osm_port_get_default_phys_ptr( p_dest_port );
+
+ p_src_node = osm_physp_get_node_ptr( p_src_physp );
+ p_dest_node = osm_physp_get_node_ptr( p_dest_physp );
+
+ /* if destination node is switch, the dest port should be port 0 */
+ if( p_dest_node->sw )
+ p_dest_physp = osm_switch_get_route_by_lid(p_dest_node->sw, cl_ntoh16(dest_lid_ho));
+
+
+ /* Go over all QoS match rules.
+ For every rule, check whether this pathrecord request
+ (src/dst ports) should comply a certain QoS match rule. */
+ for (i = 0; i < cl_ptr_vector_get_size(&p_qos_parse_tree->qos_match_rules); i++)
+ {
+ cl_ptr_vector_at(&p_qos_parse_tree->qos_match_rules, i, (void **)&p_qos_match_rule);
+
+ if (p_qos_match_rule->source)
+ {
+ osm_qos_parser_get_port_group_by_name(p_qos_parse_tree,
+ p_qos_match_rule->source,
+ &p_port_group);
+ if (p_port_group)
+ {
+ /* Port group with the given name found.
+ Now check if the src port is member of this group */
+ if ( !osm_qos_parser_is_port_in_group(p_rcv, p_src_physp, p_port_group) )
+ {
+ /* Src port is not a member of the specified port group.
+ Go to the next match rule. */
+ continue;
+ }
+ }
+ }
+
+ if (p_qos_match_rule->destination)
+ {
+ osm_qos_parser_get_port_group_by_name(p_qos_parse_tree,
+ p_qos_match_rule->destination,
+ &p_port_group);
+ if (p_port_group)
+ {
+ /* Port group with the given name found.
+ Now check if the dest port is member of this group */
+ if ( !osm_qos_parser_is_port_in_group(p_rcv, p_dest_physp, p_port_group) )
+ {
+ /* Dest port is not a member of the specified port group.
+ Go to the next match rule. */
+ continue;
+ }
+ }
+ }
+
+ /* Now check QoS class of the path record */
+
+ if (cl_ptr_vector_get_size(&p_qos_match_rule->classes) > 0)
+ {
+ /* This match rule specifies list of QoS classes.
+ Check whether this path record request contains one these classes. */
+ if (comp_mask & IB_PR_COMPMASK_QOS_CLASS)
+ {
+ boolean_t found = FALSE;
+ osm_qos_uint32_vector_item_t * p_uint32_vector_item = NULL;
+ for (i = 0; i < cl_ptr_vector_get_size(&p_qos_match_rule->classes); i++)
+ {
+ cl_ptr_vector_at(&p_qos_match_rule->classes, i, (void **)&p_uint32_vector_item);
+ if (p_uint32_vector_item->value == ib_path_rec_qos_class(p_pr))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ {
+ /* Path record QoS class doesn't match anything in the match rule.
+ Go to the next match rule. */
+ continue;
+ }
+ }
+ else
+ {
+ /* Path record doesn't have QoS class.
+ Go to the next match rule. */
+ continue;
+ }
+ }
+
+ /* Done checking QoS class of the path record.
+ Now check service id. */
+
+ if (cl_ptr_vector_get_size(&p_qos_match_rule->services) > 0)
+ {
+ /* This match rule specifies list of services.
+ Check whether this path record request contains one these services. */
+ if (comp_mask & IB_PR_COMPMASK_SERVICEID)
+ {
+ boolean_t found = FALSE;
+ osm_qos_uint64_vector_item_t * p_uint64_vector_item = NULL;
+ for (i = 0; i < cl_ptr_vector_get_size(&p_qos_match_rule->services); i++)
+ {
+ cl_ptr_vector_at(&p_qos_match_rule->services, i, (void **)&p_uint64_vector_item);
+ if (memcmp(&p_uint64_vector_item->value,&p_pr->service_id,sizeof(uint64_t)) == 0)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ {
+ /* Path record service id doesn't match anything in the match rule.
+ Go to the next match rule. */
+ continue;
+ }
+ }
+ else
+ {
+ /* Path record doesn't have service id.
+ Go to the next match rule. */
+ continue;
+ }
+ }
+
+ /* Done checking service id of the path record.
+ We had match on every criteria, so the query matches this match rule.
+ Now get the QoS Level that has to be applied on this path record. */
+ osm_qos_parser_get_qos_level_by_sn(p_qos_parse_tree,
+ p_qos_match_rule->qos_level_sn,
+ &p_qos_level);
+ break;
+ }
+
+ if (p_qos_level)
+ {
+ /* there is a QoS Level that should be applied to this query */
+ *pp_qos_level = p_qos_level;
+ osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+ "osm_qos_parser_get_qos_level_by_pr: "
+ "PathRecord request:"
+ "Src port 0x%016" PRIx64 ", "
+ "Dst port 0x%016" PRIx64 "\n",
+ cl_ntoh64(osm_physp_get_port_guid(p_src_physp)),
+ cl_ntoh64(osm_physp_get_port_guid(p_dest_physp)) );
+ osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+ "osm_qos_parser_get_qos_level_by_pr: "
+ "Applying QoS Level %d (%s)\n",
+ p_qos_level->sn,
+ (p_qos_level->use)? p_qos_level->use : "no description" );
+ }
+
+ Exit:
+ OSM_LOG_EXIT( p_rcv->p_log );
+}
+
+/***************************************************
+ ***************************************************/
+
+void osm_qos_parser_get_port_group_by_name(
+ IN osm_qos_parse_tree_t * p_qos_parse_tree,
+ IN const char * group_name,
+ OUT osm_qos_port_group_t ** pp_port_group)
+{
+ uint32_t i;
+ osm_qos_port_group_t * p_port_group = NULL;
+ *pp_port_group = NULL;
+
+ for (i = 0; i < cl_ptr_vector_get_size(&p_qos_parse_tree->port_groups); i++)
+ {
+ cl_ptr_vector_at(&p_qos_parse_tree->port_groups, i, (void **)&p_port_group);
+
+ if (!p_port_group->name)
+ continue;
+
+ if (strcasecmp(p_port_group->name,group_name) == 0)
+ *pp_port_group = p_port_group;
+ return;
+ }
+}
+
+/***************************************************
+ ***************************************************/
+
+void osm_qos_parser_get_qos_level_by_sn(
+ IN osm_qos_parse_tree_t * p_qos_parse_tree,
+ IN uint32_t sn,
+ OUT osm_qos_level_t ** pp_qos_level)
+{
+ uint32_t i;
+ osm_qos_level_t * p_qos_level = NULL;
+
+ *pp_qos_level = NULL;
+
+ for (i = 0; i < cl_ptr_vector_get_size(&p_qos_parse_tree->qos_levels); i++)
+ {
+ cl_ptr_vector_at(&p_qos_parse_tree->qos_levels, i, (void **)&p_qos_level);
+
+ if (p_qos_level->sn == sn)
+ *pp_qos_level = p_qos_level;
+ return;
+ }
+}
+
+/***************************************************
+ ***************************************************/
+
+/* free all the memory occupied by the parse tree data structure */
+void osm_qos_parser_destroy_parse_tree(
+ IN osm_qos_parse_tree_t * p_qos_parse_tree)
+{
+ uint32_t i;
+ uint32_t j;
+
+ osm_qos_port_group_t * p_port_group = NULL;
+ osm_qos_sl2vl_scope_t * p_sl2vl_scope = NULL;
+ osm_qos_vlarb_scope_t * p_vlarb_scope = NULL;
+ osm_qos_level_t * p_qos_level = NULL;
+ osm_qos_match_rule_t * p_qos_match_rule = NULL;
+
+ osm_qos_string_vector_item_t * p_str_vector_item = NULL;
+ osm_qos_uint64_vector_item_t * p_uint64_vector_item = NULL;
+ osm_qos_uint32_vector_item_t * p_uint32_vector_item = NULL;
+ osm_qos_vlarb_hl_vector_item_t * p_vlarb_hl_vector_item = NULL;
+
+ for (i = 0; i < cl_ptr_vector_get_size(&p_qos_parse_tree->port_groups); i++)
+ {
+ cl_ptr_vector_at(&p_qos_parse_tree->port_groups, i, (void **)&p_port_group);
+
+ if (p_port_group->name)
+ free(p_port_group->name);
+ if (p_port_group->use)
+ free(p_port_group->use);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_port_group->port_guids); j++)
+ {
+ cl_ptr_vector_at(&p_port_group->port_guids, j, (void **)&p_uint64_vector_item);
+ free(p_uint64_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_port_group->port_guids);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_port_group->port_names); j++)
+ {
+ cl_ptr_vector_at(&p_port_group->port_names, j, (void **)&p_str_vector_item);
+ if (p_str_vector_item->str)
+ free(p_str_vector_item->str);
+ free(p_str_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_port_group->port_names);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_port_group->partitions); j++)
+ {
+ cl_ptr_vector_at(&p_port_group->partitions, j, (void **)&p_str_vector_item);
+ if (p_str_vector_item->str)
+ free(p_str_vector_item->str);
+ free(p_str_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_port_group->partitions);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_port_group->node_types); j++)
+ {
+ cl_ptr_vector_at(&p_port_group->node_types, j, (void **)&p_uint32_vector_item);
+ free(p_uint32_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_port_group->node_types);
+
+ free(p_port_group);
+ }
+ cl_ptr_vector_destroy(&p_qos_parse_tree->port_groups);
+
+ for (i = 0; i < cl_ptr_vector_get_size(&p_qos_parse_tree->sl2vl_tables); i++)
+ {
+ cl_ptr_vector_at(&p_qos_parse_tree->sl2vl_tables, i, (void **)&p_sl2vl_scope);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_sl2vl_scope->groups); j++)
+ {
+ cl_ptr_vector_at(&p_sl2vl_scope->groups, j, (void **)&p_str_vector_item);
+ if (p_str_vector_item->str)
+ free(p_str_vector_item->str);
+ free(p_str_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_sl2vl_scope->groups);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_sl2vl_scope->from); j++)
+ {
+ cl_ptr_vector_at(&p_sl2vl_scope->from, j, (void **)&p_str_vector_item);
+ if (p_str_vector_item->str)
+ free(p_str_vector_item->str);
+ free(p_str_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_sl2vl_scope->from);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_sl2vl_scope->to); j++)
+ {
+ cl_ptr_vector_at(&p_sl2vl_scope->to, j, (void **)&p_str_vector_item);
+ if (p_str_vector_item->str)
+ free(p_str_vector_item->str);
+ free(p_str_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_sl2vl_scope->to);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_sl2vl_scope->across_from); j++)
+ {
+ cl_ptr_vector_at(&p_sl2vl_scope->across_from, j, (void **)&p_str_vector_item);
+ if (p_str_vector_item->str)
+ free(p_str_vector_item->str);
+ free(p_str_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_sl2vl_scope->across_from);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_sl2vl_scope->across_to); j++)
+ {
+ cl_ptr_vector_at(&p_sl2vl_scope->across_to, j, (void **)&p_str_vector_item);
+ if (p_str_vector_item->str)
+ free(p_str_vector_item->str);
+ free(p_str_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_sl2vl_scope->across_to);
+
+ free(p_sl2vl_scope);
+ }
+ cl_ptr_vector_destroy(&p_qos_parse_tree->sl2vl_tables);
+
+ for (i = 0; i < cl_ptr_vector_get_size(&p_qos_parse_tree->vlarb_tables); i++)
+ {
+ cl_ptr_vector_at(&p_qos_parse_tree->vlarb_tables, i, (void **)&p_vlarb_scope);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_vlarb_scope->groups); j++)
+ {
+ cl_ptr_vector_at(&p_vlarb_scope->groups, j, (void **)&p_str_vector_item);
+ if (p_str_vector_item->str)
+ free(p_str_vector_item->str);
+ free(p_str_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_vlarb_scope->groups);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_vlarb_scope->across); j++)
+ {
+ cl_ptr_vector_at(&p_vlarb_scope->across, j, (void **)&p_str_vector_item);
+ if (p_str_vector_item->str)
+ free(p_str_vector_item->str);
+ free(p_str_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_vlarb_scope->across);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_vlarb_scope->vlarb_highs); j++)
+ {
+ cl_ptr_vector_at(&p_vlarb_scope->vlarb_highs, j, (void **)&p_vlarb_hl_vector_item);
+ free(p_vlarb_hl_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_vlarb_scope->vlarb_highs);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_vlarb_scope->vlarb_lows); j++)
+ {
+ cl_ptr_vector_at(&p_vlarb_scope->vlarb_lows, j, (void **)&p_vlarb_hl_vector_item);
+ free(p_vlarb_hl_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_vlarb_scope->vlarb_lows);
+
+ free(p_vlarb_scope);
+ }
+ cl_ptr_vector_destroy(&p_qos_parse_tree->vlarb_tables);
+
+ for (i = 0; i < cl_ptr_vector_get_size(&p_qos_parse_tree->qos_levels); i++)
+ {
+ cl_ptr_vector_at(&p_qos_parse_tree->qos_levels, i, (void **)&p_qos_level);
+ if (p_qos_level->use)
+ free(p_qos_level->use);
+ free(p_qos_level);
+ }
+ cl_ptr_vector_destroy(&p_qos_parse_tree->qos_levels);
+
+ for (i = 0; i < cl_ptr_vector_get_size(&p_qos_parse_tree->qos_match_rules); i++)
+ {
+ cl_ptr_vector_at(&p_qos_parse_tree->qos_match_rules, i, (void **)&p_qos_match_rule);
+
+ if (p_qos_match_rule->use)
+ free(p_qos_match_rule->use);
+ if (p_qos_match_rule->source)
+ free(p_qos_match_rule->source);
+ if (p_qos_match_rule->destination)
+ free(p_qos_match_rule->destination);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_qos_match_rule->services); j++)
+ {
+ cl_ptr_vector_at(&p_qos_match_rule->services, j, (void **)&p_uint32_vector_item);
+ free(p_uint32_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_qos_match_rule->services);
+
+ for (j = 0; j < cl_ptr_vector_get_size(&p_qos_match_rule->classes); j++)
+ {
+ cl_ptr_vector_at(&p_qos_match_rule->classes, j, (void **)&p_uint32_vector_item);
+ free(p_uint32_vector_item);
+ }
+ cl_ptr_vector_destroy(&p_qos_match_rule->classes);
+
+ free(p_qos_match_rule);
+ }
+ cl_ptr_vector_destroy(&p_qos_parse_tree->qos_match_rules);
+
+ free(p_qos_parse_tree);
+}
+
+/***************************************************
+ ***************************************************/
+
+
--
1.4.4.1.GIT
More information about the general
mailing list