[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