[ofa-general] Re: [PATCH 3/7 V3] osm: QoS policy C & H files

Yevgeny Kliteynik kliteyn at dev.mellanox.co.il
Tue Sep 11 07:51:53 PDT 2007


Hi Sasha,

 >> +typedef struct _osm_qos_policy_t {
 >> +	cl_list_t port_groups;			/* list of osm_qos_port_group_t */
 >> +	cl_list_t sl2vl_tables;			/* list of osm_qos_sl2vl_scope_t */
 >> +	cl_list_t vlarb_tables;			/* list of osm_qos_vlarb_scope_t */
 >> +	cl_list_t qos_levels;			/* list of osm_qos_level_t */
 >> +	cl_list_t qos_match_rules;		/* list of osm_qos_match_rule_t */
 >
 > Here and above - where possible please use cl_qlist_t instead of
 > cl_list_t - it is _much_ faster (I did some benchmarking when worked
 > on up/down performance issues).

What about cl_map_t vs cl_qmap_t?
Is the difference there significant?

-- Yevgeny

Sasha Khapyorsky wrote:
> On 02:09 Tue 28 Aug     , Yevgeny Kliteynik wrote:
>> QoS policy data structures and functions
>>
>> Signed-off-by: Yevgeny Kliteynik <kliteyn at dev.mellanox.co.il>
> 
> Applied. Thanks.
> 
> I still have some comments (below) and expect it will be addressed.
> 
> Sasha
> 
>> ---
>>  opensm/include/opensm/osm_qos_policy.h |  189 +++++++
>>  opensm/opensm/osm_qos_policy.c         |  921 ++++++++++++++++++++++++++++++++
>>  2 files changed, 1110 insertions(+), 0 deletions(-)
>>  create mode 100644 opensm/include/opensm/osm_qos_policy.h
>>  create mode 100644 opensm/opensm/osm_qos_policy.c
>>
>> diff --git a/opensm/include/opensm/osm_qos_policy.h b/opensm/include/opensm/osm_qos_policy.h
>> new file mode 100644
>> index 0000000..dd15f99
>> --- /dev/null
>> +++ b/opensm/include/opensm/osm_qos_policy.h
>> @@ -0,0 +1,189 @@
>> +/*
>> + * 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:
>> + *    Declaration of OSM QoS Policy data types and functions.
>> + *
>> + * Environment:
>> + *    Linux User Mode
>> + *
>> + * Author:
>> + *    Yevgeny Kliteynik, Mellanox
>> + */
>> +
>> +#ifndef OSM_QOS_POLICY_H
>> +#define OSM_QOS_POLICY_H
>> +
>> +#include <iba/ib_types.h>
>> +#include <complib/cl_list.h>
>> +#include <opensm/osm_port.h>
>> +#include <opensm/osm_sa_path_record.h>
>> +
>> +#define YYSTYPE char *
>> +#define OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH  128
>> +#define OSM_QOS_POLICY_DEFAULT_LEVEL_NAME   "default"
>> +
>> +/***************************************************/
>> +
>> +typedef struct _osm_qos_port_group_t {
>> +	char *name;			/* single string (this port group name) */
>> +	char *use;			/* single string (description) */
>> +	cl_list_t port_name_list;	/* list of port names (.../.../...) */
>> +	uint64_t **guid_range_arr;	/* array of guid ranges (pair of 64-bit guids) */
> 
> Instead of uint64_t ** use something like:
> 
> 	struct range {
> 		uint64_t min, max;
> 	}
> 
>> +	unsigned guid_range_len;	/* num of guid ranges in the array */
>> +	cl_list_t partition_list;	/* list of partition names */
> 
> Why not pkey range here? (by name partition search is extermely slow).
> 
>> +	boolean_t node_type_ca;
>> +	boolean_t node_type_switch;
>> +	boolean_t node_type_router;
>> +	boolean_t node_type_self;
> 
> This probably could be optimized by using bitmask. Then instead of four
> separate checks you will start with single 'if (node_type_mask) ...'.
> 
>> +} osm_qos_port_group_t;
>> +
>> +/***************************************************/
>> +
>> +typedef struct _osm_qos_vlarb_scope_t {
>> +	cl_list_t group_list;		/* list of group names (strings) */
>> +	cl_list_t across_list;		/* list of 'across' group names (strings) */
>> +	cl_list_t vlarb_high_list;	/* list of num pairs (n:m,...), 32-bit values */
>> +	cl_list_t vlarb_low_list;	/* list of num pairs (n:m,...), 32-bit values */
>> +	uint32_t vl_high_limit;		/* single integer */
>> +	boolean_t vl_high_limit_set;
>> +} osm_qos_vlarb_scope_t;
>> +
>> +/***************************************************/
>> +
>> +typedef struct _osm_qos_sl2vl_scope_t {
>> +	cl_list_t group_list;		/* list of strings (port group names) */
>> +	boolean_t from[OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH];
>> +	boolean_t to[OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH];
>> +	cl_list_t across_from_list;	/* list of strings (port group names) */
>> +	cl_list_t across_to_list;	/* list of strings (port group names) */
>> +	uint8_t sl2vl_table[16];	/* array of sl2vl values */
>> +	boolean_t sl2vl_table_set;
>> +} osm_qos_sl2vl_scope_t;
>> +
>> +/***************************************************/
>> +
>> +typedef struct _osm_qos_level_t {
>> +	char *use;
>> +	char *name;
>> +	uint8_t sl;
>> +	boolean_t sl_set;
>> +	uint8_t mtu_limit;
>> +	boolean_t mtu_limit_set;
>> +	uint8_t rate_limit;
>> +	boolean_t rate_limit_set;
>> +	uint8_t pkt_life;
>> +	boolean_t pkt_life_set;
>> +	uint64_t **path_bits_range_arr;	/* array of bit ranges (real values are 32bits) */
>> +	unsigned path_bits_range_len;	/* num of bit ranges in the array */
>> +	uint64_t **pkey_range_arr;	/* array of PKey ranges (real values are 16bits) */
>> +	unsigned pkey_range_len;
>> +} osm_qos_level_t;
>> +
>> +
>> +/***************************************************/
>> +
>> +typedef struct _osm_qos_match_rule_t {
>> +	char *use;
>> +	cl_list_t source_list;			/* list of strings */
>> +	cl_list_t source_group_list;		/* list of pointers to relevant port-group */
>> +	cl_list_t destination_list;		/* list of strings */
>> +	cl_list_t destination_group_list;	/* list of pointers to relevant port-group */
>> +	char *qos_level_name;
>> +	osm_qos_level_t *p_qos_level;
>> +	uint64_t **service_id_range_arr;	/* array of SID ranges (64-bit values) */
>> +	unsigned service_id_range_len;
>> +	uint64_t **qos_class_range_arr;		/* array of QoS Class ranges (real values are 16bits) */
>> +	unsigned qos_class_range_len;
>> +	uint64_t **pkey_range_arr;		/* array of PKey ranges (real values are 16bits) */
>> +	unsigned pkey_range_len;
>> +} osm_qos_match_rule_t;
>> +
>> +/***************************************************/
>> +
>> +typedef struct _osm_qos_policy_t {
>> +	cl_list_t port_groups;			/* list of osm_qos_port_group_t */
>> +	cl_list_t sl2vl_tables;			/* list of osm_qos_sl2vl_scope_t */
>> +	cl_list_t vlarb_tables;			/* list of osm_qos_vlarb_scope_t */
>> +	cl_list_t qos_levels;			/* list of osm_qos_level_t */
>> +	cl_list_t qos_match_rules;		/* list of osm_qos_match_rule_t */
> 
> Here and above - where possible please use cl_qlist_t instead of
> cl_list_t - it is _much_ faster (I did some benchmarking when worked
> on up/down performance issues).
> 
>> +	osm_qos_level_t *p_default_qos_level;	/* default QoS level */
>> +} osm_qos_policy_t;
>> +
>> +/***************************************************/
>> +
>> +osm_qos_port_group_t * osm_qos_policy_port_group_create();
>> +void osm_qos_policy_port_group_destroy(osm_qos_port_group_t * p_port_group);
>> +
>> +osm_qos_vlarb_scope_t * osm_qos_policy_vlarb_scope_create();
>> +void osm_qos_policy_vlarb_scope_destroy(osm_qos_vlarb_scope_t * p_vlarb_scope);
>> +
>> +osm_qos_sl2vl_scope_t * osm_qos_policy_sl2vl_scope_create();
>> +void osm_qos_policy_sl2vl_scope_destroy(osm_qos_sl2vl_scope_t * p_sl2vl_scope);
>> +
>> +osm_qos_level_t * osm_qos_policy_qos_level_create();
>> +void osm_qos_policy_qos_level_destroy(osm_qos_level_t * p_qos_level);
>> +
>> +boolean_t osm_qos_level_has_pkey(IN const osm_qos_level_t * p_qos_level,
>> +				 IN ib_net16_t pkey);
>> +
>> +ib_net16_t osm_qos_level_get_shared_pkey(IN const osm_qos_level_t * p_qos_level,
>> +					 IN const osm_physp_t * p_src_physp,
>> +					 IN const osm_physp_t * p_dest_physp);
>> +
>> +osm_qos_match_rule_t * osm_qos_policy_match_rule_create();
>> +void osm_qos_policy_match_rule_destroy(osm_qos_match_rule_t * p_match_rule);
>> +
>> +osm_qos_policy_t * osm_qos_policy_create();
>> +void osm_qos_policy_destroy(osm_qos_policy_t * p_qos_policy);
>> +int osm_qos_policy_validate(osm_qos_policy_t * p_qos_policy, osm_log_t * p_log);
>> +
>> +void osm_qos_policy_get_qos_level_by_pr(IN const osm_qos_policy_t * p_qos_policy,
>> +					IN const osm_pr_rcv_t * p_rcv,
>> +					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,
>> +					OUT osm_qos_level_t ** pp_qos_level);
>> +
>> +/***************************************************/
>> +
>> +int osm_qos_parse_policy_file(IN osm_subn_t * const p_subn);
>> +
>> +/***************************************************/
>> +
>> +#endif				/* ifndef OSM_QOS_POLICY_H */
>> +
>> diff --git a/opensm/opensm/osm_qos_policy.c b/opensm/opensm/osm_qos_policy.c
>> new file mode 100644
>> index 0000000..a5a8856
>> --- /dev/null
>> +++ b/opensm/opensm/osm_qos_policy.c
>> @@ -0,0 +1,921 @@
>> +/*
>> + * 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 Policy functions.
>> + *
>> + * Environment:
>> + *    Linux User Mode
>> + *
>> + * Author:
>> + *    Yevgeny Kliteynik, Mellanox
>> + */
>> +
>> +#include <stdio.h>
>> +#include <assert.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +#include <ctype.h>
>> +#include <opensm/osm_log.h>
>> +#include <opensm/osm_node.h>
>> +#include <opensm/osm_port.h>
>> +#include <opensm/osm_partition.h>
>> +#include <opensm/osm_qos_policy.h>
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +static boolean_t
>> +__is_num_in_range_arr(uint64_t ** range_arr,
>> +		  unsigned range_arr_len, uint64_t num)
>> +{
>> +	unsigned ind_1 = 0;
>> +	unsigned ind_2 = range_arr_len - 1;
>> +	unsigned ind_mid;
>> +
>> +	if (!range_arr || !range_arr_len)
>> +		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--;
>> +	}
>> +
>> +	return FALSE;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +static void __free_single_element(void *p_element, void *context)
>> +{
>> +	if (p_element)
>> +		free(p_element);
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +osm_qos_port_group_t *osm_qos_policy_port_group_create()
>> +{
>> +	osm_qos_port_group_t *p =
>> +	    (osm_qos_port_group_t *) malloc(sizeof(osm_qos_port_group_t));
>> +	if (!p)
>> +		return NULL;
>> +
>> +	memset(p, 0, sizeof(osm_qos_port_group_t));
>> +
>> +	cl_list_init(&p->port_name_list, 10);
>> +	cl_list_init(&p->partition_list, 10);
>> +
>> +	return p;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +void osm_qos_policy_port_group_destroy(osm_qos_port_group_t * p)
>> +{
>> +	unsigned i;
>> +
>> +	if (!p)
>> +		return;
>> +
>> +	if (p->name)
>> +		free(p->name);
>> +	if (p->use)
>> +		free(p->use);
>> +
>> +	for (i = 0; i < p->guid_range_len; i++)
>> +		free(p->guid_range_arr[i]);
>> +	if (p->guid_range_arr)
>> +		free(p->guid_range_arr);
>> +
>> +	cl_list_apply_func(&p->port_name_list, __free_single_element, NULL);
>> +	cl_list_remove_all(&p->port_name_list);
>> +	cl_list_destroy(&p->port_name_list);
>> +
>> +	cl_list_apply_func(&p->partition_list, __free_single_element, NULL);
>> +	cl_list_remove_all(&p->partition_list);
>> +	cl_list_destroy(&p->partition_list);
>> +
>> +	free(p);
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +osm_qos_vlarb_scope_t *osm_qos_policy_vlarb_scope_create()
>> +{
>> +	osm_qos_vlarb_scope_t *p =
>> +	    (osm_qos_vlarb_scope_t *) malloc(sizeof(osm_qos_sl2vl_scope_t));
>> +	if (!p)
>> +		return NULL;
>> +
>> +	memset(p, 0, sizeof(osm_qos_vlarb_scope_t));
>> +
>> +	cl_list_init(&p->group_list, 10);
>> +	cl_list_init(&p->across_list, 10);
>> +	cl_list_init(&p->vlarb_high_list, 10);
>> +	cl_list_init(&p->vlarb_low_list, 10);
>> +
>> +	return p;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +void osm_qos_policy_vlarb_scope_destroy(osm_qos_vlarb_scope_t * p)
>> +{
>> +	if (!p)
>> +		return;
>> +
>> +	cl_list_apply_func(&p->group_list, __free_single_element, NULL);
>> +	cl_list_apply_func(&p->across_list, __free_single_element, NULL);
>> +	cl_list_apply_func(&p->vlarb_high_list, __free_single_element, NULL);
>> +	cl_list_apply_func(&p->vlarb_low_list, __free_single_element, NULL);
>> +
>> +	cl_list_remove_all(&p->group_list);
>> +	cl_list_remove_all(&p->across_list);
>> +	cl_list_remove_all(&p->vlarb_high_list);
>> +	cl_list_remove_all(&p->vlarb_low_list);
>> +
>> +	cl_list_destroy(&p->group_list);
>> +	cl_list_destroy(&p->across_list);
>> +	cl_list_destroy(&p->vlarb_high_list);
>> +	cl_list_destroy(&p->vlarb_low_list);
>> +
>> +	free(p);
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +osm_qos_sl2vl_scope_t *osm_qos_policy_sl2vl_scope_create()
>> +{
>> +	osm_qos_sl2vl_scope_t *p =
>> +	    (osm_qos_sl2vl_scope_t *) malloc(sizeof(osm_qos_sl2vl_scope_t));
>> +	if (!p)
>> +		return NULL;
>> +
>> +	memset(p, 0, sizeof(osm_qos_vlarb_scope_t));
>> +
>> +	cl_list_init(&p->group_list, 10);
>> +	cl_list_init(&p->across_from_list, 10);
>> +	cl_list_init(&p->across_to_list, 10);
>> +
>> +	return p;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +void osm_qos_policy_sl2vl_scope_destroy(osm_qos_sl2vl_scope_t * p)
>> +{
>> +	if (!p)
>> +		return;
>> +
>> +	cl_list_apply_func(&p->group_list, __free_single_element, NULL);
>> +	cl_list_apply_func(&p->across_from_list, __free_single_element, NULL);
>> +	cl_list_apply_func(&p->across_to_list, __free_single_element, NULL);
>> +
>> +	cl_list_remove_all(&p->group_list);
>> +	cl_list_remove_all(&p->across_from_list);
>> +	cl_list_remove_all(&p->across_to_list);
>> +
>> +	cl_list_destroy(&p->group_list);
>> +	cl_list_destroy(&p->across_from_list);
>> +	cl_list_destroy(&p->across_to_list);
>> +
>> +	free(p);
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +osm_qos_level_t *osm_qos_policy_qos_level_create()
>> +{
>> +	osm_qos_level_t *p =
>> +	    (osm_qos_level_t *) malloc(sizeof(osm_qos_level_t));
>> +	if (!p)
>> +		return NULL;
>> +	memset(p, 0, sizeof(osm_qos_level_t));
>> +	return p;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +void osm_qos_policy_qos_level_destroy(osm_qos_level_t * p)
>> +{
>> +	unsigned i;
>> +
>> +	if (!p)
>> +		return;
>> +
>> +	if (p->use)
>> +		free(p->use);
>> +
>> +	for (i = 0; i < p->path_bits_range_len; i++)
>> +		free(p->path_bits_range_arr[i]);
>> +	if (p->path_bits_range_arr)
>> +		free(p->path_bits_range_arr);
>> +
>> +	free(p);
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +boolean_t osm_qos_level_has_pkey(IN const osm_qos_level_t * p_qos_level,
>> +				 IN ib_net16_t pkey)
>> +{
>> +	if (!p_qos_level || !p_qos_level->pkey_range_len)
>> +		return FALSE;
>> +	return __is_num_in_range_arr(p_qos_level->pkey_range_arr,
>> +				     p_qos_level->pkey_range_len,
>> +				     cl_ntoh16(pkey));
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +ib_net16_t osm_qos_level_get_shared_pkey(IN const osm_qos_level_t * p_qos_level,
>> +					 IN const osm_physp_t * p_src_physp,
>> +					 IN const osm_physp_t * p_dest_physp)
>> +{
>> +	unsigned i;
>> +	uint16_t pkey_ho = 0;
>> +
>> +	if (!p_qos_level || !p_qos_level->pkey_range_len)
>> +		return 0;
>> +
>> +	/*
>> +	 * ToDo: This approach is not optimal.
>> +	 *       Think how to find shared pkey that also exists
>> +	 *       in QoS level in less runtime.
>> +	 */
> 
> When this "ToDo" will be addressed?
> 
>> +
>> +	for (i = 0; i < p_qos_level->pkey_range_len; i++) {
>> +		for (pkey_ho = p_qos_level->pkey_range_arr[i][0];
>> +		     pkey_ho <= p_qos_level->pkey_range_arr[i][1]; pkey_ho++) {
>> +			if (osm_physp_share_this_pkey
>> +			    (p_src_physp, p_dest_physp, cl_hton16(pkey_ho)))
>> +				return cl_hton16(pkey_ho);
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +osm_qos_match_rule_t *osm_qos_policy_match_rule_create()
>> +{
>> +	osm_qos_match_rule_t *p =
>> +	    (osm_qos_match_rule_t *) malloc(sizeof(osm_qos_match_rule_t));
>> +	if (!p)
>> +		return NULL;
>> +
>> +	memset(p, 0, sizeof(osm_qos_match_rule_t));
>> +
>> +	cl_list_init(&p->source_list, 10);
>> +	cl_list_init(&p->source_group_list, 10);
>> +	cl_list_init(&p->destination_list, 10);
>> +	cl_list_init(&p->destination_group_list, 10);
>> +
>> +	return p;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +void osm_qos_policy_match_rule_destroy(osm_qos_match_rule_t * p)
>> +{
>> +	unsigned i;
>> +
>> +	if (!p)
>> +		return;
>> +
>> +	if (p->qos_level_name)
>> +		free(p->qos_level_name);
>> +	if (p->use)
>> +		free(p->use);
>> +
>> +	for (i = 0; i < p->service_id_range_len; i++)
>> +		free(p->service_id_range_arr[i]);
>> +	if (p->service_id_range_arr)
>> +		free(p->service_id_range_arr);
>> +
>> +	for (i = 0; i < p->qos_class_range_len; i++)
>> +		free(p->qos_class_range_arr[i]);
>> +	if (p->qos_class_range_arr)
>> +		free(p->qos_class_range_arr);
>> +
>> +	cl_list_apply_func(&p->source_list, __free_single_element, NULL);
>> +	cl_list_remove_all(&p->source_list);
>> +	cl_list_destroy(&p->source_list);
>> +
>> +	cl_list_remove_all(&p->source_group_list);
>> +	cl_list_destroy(&p->source_group_list);
>> +
>> +	cl_list_apply_func(&p->destination_list, __free_single_element, NULL);
>> +	cl_list_remove_all(&p->destination_list);
>> +	cl_list_destroy(&p->destination_list);
>> +
>> +	cl_list_remove_all(&p->destination_group_list);
>> +	cl_list_destroy(&p->destination_group_list);
>> +
>> +	free(p);
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +osm_qos_policy_t * osm_qos_policy_create()
>> +{
>> +	osm_qos_policy_t * p_qos_policy = (osm_qos_policy_t *)malloc(sizeof(osm_qos_policy_t));
>> +	if (!p_qos_policy)
>> +		return NULL;
>> +
>> +	memset(p_qos_policy, 0, sizeof(osm_qos_policy_t));
>> +
>> +	cl_list_construct(&p_qos_policy->port_groups);
>> +	cl_list_init(&p_qos_policy->port_groups, 10);
>> +
>> +	cl_list_construct(&p_qos_policy->vlarb_tables);
>> +	cl_list_init(&p_qos_policy->vlarb_tables, 10);
>> +
>> +	cl_list_construct(&p_qos_policy->sl2vl_tables);
>> +	cl_list_init(&p_qos_policy->sl2vl_tables, 10);
>> +
>> +	cl_list_construct(&p_qos_policy->qos_levels);
>> +	cl_list_init(&p_qos_policy->qos_levels, 10);
>> +
>> +	cl_list_construct(&p_qos_policy->qos_match_rules);
>> +	cl_list_init(&p_qos_policy->qos_match_rules, 10);
>> +
>> +	return p_qos_policy;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +void osm_qos_policy_destroy(osm_qos_policy_t * p_qos_policy)
>> +{
>> +	cl_list_iterator_t list_iterator;
>> +	osm_qos_port_group_t *p_port_group = NULL;
>> +	osm_qos_vlarb_scope_t *p_vlarb_scope = NULL;
>> +	osm_qos_sl2vl_scope_t *p_sl2vl_scope = NULL;
>> +	osm_qos_level_t *p_qos_level = NULL;
>> +	osm_qos_match_rule_t *p_qos_match_rule = NULL;
>> +
>> +	if (!p_qos_policy)
>> +		return;
>> +
>> +	list_iterator = cl_list_head(&p_qos_policy->port_groups);
>> +	while (list_iterator != cl_list_end(&p_qos_policy->port_groups)) {
>> +		p_port_group =
>> +		    (osm_qos_port_group_t *) cl_list_obj(list_iterator);
>> +		if (p_port_group)
>> +			osm_qos_policy_port_group_destroy(p_port_group);
>> +		list_iterator = cl_list_next(list_iterator);
>> +	}
>> +	cl_list_remove_all(&p_qos_policy->port_groups);
>> +	cl_list_destroy(&p_qos_policy->port_groups);
>> +
>> +	list_iterator = cl_list_head(&p_qos_policy->vlarb_tables);
>> +	while (list_iterator != cl_list_end(&p_qos_policy->vlarb_tables)) {
>> +		p_vlarb_scope =
>> +		    (osm_qos_vlarb_scope_t *) cl_list_obj(list_iterator);
>> +		if (p_vlarb_scope)
>> +			osm_qos_policy_vlarb_scope_destroy(p_vlarb_scope);
>> +		list_iterator = cl_list_next(list_iterator);
>> +	}
>> +	cl_list_remove_all(&p_qos_policy->vlarb_tables);
>> +	cl_list_destroy(&p_qos_policy->vlarb_tables);
>> +
>> +	list_iterator = cl_list_head(&p_qos_policy->sl2vl_tables);
>> +	while (list_iterator != cl_list_end(&p_qos_policy->sl2vl_tables)) {
>> +		p_sl2vl_scope =
>> +		    (osm_qos_sl2vl_scope_t *) cl_list_obj(list_iterator);
>> +		if (p_sl2vl_scope)
>> +			osm_qos_policy_sl2vl_scope_destroy(p_sl2vl_scope);
>> +		list_iterator = cl_list_next(list_iterator);
>> +	}
>> +	cl_list_remove_all(&p_qos_policy->sl2vl_tables);
>> +	cl_list_destroy(&p_qos_policy->sl2vl_tables);
>> +
>> +	list_iterator = cl_list_head(&p_qos_policy->qos_levels);
>> +	while (list_iterator != cl_list_end(&p_qos_policy->qos_levels)) {
>> +		p_qos_level = (osm_qos_level_t *) cl_list_obj(list_iterator);
>> +		if (p_qos_level)
>> +			osm_qos_policy_qos_level_destroy(p_qos_level);
>> +		list_iterator = cl_list_next(list_iterator);
>> +	}
>> +	cl_list_remove_all(&p_qos_policy->qos_levels);
>> +	cl_list_destroy(&p_qos_policy->qos_levels);
>> +
>> +	list_iterator = cl_list_head(&p_qos_policy->qos_match_rules);
>> +	while (list_iterator != cl_list_end(&p_qos_policy->qos_match_rules)) {
>> +		p_qos_match_rule =
>> +		    (osm_qos_match_rule_t *) cl_list_obj(list_iterator);
>> +		if (p_qos_match_rule)
>> +			osm_qos_policy_match_rule_destroy(p_qos_match_rule);
>> +		list_iterator = cl_list_next(list_iterator);
>> +	}
>> +	cl_list_remove_all(&p_qos_policy->qos_match_rules);
>> +	cl_list_destroy(&p_qos_policy->qos_match_rules);
>> +
>> +	free(p_qos_policy);
>> +
>> +	p_qos_policy = NULL;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +static boolean_t
>> +__qos_policy_is_port_in_group(osm_subn_t * p_subn,
>> +			      const osm_physp_t * p_physp,
>> +			      osm_qos_port_group_t * p_port_group)
>> +{
>> +	osm_node_t *p_node = osm_physp_get_node_ptr(p_physp);
>> +	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);
>> +	cl_list_iterator_t list_iterator;
>> +	char *partition_name;
>> +
>> +	/* check whether this port's type matches any of group's types */
>> +
>> +	if ((node_type == IB_NODE_TYPE_CA && p_port_group->node_type_ca) ||
>> +	    (node_type == IB_NODE_TYPE_SWITCH && p_port_group->node_type_switch)
>> +	    || (node_type == IB_NODE_TYPE_ROUTER
>> +		&& p_port_group->node_type_router))
>> +		return TRUE;
>> +
>> +	/* check whether this port's guid is in range of this group's guids */
>> +
>> +	if (__is_num_in_range_arr(p_port_group->guid_range_arr,
>> +				  p_port_group->guid_range_len, port_guid_ho))
>> +		return TRUE;
>> +
>> +	/* check whether this port is member of this group's partitions */
>> +
>> +	list_iterator = cl_list_head(&p_port_group->partition_list);
>> +	while (list_iterator != cl_list_end(&p_port_group->partition_list)) {
>> +		partition_name = (char *)cl_list_obj(list_iterator);
>> +		if (partition_name && strlen(partition_name)) {
>> +			p_prtn = osm_prtn_find_by_name(p_subn, partition_name);
>> +			if (p_prtn) {
>> +				if (osm_prtn_is_guid(p_prtn, port_guid))
>> +					return TRUE;
>> +			}
>> +		}
>> +		list_iterator = cl_list_next(list_iterator);
>> +	}
>> +
>> +	/* check whether this port's name matches any of group's names */
>> +
>> +	/*
>> +	 * TODO: check port names
>> +	 *
>> +	 *  char desc[IB_NODE_DESCRIPTION_SIZE + 1];
>> +	 *  memcpy(desc, p_node->node_desc.description, IB_NODE_DESCRIPTION_SIZE);
>> +	 *  desc[IB_NODE_DESCRIPTION_SIZE] = '\0';
>> +	 */
>> +
>> +	return FALSE;
>> +}				/* __qos_policy_is_port_in_group() */
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +static boolean_t
>> +__qos_policy_is_port_in_group_list(const osm_pr_rcv_t * p_rcv,
>> +				   const osm_physp_t * p_physp,
>> +				   cl_list_t * p_port_group_list)
>> +{
>> +	osm_qos_port_group_t *p_port_group;
>> +	cl_list_iterator_t list_iterator;
>> +
>> +	list_iterator = cl_list_head(p_port_group_list);
>> +	while (list_iterator != cl_list_end(p_port_group_list)) {
>> +		p_port_group =
>> +		    (osm_qos_port_group_t *) cl_list_obj(list_iterator);
>> +		if (p_port_group) {
>> +			if (__qos_policy_is_port_in_group
>> +			    (p_rcv->p_subn, p_physp, p_port_group))
>> +				return TRUE;
>> +		}
>> +		list_iterator = cl_list_next(list_iterator);
>> +	}
>> +	return FALSE;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +static osm_qos_match_rule_t *__qos_policy_get_match_rule_by_pr(
>> +			 const osm_qos_policy_t * p_qos_policy,
>> +			 const osm_pr_rcv_t * p_rcv,
>> +			 const ib_path_rec_t * p_pr,
>> +			 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;
>> +
>> +	if (!cl_list_count(&p_qos_policy->qos_match_rules))
>> +		return NULL;
>> +
>> +	/* Go over all QoS match rules and find the one that matches the request */
>> +
>> +	list_iterator = cl_list_head(&p_qos_policy->qos_match_rules);
>> +	while (list_iterator != cl_list_end(&p_qos_policy->qos_match_rules)) {
>> +		p_qos_match_rule =
>> +		    (osm_qos_match_rule_t *) cl_list_obj(list_iterator);
>> +		if (!p_qos_match_rule) {
>> +			list_iterator = cl_list_next(list_iterator);
>> +			continue;
>> +		}
>> +
>> +		/* If a match rule has Source groups, PR request source has to be in this list */
>> +
>> +		if (cl_list_count(&p_qos_match_rule->source_group_list)) {
>> +			if (!__qos_policy_is_port_in_group_list(p_rcv,
>> +								p_src_physp,
>> +								&p_qos_match_rule->
>> +								source_group_list))
>> +			{
>> +				list_iterator = cl_list_next(list_iterator);
>> +				continue;
>> +			}
>> +		}
>> +
>> +		/* If a match rule has Destination groups, PR request dest. has to be in this list */
>> +
>> +		if (cl_list_count(&p_qos_match_rule->destination_group_list)) {
>> +			if (!__qos_policy_is_port_in_group_list(p_rcv,
>> +								p_dest_physp,
>> +								&p_qos_match_rule->
>> +								destination_group_list))
>> +			{
>> +				list_iterator = cl_list_next(list_iterator);
>> +				continue;
>> +			}
>> +		}
>> +
>> +		/* If a match rule has QoS classes, PR request HAS
>> +		   to have a matching QoS class to match the rule */
>> +
>> +		if (p_qos_match_rule->qos_class_range_len) {
>> +			if (!(comp_mask & IB_PR_COMPMASK_QOS_CLASS)) {
>> +				list_iterator = cl_list_next(list_iterator);
>> +				continue;
>> +			}
>> +
>> +			if (!__is_num_in_range_arr
>> +			    (p_qos_match_rule->qos_class_range_arr,
>> +			     p_qos_match_rule->qos_class_range_len,
>> +			     ib_path_rec_qos_class(p_pr))) {
>> +				list_iterator = cl_list_next(list_iterator);
>> +				continue;
>> +			}
>> +
>> +		}
>> +
>> +		/* If a match rule has Service IDs, PR request HAS
>> +		   to have a matching Service ID to match the rule */
>> +
>> +		if (p_qos_match_rule->service_id_range_len) {
>> +			if (!(comp_mask & IB_PR_COMPMASK_SERVICEID)) {
>> +				list_iterator = cl_list_next(list_iterator);
>> +				continue;
>> +			}
>> +
>> +			if (!__is_num_in_range_arr
>> +			    (p_qos_match_rule->service_id_range_arr,
>> +			     p_qos_match_rule->service_id_range_len,
>> +			     p_pr->service_id)) {
>> +				list_iterator = cl_list_next(list_iterator);
>> +				continue;
>> +			}
>> +
>> +		}
>> +
>> +		/* If a match rule has PKeys, PR request HAS
>> +		   to have a matching PKey to match the rule */
>> +
>> +		if (p_qos_match_rule->pkey_range_len) {
>> +			if (!(comp_mask & IB_PR_COMPMASK_PKEY)) {
>> +				list_iterator = cl_list_next(list_iterator);
>> +				continue;
>> +			}
>> +
>> +			if (!__is_num_in_range_arr
>> +			    (p_qos_match_rule->pkey_range_arr,
>> +			     p_qos_match_rule->pkey_range_len,
>> +			     ib_path_rec_qos_class(p_pr))) {
>> +				list_iterator = cl_list_next(list_iterator);
>> +				continue;
>> +			}
>> +
>> +		}
>> +
>> +		/* if we got here, then this match-rule matched this PR request */
>> +		break;
>> +	}
>> +
>> +	if (list_iterator == cl_list_end(&p_qos_policy->qos_match_rules))
>> +		return NULL;
>> +
>> +	return p_qos_match_rule;
>> +}				/* __qos_policy_get_match_rule_by_pr() */
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +static osm_qos_level_t *__qos_policy_get_qos_level_by_name(osm_qos_policy_t * p_qos_policy,
>> +							   char *name)
>> +{
>> +	osm_qos_level_t *p_qos_level = NULL;
>> +	cl_list_iterator_t list_iterator;
>> +
>> +	list_iterator = cl_list_head(&p_qos_policy->qos_levels);
>> +	while (list_iterator != cl_list_end(&p_qos_policy->qos_levels)) {
>> +		p_qos_level = (osm_qos_level_t *) cl_list_obj(list_iterator);
>> +		if (!p_qos_level)
>> +			continue;
>> +
>> +		/* names are case INsensitive */
>> +		if (strcasecmp(name, p_qos_level->name) == 0)
>> +			return p_qos_level;
>> +
>> +		list_iterator = cl_list_next(list_iterator);
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +static osm_qos_port_group_t *__qos_policy_get_port_group_by_name(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;
>> +
>> +	list_iterator = cl_list_head(&p_qos_policy->port_groups);
>> +	while (list_iterator != cl_list_end(&p_qos_policy->port_groups)) {
>> +		p_port_group =
>> +		    (osm_qos_port_group_t *) cl_list_obj(list_iterator);
>> +		if (!p_port_group)
>> +			continue;
>> +
>> +		/* names are case INsensitive */
>> +		if (strcasecmp(name, p_port_group->name) == 0)
>> +			return p_port_group;
>> +
>> +		list_iterator = cl_list_next(list_iterator);
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +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;
>> +	osm_qos_port_group_t *p_port_group = NULL;
>> +	osm_qos_match_rule_t *p_qos_match_rule = NULL;
>> +	char *str;
>> +	unsigned i;
>> +	int res = 0;
>> +
>> +	OSM_LOG_ENTER(p_log, osm_qos_policy_validate);
>> +
>> +	/* 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);
>> +	if (!p_qos_policy->p_default_qos_level) {
>> +		osm_log(p_log, OSM_LOG_ERROR,
>> +			"osm_qos_policy_validate: ERR AC10: "
>> +			"Default qos-level (%s) not defined.\n",
>> +			OSM_QOS_POLICY_DEFAULT_LEVEL_NAME);
>> +		res = 1;
>> +		goto Exit;
>> +	}
>> +
>> +	/* scan all the match rules, and fill the lists of pointers to
>> +	   relevant qos levels and port groups to speed up PR matching */
>> +
>> +	i = 1;
>> +	match_rules_list_iterator =
>> +	    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 *)
>> +		    cl_list_obj(match_rules_list_iterator);
>> +		CL_ASSERT(p_qos_match_rule);
>> +
>> +		/* find the matching qos-level for each match-rule */
>> +
>> +		p_qos_match_rule->p_qos_level =
>> +		    __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,
>> +				"osm_qos_policy_validate: ERR AC11: "
>> +				"qos-match-rule num %u: qos-level '%s' not found\n",
>> +				i, p_qos_match_rule->qos_level_name);
>> +			res = 1;
>> +			goto Exit;
>> +		}
>> +
>> +		/* find the matching port-group for element of source_list */
>> +
>> +		if (cl_list_count(&p_qos_match_rule->source_list)) {
>> +			list_iterator =
>> +			    cl_list_head(&p_qos_match_rule->source_list);
>> +			while (list_iterator !=
>> +			       cl_list_end(&p_qos_match_rule->source_list)) {
>> +				str = (char *)cl_list_obj(list_iterator);
>> +				CL_ASSERT(str);
>> +
>> +				p_port_group =
>> +				    __qos_policy_get_port_group_by_name(p_qos_policy, str);
>> +				if (!p_port_group) {
>> +					osm_log(p_log,
>> +						OSM_LOG_ERROR,
>> +						"osm_qos_policy_validate: ERR AC12: "
>> +						"qos-match-rule num %u: source port-group '%s' not found\n",
>> +						i, str);
>> +					res = 1;
>> +					goto Exit;
>> +				}
>> +
>> +				cl_list_insert_tail(&p_qos_match_rule->
>> +						    source_group_list,
>> +						    p_port_group);
>> +
>> +				list_iterator = cl_list_next(list_iterator);
>> +			}
>> +		}
>> +
>> +		/* find the matching port-group for element of destination_list */
>> +
>> +		if (cl_list_count(&p_qos_match_rule->destination_list)) {
>> +			list_iterator =
>> +			    cl_list_head(&p_qos_match_rule->destination_list);
>> +			while (list_iterator !=
>> +			       cl_list_end(&p_qos_match_rule->
>> +					   destination_list)) {
>> +				str = (char *)cl_list_obj(list_iterator);
>> +				CL_ASSERT(str);
>> +
>> +				p_port_group =
>> +				    __qos_policy_get_port_group_by_name(p_qos_policy,str);
>> +				if (!p_port_group) {
>> +					osm_log(p_log,
>> +						OSM_LOG_ERROR,
>> +						"osm_qos_policy_validate: ERR AC13: "
>> +						"qos-match-rule num %u: destination port-group '%s' not found\n",
>> +						i, str);
>> +					res = 1;
>> +					goto Exit;
>> +				}
>> +
>> +				cl_list_insert_tail(&p_qos_match_rule->
>> +						    destination_group_list,
>> +						    p_port_group);
>> +
>> +				list_iterator = cl_list_next(list_iterator);
>> +			}
>> +		}
>> +
>> +		/* done with the current match-rule */
>> +
>> +		match_rules_list_iterator =
>> +		    cl_list_next(match_rules_list_iterator);
>> +		i++;
>> +	}
>> +
>> +      Exit:
>> +	OSM_LOG_EXIT(p_log);
>> +	return res;
>> +}				/* osm_qos_policy_validate() */
>> +
>> +/***************************************************
>> + ***************************************************/
>> +
>> +void osm_qos_policy_get_qos_level_by_pr(IN const osm_qos_policy_t * p_qos_policy,
>> +					IN const osm_pr_rcv_t * p_rcv,
>> +					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,
>> +					OUT osm_qos_level_t ** pp_qos_level)
>> +{
>> +	osm_qos_match_rule_t *p_qos_match_rule = NULL;
>> +	osm_qos_level_t *p_qos_level = NULL;
>> +
>> +	OSM_LOG_ENTER(p_rcv->p_log, osm_qos_policy_get_qos_level_by_pr);
>> +
>> +	*pp_qos_level = NULL;
>> +
>> +	if (!p_qos_policy)
>> +		goto Exit;
>> +
>> +	p_qos_match_rule = __qos_policy_get_match_rule_by_pr(p_qos_policy,
>> +							     p_rcv,
>> +							     p_pr,
>> +							     p_src_physp,
>> +							     p_dest_physp,
>> +							     comp_mask);
>> +
>> +	if (p_qos_match_rule)
>> +		p_qos_level = p_qos_match_rule->p_qos_level;
>> +	else
>> +		p_qos_level = p_qos_policy->p_default_qos_level;
>> +
>> +	osm_log(p_rcv->p_log, OSM_LOG_DEBUG,
>> +		"osm_qos_policy_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_policy_get_qos_level_by_pr: "
>> +		"Applying QoS Level %s (%s)\n",
>> +		p_qos_level->name,
>> +		(p_qos_level->use) ? p_qos_level->use : "no description");
>> +
>> +	*pp_qos_level = p_qos_level;
>> +
>> +      Exit:
>> +	OSM_LOG_EXIT(p_rcv->p_log);
>> +}				/* osm_qos_policy_get_qos_level_by_pr() */
>> +
>> +/***************************************************
>> + ***************************************************/
>> -- 
>> 1.5.1.4
>>
> 




More information about the general mailing list