2 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5 * Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
7 * This software is available to you under a choice of one of two
8 * licenses. You may choose to be licensed under the terms of the GNU
9 * General Public License (GPL) Version 2, available from the file
10 * COPYING in the main directory of this source tree, or the
11 * OpenIB.org BSD license below:
13 * Redistribution and use in source and binary forms, with or
14 * without modification, are permitted provided that the following
17 * - Redistributions of source code must retain the above
18 * copyright notice, this list of conditions and the following
21 * - Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials
24 * provided with the distribution.
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39 * OSM QoS Policy functions.
42 * Yevgeny Kliteynik, Mellanox
50 #include <opensm/osm_log.h>
51 #include <opensm/osm_node.h>
52 #include <opensm/osm_port.h>
53 #include <opensm/osm_partition.h>
54 #include <opensm/osm_opensm.h>
55 #include <opensm/osm_qos_policy.h>
57 extern osm_qos_level_t __default_simple_qos_level;
59 /***************************************************
60 ***************************************************/
63 __build_nodebyname_hash(osm_qos_policy_t * p_qos_policy)
66 cl_qmap_t * p_node_guid_tbl = &p_qos_policy->p_subn->node_guid_tbl;
68 p_qos_policy->p_node_hash = st_init_strtable();
69 CL_ASSERT(p_qos_policy->p_node_hash);
71 if (!p_node_guid_tbl || !cl_qmap_count(p_node_guid_tbl))
74 for (p_node = (osm_node_t *) cl_qmap_head(p_node_guid_tbl);
75 p_node != (osm_node_t *) cl_qmap_end(p_node_guid_tbl);
76 p_node = (osm_node_t *) cl_qmap_next(&p_node->map_item)) {
77 if (!st_lookup(p_qos_policy->p_node_hash,
78 (st_data_t)p_node->print_desc, NULL))
79 st_insert(p_qos_policy->p_node_hash,
80 (st_data_t)p_node->print_desc,
85 /***************************************************
86 ***************************************************/
89 __is_num_in_range_arr(uint64_t ** range_arr,
90 unsigned range_arr_len, uint64_t num)
93 unsigned ind_2 = range_arr_len - 1;
96 if (!range_arr || !range_arr_len)
99 while (ind_1 <= ind_2) {
100 if (num < range_arr[ind_1][0] || num > range_arr[ind_2][1])
102 else if (num <= range_arr[ind_1][1] || num >= range_arr[ind_2][0])
105 ind_mid = ind_1 + (ind_2 - ind_1 + 1)/2;
107 if (num < range_arr[ind_mid][0])
109 else if (num > range_arr[ind_mid][1])
121 /***************************************************
122 ***************************************************/
124 static void __free_single_element(void *p_element, void *context)
130 /***************************************************
131 ***************************************************/
133 osm_qos_port_t *osm_qos_policy_port_create(osm_physp_t *p_physp)
136 (osm_qos_port_t *) malloc(sizeof(osm_qos_port_t));
139 memset(p, 0, sizeof(osm_qos_port_t));
141 p->p_physp = p_physp;
145 /***************************************************
146 ***************************************************/
148 osm_qos_port_group_t *osm_qos_policy_port_group_create()
150 osm_qos_port_group_t *p =
151 (osm_qos_port_group_t *) malloc(sizeof(osm_qos_port_group_t));
155 memset(p, 0, sizeof(osm_qos_port_group_t));
156 cl_qmap_init(&p->port_map);
161 /***************************************************
162 ***************************************************/
164 void osm_qos_policy_port_group_destroy(osm_qos_port_group_t * p)
166 osm_qos_port_t * p_port;
167 osm_qos_port_t * p_old_port;
177 p_port = (osm_qos_port_t *) cl_qmap_head(&p->port_map);
178 while (p_port != (osm_qos_port_t *) cl_qmap_end(&p->port_map))
181 p_port = (osm_qos_port_t *) cl_qmap_next(&p_port->map_item);
184 cl_qmap_remove_all(&p->port_map);
189 /***************************************************
190 ***************************************************/
192 osm_qos_vlarb_scope_t *osm_qos_policy_vlarb_scope_create()
194 osm_qos_vlarb_scope_t *p =
195 (osm_qos_vlarb_scope_t *) malloc(sizeof(osm_qos_sl2vl_scope_t));
199 memset(p, 0, sizeof(osm_qos_vlarb_scope_t));
201 cl_list_init(&p->group_list, 10);
202 cl_list_init(&p->across_list, 10);
203 cl_list_init(&p->vlarb_high_list, 10);
204 cl_list_init(&p->vlarb_low_list, 10);
209 /***************************************************
210 ***************************************************/
212 void osm_qos_policy_vlarb_scope_destroy(osm_qos_vlarb_scope_t * p)
217 cl_list_apply_func(&p->group_list, __free_single_element, NULL);
218 cl_list_apply_func(&p->across_list, __free_single_element, NULL);
219 cl_list_apply_func(&p->vlarb_high_list, __free_single_element, NULL);
220 cl_list_apply_func(&p->vlarb_low_list, __free_single_element, NULL);
222 cl_list_remove_all(&p->group_list);
223 cl_list_remove_all(&p->across_list);
224 cl_list_remove_all(&p->vlarb_high_list);
225 cl_list_remove_all(&p->vlarb_low_list);
227 cl_list_destroy(&p->group_list);
228 cl_list_destroy(&p->across_list);
229 cl_list_destroy(&p->vlarb_high_list);
230 cl_list_destroy(&p->vlarb_low_list);
235 /***************************************************
236 ***************************************************/
238 osm_qos_sl2vl_scope_t *osm_qos_policy_sl2vl_scope_create()
240 osm_qos_sl2vl_scope_t *p =
241 (osm_qos_sl2vl_scope_t *) malloc(sizeof(osm_qos_sl2vl_scope_t));
245 memset(p, 0, sizeof(osm_qos_sl2vl_scope_t));
247 cl_list_init(&p->group_list, 10);
248 cl_list_init(&p->across_from_list, 10);
249 cl_list_init(&p->across_to_list, 10);
254 /***************************************************
255 ***************************************************/
257 void osm_qos_policy_sl2vl_scope_destroy(osm_qos_sl2vl_scope_t * p)
262 cl_list_apply_func(&p->group_list, __free_single_element, NULL);
263 cl_list_apply_func(&p->across_from_list, __free_single_element, NULL);
264 cl_list_apply_func(&p->across_to_list, __free_single_element, NULL);
266 cl_list_remove_all(&p->group_list);
267 cl_list_remove_all(&p->across_from_list);
268 cl_list_remove_all(&p->across_to_list);
270 cl_list_destroy(&p->group_list);
271 cl_list_destroy(&p->across_from_list);
272 cl_list_destroy(&p->across_to_list);
277 /***************************************************
278 ***************************************************/
280 osm_qos_level_t *osm_qos_policy_qos_level_create()
283 (osm_qos_level_t *) malloc(sizeof(osm_qos_level_t));
286 memset(p, 0, sizeof(osm_qos_level_t));
290 /***************************************************
291 ***************************************************/
293 void osm_qos_policy_qos_level_destroy(osm_qos_level_t * p)
305 for (i = 0; i < p->path_bits_range_len; i++)
306 free(p->path_bits_range_arr[i]);
307 if (p->path_bits_range_arr)
308 free(p->path_bits_range_arr);
313 /***************************************************
314 ***************************************************/
316 boolean_t osm_qos_level_has_pkey(IN const osm_qos_level_t * p_qos_level,
319 if (!p_qos_level || !p_qos_level->pkey_range_len)
321 return __is_num_in_range_arr(p_qos_level->pkey_range_arr,
322 p_qos_level->pkey_range_len,
326 /***************************************************
327 ***************************************************/
329 ib_net16_t osm_qos_level_get_shared_pkey(IN const osm_qos_level_t * p_qos_level,
330 IN const osm_physp_t * p_src_physp,
331 IN const osm_physp_t * p_dest_physp)
334 uint16_t pkey_ho = 0;
336 if (!p_qos_level || !p_qos_level->pkey_range_len)
340 * ToDo: This approach is not optimal.
341 * Think how to find shared pkey that also exists
342 * in QoS level in less runtime.
345 for (i = 0; i < p_qos_level->pkey_range_len; i++) {
346 for (pkey_ho = p_qos_level->pkey_range_arr[i][0];
347 pkey_ho <= p_qos_level->pkey_range_arr[i][1]; pkey_ho++) {
348 if (osm_physp_share_this_pkey
349 (p_src_physp, p_dest_physp, cl_hton16(pkey_ho)))
350 return cl_hton16(pkey_ho);
357 /***************************************************
358 ***************************************************/
360 osm_qos_match_rule_t *osm_qos_policy_match_rule_create()
362 osm_qos_match_rule_t *p =
363 (osm_qos_match_rule_t *) malloc(sizeof(osm_qos_match_rule_t));
367 memset(p, 0, sizeof(osm_qos_match_rule_t));
369 cl_list_init(&p->source_list, 10);
370 cl_list_init(&p->source_group_list, 10);
371 cl_list_init(&p->destination_list, 10);
372 cl_list_init(&p->destination_group_list, 10);
377 /***************************************************
378 ***************************************************/
380 void osm_qos_policy_match_rule_destroy(osm_qos_match_rule_t * p)
387 if (p->qos_level_name)
388 free(p->qos_level_name);
392 for (i = 0; i < p->service_id_range_len; i++)
393 free(p->service_id_range_arr[i]);
394 if (p->service_id_range_arr)
395 free(p->service_id_range_arr);
397 for (i = 0; i < p->qos_class_range_len; i++)
398 free(p->qos_class_range_arr[i]);
399 if (p->qos_class_range_arr)
400 free(p->qos_class_range_arr);
402 for (i = 0; i < p->pkey_range_len; i++)
403 free(p->pkey_range_arr[i]);
404 if (p->pkey_range_arr)
405 free(p->pkey_range_arr);
407 cl_list_apply_func(&p->source_list, __free_single_element, NULL);
408 cl_list_remove_all(&p->source_list);
409 cl_list_destroy(&p->source_list);
411 cl_list_remove_all(&p->source_group_list);
412 cl_list_destroy(&p->source_group_list);
414 cl_list_apply_func(&p->destination_list, __free_single_element, NULL);
415 cl_list_remove_all(&p->destination_list);
416 cl_list_destroy(&p->destination_list);
418 cl_list_remove_all(&p->destination_group_list);
419 cl_list_destroy(&p->destination_group_list);
424 /***************************************************
425 ***************************************************/
427 osm_qos_policy_t * osm_qos_policy_create(osm_subn_t * p_subn)
429 osm_qos_policy_t * p_qos_policy = (osm_qos_policy_t *)malloc(sizeof(osm_qos_policy_t));
433 memset(p_qos_policy, 0, sizeof(osm_qos_policy_t));
435 cl_list_construct(&p_qos_policy->port_groups);
436 cl_list_init(&p_qos_policy->port_groups, 10);
438 cl_list_construct(&p_qos_policy->vlarb_tables);
439 cl_list_init(&p_qos_policy->vlarb_tables, 10);
441 cl_list_construct(&p_qos_policy->sl2vl_tables);
442 cl_list_init(&p_qos_policy->sl2vl_tables, 10);
444 cl_list_construct(&p_qos_policy->qos_levels);
445 cl_list_init(&p_qos_policy->qos_levels, 10);
447 cl_list_construct(&p_qos_policy->qos_match_rules);
448 cl_list_init(&p_qos_policy->qos_match_rules, 10);
450 p_qos_policy->p_subn = p_subn;
451 __build_nodebyname_hash(p_qos_policy);
456 /***************************************************
457 ***************************************************/
459 void osm_qos_policy_destroy(osm_qos_policy_t * p_qos_policy)
461 cl_list_iterator_t list_iterator;
462 osm_qos_port_group_t *p_port_group = NULL;
463 osm_qos_vlarb_scope_t *p_vlarb_scope = NULL;
464 osm_qos_sl2vl_scope_t *p_sl2vl_scope = NULL;
465 osm_qos_level_t *p_qos_level = NULL;
466 osm_qos_match_rule_t *p_qos_match_rule = NULL;
471 list_iterator = cl_list_head(&p_qos_policy->port_groups);
472 while (list_iterator != cl_list_end(&p_qos_policy->port_groups)) {
474 (osm_qos_port_group_t *) cl_list_obj(list_iterator);
476 osm_qos_policy_port_group_destroy(p_port_group);
477 list_iterator = cl_list_next(list_iterator);
479 cl_list_remove_all(&p_qos_policy->port_groups);
480 cl_list_destroy(&p_qos_policy->port_groups);
482 list_iterator = cl_list_head(&p_qos_policy->vlarb_tables);
483 while (list_iterator != cl_list_end(&p_qos_policy->vlarb_tables)) {
485 (osm_qos_vlarb_scope_t *) cl_list_obj(list_iterator);
487 osm_qos_policy_vlarb_scope_destroy(p_vlarb_scope);
488 list_iterator = cl_list_next(list_iterator);
490 cl_list_remove_all(&p_qos_policy->vlarb_tables);
491 cl_list_destroy(&p_qos_policy->vlarb_tables);
493 list_iterator = cl_list_head(&p_qos_policy->sl2vl_tables);
494 while (list_iterator != cl_list_end(&p_qos_policy->sl2vl_tables)) {
496 (osm_qos_sl2vl_scope_t *) cl_list_obj(list_iterator);
498 osm_qos_policy_sl2vl_scope_destroy(p_sl2vl_scope);
499 list_iterator = cl_list_next(list_iterator);
501 cl_list_remove_all(&p_qos_policy->sl2vl_tables);
502 cl_list_destroy(&p_qos_policy->sl2vl_tables);
504 list_iterator = cl_list_head(&p_qos_policy->qos_levels);
505 while (list_iterator != cl_list_end(&p_qos_policy->qos_levels)) {
506 p_qos_level = (osm_qos_level_t *) cl_list_obj(list_iterator);
508 osm_qos_policy_qos_level_destroy(p_qos_level);
509 list_iterator = cl_list_next(list_iterator);
511 cl_list_remove_all(&p_qos_policy->qos_levels);
512 cl_list_destroy(&p_qos_policy->qos_levels);
514 list_iterator = cl_list_head(&p_qos_policy->qos_match_rules);
515 while (list_iterator != cl_list_end(&p_qos_policy->qos_match_rules)) {
517 (osm_qos_match_rule_t *) cl_list_obj(list_iterator);
518 if (p_qos_match_rule)
519 osm_qos_policy_match_rule_destroy(p_qos_match_rule);
520 list_iterator = cl_list_next(list_iterator);
522 cl_list_remove_all(&p_qos_policy->qos_match_rules);
523 cl_list_destroy(&p_qos_policy->qos_match_rules);
525 if (p_qos_policy->p_node_hash)
526 st_free_table(p_qos_policy->p_node_hash);
533 /***************************************************
534 ***************************************************/
537 __qos_policy_is_port_in_group(osm_subn_t * p_subn,
538 const osm_physp_t * p_physp,
539 osm_qos_port_group_t * p_port_group)
541 osm_node_t *p_node = osm_physp_get_node_ptr(p_physp);
542 ib_net64_t port_guid = osm_physp_get_port_guid(p_physp);
543 uint64_t port_guid_ho = cl_ntoh64(port_guid);
545 /* check whether this port's type matches any of group's types */
547 if ( p_port_group->node_types &
548 (((uint8_t)1)<<osm_node_get_type(p_node)) )
551 /* check whether this port's guid is in group's port map */
553 if (cl_qmap_get(&p_port_group->port_map, port_guid_ho) !=
554 cl_qmap_end(&p_port_group->port_map))
558 } /* __qos_policy_is_port_in_group() */
560 /***************************************************
561 ***************************************************/
564 __qos_policy_is_port_in_group_list(const osm_qos_policy_t * p_qos_policy,
565 const osm_physp_t * p_physp,
566 cl_list_t * p_port_group_list)
568 osm_qos_port_group_t *p_port_group;
569 cl_list_iterator_t list_iterator;
571 list_iterator = cl_list_head(p_port_group_list);
572 while (list_iterator != cl_list_end(p_port_group_list)) {
574 (osm_qos_port_group_t *) cl_list_obj(list_iterator);
576 if (__qos_policy_is_port_in_group
577 (p_qos_policy->p_subn, p_physp, p_port_group))
580 list_iterator = cl_list_next(list_iterator);
585 /***************************************************
586 ***************************************************/
588 static osm_qos_match_rule_t *__qos_policy_get_match_rule_by_params(
589 const osm_qos_policy_t * p_qos_policy,
593 const osm_physp_t * p_src_physp,
594 const osm_physp_t * p_dest_physp,
595 ib_net64_t comp_mask)
597 osm_qos_match_rule_t *p_qos_match_rule = NULL;
598 cl_list_iterator_t list_iterator;
599 osm_log_t * p_log = &p_qos_policy->p_subn->p_osm->log;
601 boolean_t matched_by_sguid = FALSE,
602 matched_by_dguid = FALSE,
603 matched_by_class = FALSE,
604 matched_by_sid = FALSE,
605 matched_by_pkey = FALSE;
607 if (!cl_list_count(&p_qos_policy->qos_match_rules))
610 OSM_LOG_ENTER(p_log);
612 /* Go over all QoS match rules and find the one that matches the request */
614 list_iterator = cl_list_head(&p_qos_policy->qos_match_rules);
615 while (list_iterator != cl_list_end(&p_qos_policy->qos_match_rules)) {
617 (osm_qos_match_rule_t *) cl_list_obj(list_iterator);
618 if (!p_qos_match_rule) {
619 list_iterator = cl_list_next(list_iterator);
623 /* If a match rule has Source groups, PR request source has to be in this list */
625 if (cl_list_count(&p_qos_match_rule->source_group_list)) {
626 if (!__qos_policy_is_port_in_group_list(p_qos_policy,
631 list_iterator = cl_list_next(list_iterator);
634 matched_by_sguid = TRUE;
637 /* If a match rule has Destination groups, PR request dest. has to be in this list */
639 if (cl_list_count(&p_qos_match_rule->destination_group_list)) {
640 if (!__qos_policy_is_port_in_group_list(p_qos_policy,
643 destination_group_list))
645 list_iterator = cl_list_next(list_iterator);
648 matched_by_dguid = TRUE;
651 /* If a match rule has QoS classes, PR request HAS
652 to have a matching QoS class to match the rule */
654 if (p_qos_match_rule->qos_class_range_len) {
655 if (!(comp_mask & IB_PR_COMPMASK_QOS_CLASS)) {
656 list_iterator = cl_list_next(list_iterator);
660 if (!__is_num_in_range_arr
661 (p_qos_match_rule->qos_class_range_arr,
662 p_qos_match_rule->qos_class_range_len,
664 list_iterator = cl_list_next(list_iterator);
667 matched_by_class = TRUE;
670 /* If a match rule has Service IDs, PR request HAS
671 to have a matching Service ID to match the rule */
673 if (p_qos_match_rule->service_id_range_len) {
674 if (!(comp_mask & IB_PR_COMPMASK_SERVICEID_MSB) ||
675 !(comp_mask & IB_PR_COMPMASK_SERVICEID_LSB)) {
676 list_iterator = cl_list_next(list_iterator);
680 if (!__is_num_in_range_arr
681 (p_qos_match_rule->service_id_range_arr,
682 p_qos_match_rule->service_id_range_len,
684 list_iterator = cl_list_next(list_iterator);
687 matched_by_sid = TRUE;
690 /* If a match rule has PKeys, PR request HAS
691 to have a matching PKey to match the rule */
693 if (p_qos_match_rule->pkey_range_len) {
694 if (!(comp_mask & IB_PR_COMPMASK_PKEY)) {
695 list_iterator = cl_list_next(list_iterator);
699 if (!__is_num_in_range_arr
700 (p_qos_match_rule->pkey_range_arr,
701 p_qos_match_rule->pkey_range_len,
703 list_iterator = cl_list_next(list_iterator);
706 matched_by_pkey = TRUE;
709 /* if we got here, then this match-rule matched this PR request */
713 if (list_iterator == cl_list_end(&p_qos_policy->qos_match_rules))
714 p_qos_match_rule = NULL;
716 if (p_qos_match_rule)
717 OSM_LOG(p_log, OSM_LOG_DEBUG,
718 "request matched rule (%s) by:%s%s%s%s%s\n",
719 (p_qos_match_rule->use) ?
720 p_qos_match_rule->use : "no description",
721 (matched_by_sguid) ? " SGUID" : "",
722 (matched_by_dguid) ? " DGUID" : "",
723 (matched_by_class) ? " QoS_Class" : "",
724 (matched_by_sid) ? " ServiceID" : "",
725 (matched_by_pkey) ? " PKey" : "");
727 OSM_LOG(p_log, OSM_LOG_DEBUG,
728 "request not matched any rule\n");
731 return p_qos_match_rule;
732 } /* __qos_policy_get_match_rule_by_params() */
734 /***************************************************
735 ***************************************************/
737 static osm_qos_level_t *__qos_policy_get_qos_level_by_name(
738 const osm_qos_policy_t * p_qos_policy,
741 osm_qos_level_t *p_qos_level = NULL;
742 cl_list_iterator_t list_iterator;
744 list_iterator = cl_list_head(&p_qos_policy->qos_levels);
745 while (list_iterator != cl_list_end(&p_qos_policy->qos_levels)) {
746 p_qos_level = (osm_qos_level_t *) cl_list_obj(list_iterator);
750 /* names are case INsensitive */
751 if (strcasecmp(name, p_qos_level->name) == 0)
754 list_iterator = cl_list_next(list_iterator);
760 /***************************************************
761 ***************************************************/
763 static osm_qos_port_group_t *__qos_policy_get_port_group_by_name(
764 const osm_qos_policy_t * p_qos_policy,
765 const char *const name)
767 osm_qos_port_group_t *p_port_group = NULL;
768 cl_list_iterator_t list_iterator;
770 list_iterator = cl_list_head(&p_qos_policy->port_groups);
771 while (list_iterator != cl_list_end(&p_qos_policy->port_groups)) {
773 (osm_qos_port_group_t *) cl_list_obj(list_iterator);
777 /* names are case INsensitive */
778 if (strcasecmp(name, p_port_group->name) == 0)
781 list_iterator = cl_list_next(list_iterator);
787 /***************************************************
788 ***************************************************/
790 static void __qos_policy_validate_pkey(
791 osm_qos_policy_t * p_qos_policy,
792 osm_qos_match_rule_t * p_qos_match_rule,
800 if (!p_qos_policy || !p_qos_match_rule || !p_prtn)
803 if (!p_qos_match_rule->p_qos_level->sl_set ||
804 p_prtn->sl == p_qos_match_rule->p_qos_level->sl)
807 /* overriding partition's SL */
808 OSM_LOG(&p_qos_policy->p_subn->p_osm->log, OSM_LOG_ERROR,
809 "ERR AC15: pkey 0x%04X in match rule - "
810 "overriding partition SL (%u) with QoS Level SL (%u)\n",
811 cl_ntoh16(p_prtn->pkey), p_prtn->sl,
812 p_qos_match_rule->p_qos_level->sl);
813 p_prtn->sl = p_qos_match_rule->p_qos_level->sl;
816 /* If this partition is an IPoIB partition, there should
817 be a matching MCast group. Fix this group's SL too */
822 p_mgrp = osm_get_mgrp_by_mlid(p_qos_policy->p_subn, p_prtn->mlid);
824 OSM_LOG(&p_qos_policy->p_subn->p_osm->log, OSM_LOG_ERROR,
825 "ERR AC16: MCast group for partition with "
826 "pkey 0x%04X not found\n",
827 cl_ntoh16(p_prtn->pkey));
831 CL_ASSERT((cl_ntoh16(p_mgrp->mcmember_rec.pkey) & 0x7fff) ==
832 (cl_ntoh16(p_prtn->pkey) & 0x7fff));
834 ib_member_get_sl_flow_hop(p_mgrp->mcmember_rec.sl_flow_hop,
836 if (sl != p_prtn->sl) {
837 OSM_LOG(&p_qos_policy->p_subn->p_osm->log, OSM_LOG_DEBUG,
838 "Updating MCGroup (MLID 0x%04x) SL to "
839 "match partition SL (%u)\n",
840 cl_hton16(p_mgrp->mcmember_rec.mlid),
842 p_mgrp->mcmember_rec.sl_flow_hop =
843 ib_member_set_sl_flow_hop(p_prtn->sl, flow, hop);
847 /***************************************************
848 ***************************************************/
850 int osm_qos_policy_validate(osm_qos_policy_t * p_qos_policy,
853 cl_list_iterator_t match_rules_list_iterator;
854 cl_list_iterator_t list_iterator;
855 osm_qos_port_group_t *p_port_group = NULL;
856 osm_qos_match_rule_t *p_qos_match_rule = NULL;
864 OSM_LOG_ENTER(p_log);
866 /* set default qos level */
868 p_qos_policy->p_default_qos_level =
869 __qos_policy_get_qos_level_by_name(p_qos_policy, OSM_QOS_POLICY_DEFAULT_LEVEL_NAME);
870 if (!p_qos_policy->p_default_qos_level) {
871 /* There's no default QoS level in the usual qos-level section.
872 Check whether the 'simple' default QoS level that can be
873 defined in the qos-ulp section exists */
874 if (__default_simple_qos_level.sl_set) {
875 p_qos_policy->p_default_qos_level = &__default_simple_qos_level;
878 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC10: "
879 "Default qos-level (%s) not defined.\n",
880 OSM_QOS_POLICY_DEFAULT_LEVEL_NAME);
886 /* scan all the match rules, and fill the lists of pointers to
887 relevant qos levels and port groups to speed up PR matching */
890 match_rules_list_iterator =
891 cl_list_head(&p_qos_policy->qos_match_rules);
892 while (match_rules_list_iterator !=
893 cl_list_end(&p_qos_policy->qos_match_rules)) {
895 (osm_qos_match_rule_t *)
896 cl_list_obj(match_rules_list_iterator);
897 CL_ASSERT(p_qos_match_rule);
899 /* find the matching qos-level for each match-rule */
901 if (!p_qos_match_rule->p_qos_level)
902 p_qos_match_rule->p_qos_level =
903 __qos_policy_get_qos_level_by_name(p_qos_policy,
904 p_qos_match_rule->qos_level_name);
906 if (!p_qos_match_rule->p_qos_level) {
907 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC11: "
908 "qos-match-rule num %u: qos-level '%s' not found\n",
909 i, p_qos_match_rule->qos_level_name);
914 /* find the matching port-group for element of source_list */
916 if (cl_list_count(&p_qos_match_rule->source_list)) {
918 cl_list_head(&p_qos_match_rule->source_list);
919 while (list_iterator !=
920 cl_list_end(&p_qos_match_rule->source_list)) {
921 str = (char *)cl_list_obj(list_iterator);
925 __qos_policy_get_port_group_by_name(p_qos_policy, str);
927 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC12: "
928 "qos-match-rule num %u: source port-group '%s' not found\n",
934 cl_list_insert_tail(&p_qos_match_rule->
938 list_iterator = cl_list_next(list_iterator);
942 /* find the matching port-group for element of destination_list */
944 if (cl_list_count(&p_qos_match_rule->destination_list)) {
946 cl_list_head(&p_qos_match_rule->destination_list);
947 while (list_iterator !=
948 cl_list_end(&p_qos_match_rule->
950 str = (char *)cl_list_obj(list_iterator);
954 __qos_policy_get_port_group_by_name(p_qos_policy,str);
956 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC13: "
957 "qos-match-rule num %u: destination port-group '%s' not found\n",
963 cl_list_insert_tail(&p_qos_match_rule->
964 destination_group_list,
967 list_iterator = cl_list_next(list_iterator);
972 * Scan all the pkeys in matching rule, and if the
973 * partition for these pkeys exists, set the SL
974 * according to the QoS Level.
975 * Warn if there's mismatch between QoS level SL
979 for (j = 0; j < p_qos_match_rule->pkey_range_len; j++) {
980 for ( pkey_64 = p_qos_match_rule->pkey_range_arr[j][0];
981 pkey_64 <= p_qos_match_rule->pkey_range_arr[j][1];
983 pkey = cl_hton16((uint16_t)(pkey_64 & 0x7fff));
984 p_prtn = (osm_prtn_t *)cl_qmap_get(
985 &p_qos_policy->p_subn->prtn_pkey_tbl, pkey);
987 if (p_prtn == (osm_prtn_t *)cl_qmap_end(
988 &p_qos_policy->p_subn->prtn_pkey_tbl))
989 /* partition for this pkey not found */
990 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR AC14: "
991 "pkey 0x%04X in match rule - "
992 "partition doesn't exist\n",
995 __qos_policy_validate_pkey(p_qos_policy,
1001 /* done with the current match-rule */
1003 match_rules_list_iterator =
1004 cl_list_next(match_rules_list_iterator);
1009 OSM_LOG_EXIT(p_log);
1011 } /* osm_qos_policy_validate() */
1013 /***************************************************
1014 ***************************************************/
1016 static osm_qos_level_t * __qos_policy_get_qos_level_by_params(
1017 IN const osm_qos_policy_t * p_qos_policy,
1018 IN const osm_physp_t * p_src_physp,
1019 IN const osm_physp_t * p_dest_physp,
1020 IN uint64_t service_id,
1021 IN uint16_t qos_class,
1023 IN ib_net64_t comp_mask)
1025 osm_qos_match_rule_t *p_qos_match_rule = NULL;
1030 p_qos_match_rule = __qos_policy_get_match_rule_by_params(
1031 p_qos_policy, service_id, qos_class, pkey,
1032 p_src_physp, p_dest_physp, comp_mask);
1034 return p_qos_match_rule ? p_qos_match_rule->p_qos_level :
1035 p_qos_policy->p_default_qos_level;
1036 } /* __qos_policy_get_qos_level_by_params() */
1038 /***************************************************
1039 ***************************************************/
1041 osm_qos_level_t * osm_qos_policy_get_qos_level_by_pr(
1042 IN const osm_qos_policy_t * p_qos_policy,
1043 IN const ib_path_rec_t * p_pr,
1044 IN const osm_physp_t * p_src_physp,
1045 IN const osm_physp_t * p_dest_physp,
1046 IN ib_net64_t comp_mask)
1048 return __qos_policy_get_qos_level_by_params(
1049 p_qos_policy, p_src_physp, p_dest_physp,
1050 cl_ntoh64(p_pr->service_id), ib_path_rec_qos_class(p_pr),
1051 cl_ntoh16(p_pr->pkey), comp_mask);
1054 /***************************************************
1055 ***************************************************/
1057 osm_qos_level_t * osm_qos_policy_get_qos_level_by_mpr(
1058 IN const osm_qos_policy_t * p_qos_policy,
1059 IN const ib_multipath_rec_t * p_mpr,
1060 IN const osm_physp_t * p_src_physp,
1061 IN const osm_physp_t * p_dest_physp,
1062 IN ib_net64_t comp_mask)
1064 ib_net64_t pr_comp_mask = 0;
1070 * Converting MultiPathRecord compmask to the PathRecord
1071 * compmask. Note that only relevant bits are set.
1074 ((comp_mask & IB_MPR_COMPMASK_QOS_CLASS) ?
1075 IB_PR_COMPMASK_QOS_CLASS : 0) |
1076 ((comp_mask & IB_MPR_COMPMASK_PKEY) ?
1077 IB_PR_COMPMASK_PKEY : 0) |
1078 ((comp_mask & IB_MPR_COMPMASK_SERVICEID_MSB) ?
1079 IB_PR_COMPMASK_SERVICEID_MSB : 0) |
1080 ((comp_mask & IB_MPR_COMPMASK_SERVICEID_LSB) ?
1081 IB_PR_COMPMASK_SERVICEID_LSB : 0);
1083 return __qos_policy_get_qos_level_by_params(
1084 p_qos_policy, p_src_physp, p_dest_physp,
1085 cl_ntoh64(ib_multipath_rec_service_id(p_mpr)),
1086 ib_multipath_rec_qos_class(p_mpr),
1087 cl_ntoh16(p_mpr->pkey), pr_comp_mask);
1090 /***************************************************
1091 ***************************************************/