New policy (allow_both_pkeys) added to indicate whether both full and limited membership on the same partition is allowed or not.
In order to support allow_both_pkeys, the partition file syntax is extended with "both" flag (in addition to "full" and "limited"). Signed-off-by: Hal Rosenstock <[email protected]> --- include/opensm/osm_pkey.h | 11 ++++-- include/opensm/osm_subnet.h | 1 + opensm/osm_pkey.c | 25 ++++++++----- opensm/osm_pkey_mgr.c | 6 +++- opensm/osm_port.c | 3 +- opensm/osm_prtn.c | 23 +++++++++--- opensm/osm_prtn_config.c | 80 +++++++++++++++++++++++++++++------------- opensm/osm_subnet.c | 9 ++++- 8 files changed, 110 insertions(+), 48 deletions(-) diff --git a/include/opensm/osm_pkey.h b/include/opensm/osm_pkey.h index 0d284de..d70f5d9 100644 --- a/include/opensm/osm_pkey.h +++ b/include/opensm/osm_pkey.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. - * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. + * Copyright (c) 2002-2010 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 @@ -472,10 +472,11 @@ osm_pkey_tbl_get_block_and_idx(IN osm_pkey_tbl_t * p_pkey_tbl, */ ib_api_status_t osm_pkey_tbl_set(IN osm_pkey_tbl_t * p_pkey_tbl, - IN uint16_t block, IN ib_pkey_table_t * p_tbl); + IN uint16_t block, IN ib_pkey_table_t * p_tbl, + IN boolean_t allow_both_pkeys); /* * p_pkey_tbl -* [in] Pointer to osm_pkey_tbl_t object. +* [in] Pointer to osm_pkey_tbl_t object * * block * [in] The block number to set @@ -483,6 +484,10 @@ osm_pkey_tbl_set(IN osm_pkey_tbl_t * p_pkey_tbl, * p_tbl * [in] The IB PKey block to copy to the object * +* allow_both_pkeys +* [in] Whether both full and limited membership on same partition +* are allowed +* * RETURN VALUES * IB_SUCCESS or IB_ERROR * diff --git a/include/opensm/osm_subnet.h b/include/opensm/osm_subnet.h index 83ef77e..50952fc 100644 --- a/include/opensm/osm_subnet.h +++ b/include/opensm/osm_subnet.h @@ -181,6 +181,7 @@ typedef struct osm_subn_opt { unsigned long log_max_size; char *partition_config_file; boolean_t no_partition_enforcement; + boolean_t allow_both_pkeys; boolean_t qos; char *qos_policy_file; boolean_t accum_log_file; diff --git a/opensm/osm_pkey.c b/opensm/osm_pkey.c index 885f28a..c7c89fd 100644 --- a/opensm/osm_pkey.c +++ b/opensm/osm_pkey.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. - * Copyright (c) 2002-2006,2008 Mellanox Technologies LTD. All rights reserved. + * Copyright (c) 2002-2010 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 @@ -110,12 +110,13 @@ void osm_pkey_tbl_init_new_blocks(IN const osm_pkey_tbl_t * p_pkey_tbl) } ib_api_status_t osm_pkey_tbl_set(IN osm_pkey_tbl_t * p_pkey_tbl, - IN uint16_t block, IN ib_pkey_table_t * p_tbl) + IN uint16_t block, IN ib_pkey_table_t * p_tbl, + IN boolean_t allow_both_pkeys) { uint16_t b, i; ib_pkey_table_t *p_pkey_block; uint16_t *p_prev_pkey; - ib_net16_t pkey; + ib_net16_t pkey, pkey_base; /* make sure the block is allocated */ if (cl_ptr_vector_get_size(&p_pkey_tbl->blocks) > block) @@ -157,19 +158,23 @@ ib_api_status_t osm_pkey_tbl_set(IN osm_pkey_tbl_t * p_pkey_tbl, if (ib_pkey_is_invalid(pkey)) continue; + if (allow_both_pkeys) + pkey_base = pkey; + else + pkey_base = ib_pkey_get_base(pkey); + /* + If allow_both_pkeys is FALSE, ignore the PKey Full Member bit in the key but store the pointer to the table element as the map value */ - p_prev_pkey = - cl_map_get(&p_pkey_tbl->keys, - ib_pkey_get_base(pkey)); + p_prev_pkey = cl_map_get(&p_pkey_tbl->keys, pkey_base); - /* we only insert if no previous or it is not full member */ + /* we only insert if no previous or it is not full member and allow_both_pkeys is FALSE */ if ((p_prev_pkey == NULL) || - (cl_ntoh16(*p_prev_pkey) < cl_ntoh16(pkey))) - cl_map_insert(&p_pkey_tbl->keys, - ib_pkey_get_base(pkey), + (allow_both_pkeys == FALSE && + cl_ntoh16(*p_prev_pkey) < cl_ntoh16(pkey))) + cl_map_insert(&p_pkey_tbl->keys, pkey_base, &(p_pkey_block->pkey_entry[i]) ); } diff --git a/opensm/osm_pkey_mgr.c b/opensm/osm_pkey_mgr.c index 898a3b8..2fff373 100644 --- a/opensm/osm_pkey_mgr.c +++ b/opensm/osm_pkey_mgr.c @@ -104,7 +104,11 @@ pkey_mgr_process_physical_port(IN osm_log_t * p_log, return; } p_pending->pkey = pkey; - p_orig_pkey = cl_map_get(&p_pkey_tbl->keys, ib_pkey_get_base(pkey)); + if (sm->p_subn->opt.allow_both_pkeys) + p_orig_pkey = cl_map_get(&p_pkey_tbl->keys, pkey); + else + p_orig_pkey = cl_map_get(&p_pkey_tbl->keys, + ib_pkey_get_base(pkey)); if (!p_orig_pkey) { p_pending->is_new = TRUE; cl_qlist_insert_tail(&p_pkey_tbl->pending, diff --git a/opensm/osm_port.c b/opensm/osm_port.c index 9c94719..b8e4988 100644 --- a/opensm/osm_port.c +++ b/opensm/osm_port.c @@ -633,7 +633,8 @@ void osm_physp_set_pkey_tbl(IN osm_log_t * p_log, IN const osm_subn_t * p_subn, return; } - osm_pkey_tbl_set(&p_physp->pkeys, block_num, p_pkey_tbl); + osm_pkey_tbl_set(&p_physp->pkeys, block_num, p_pkey_tbl, + p_subn->opt.allow_both_pkeys); } osm_alias_guid_t *osm_alias_guid_new(IN const ib_net64_t alias_guid, diff --git a/opensm/osm_prtn.c b/opensm/osm_prtn.c index 3fd4fc0..5598fd4 100644 --- a/opensm/osm_prtn.c +++ b/opensm/osm_prtn.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2006-2009 Voltaire, Inc. All rights reserved. + * Copyright (c) 2010 Mellanox Technologies LTD. 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 @@ -117,14 +118,24 @@ ib_api_status_t osm_prtn_add_port(osm_log_t * p_log, osm_subn_t * p_subn, return status; } - if (cl_map_remove(&p->part_guid_tbl, guid) || - cl_map_remove(&p->full_guid_tbl, guid)) - OSM_LOG(p_log, OSM_LOG_VERBOSE, "port 0x%" PRIx64 " already " - "in partition \'%s\' (0x%04x). Will overwrite\n", - cl_ntoh64(guid), p->name, cl_ntoh16(p->pkey)); - p_tbl = (full == TRUE) ? &p->full_guid_tbl : &p->part_guid_tbl; + if (p_subn->opt.allow_both_pkeys) { + if (cl_map_remove(p_tbl, guid)) + OSM_LOG(p_log, OSM_LOG_ERROR, "port 0x%" PRIx64 + " already in partition \'%s\' (0x%04x) full %d." + " Will overwrite\n", + cl_ntoh64(guid), p->name, cl_ntoh16(p->pkey), + full); + } else { + if (cl_map_remove(&p->part_guid_tbl, guid) || + cl_map_remove(&p->full_guid_tbl, guid)) + OSM_LOG(p_log, OSM_LOG_VERBOSE, "port 0x%" PRIx64 + " already in partition \'%s\' (0x%04x)." + " Will overwrite\n", + cl_ntoh64(guid), p->name, cl_ntoh16(p->pkey)); + } + if (cl_map_insert(p_tbl, guid, p_physp) == NULL) return IB_INSUFFICIENT_MEMORY; diff --git a/opensm/osm_prtn_config.c b/opensm/osm_prtn_config.c index 0d02597..4c4c3a5 100644 --- a/opensm/osm_prtn_config.c +++ b/opensm/osm_prtn_config.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2006-2008 Voltaire, Inc. All rights reserved. + * Copyright (c) 2010 Mellanox Technologies LTD. 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 @@ -52,12 +53,18 @@ #include <opensm/osm_subnet.h> #include <opensm/osm_log.h> +typedef enum { + LIMITED, + FULL, + BOTH +} membership_t; + struct part_conf { osm_log_t *p_log; osm_subn_t *p_subn; osm_prtn_t *p_prtn; unsigned is_ipoib, mtu, rate, sl, scope_mask; - boolean_t full; + membership_t membership; }; extern osm_prtn_t *osm_prtn_make_new(osm_log_t * p_log, osm_subn_t * p_subn, @@ -171,13 +178,20 @@ static int partition_add_flag(unsigned lineno, struct part_conf *conf, conf->sl = sl; } else if (!strncmp(flag, "defmember", len)) { if (!val || (strncmp(val, "limited", strlen(val)) + && strncmp(val, "both", strlen(val)) && strncmp(val, "full", strlen(val)))) OSM_LOG(conf->p_log, OSM_LOG_VERBOSE, "PARSE WARN: line %d: " - "flag \'defmember\' requires valid value (limited or full)" + "flag \'defmember\' requires valid value (limited or full or both)" " - skipped\n", lineno); - else - conf->full = strncmp(val, "full", strlen(val)) == 0; + else { + if (!strncmp(val, "full", strlen(val))) + conf->membership = FULL; + else if (!strncmp(val, "both", strlen(val))) + conf->membership = BOTH; + else + conf->membership = LIMITED; + } } else { OSM_LOG(conf->p_log, OSM_LOG_VERBOSE, "PARSE WARN: line %d: " @@ -187,22 +201,36 @@ static int partition_add_flag(unsigned lineno, struct part_conf *conf, return 0; } +static int partition_add_all(struct part_conf *conf, osm_prtn_t * p, + unsigned type, membership_t membership) +{ + if (membership != LIMITED && + osm_prtn_add_all(conf->p_log, conf->p_subn, p, type, TRUE) != IB_SUCCESS) + return -1; + if (membership != FULL && + osm_prtn_add_all(conf->p_log, conf->p_subn, p, type, FALSE) != IB_SUCCESS) + return -1; + return 0; +} + static int partition_add_port(unsigned lineno, struct part_conf *conf, char *name, char *flag) { osm_prtn_t *p = conf->p_prtn; ib_net64_t guid; - boolean_t full = conf->full; + membership_t membership = conf->membership; if (!name || !*name || !strncmp(name, "NONE", strlen(name))) return 0; if (flag) { /* reset default membership to limited */ - full = FALSE; + membership = LIMITED; if (!strncmp(flag, "full", strlen(flag))) - full = TRUE; - else if (strncmp(flag, "limited", strlen(flag))) { + membership = FULL; + else if (!strncmp(flag, "both", strlen(flag))) + membership = BOTH; + else if (!strncmp(flag, "limited", strlen(flag))) { OSM_LOG(conf->p_log, OSM_LOG_VERBOSE, "PARSE WARN: line %d: " "unrecognized port flag \'%s\'." @@ -210,19 +238,17 @@ static int partition_add_port(unsigned lineno, struct part_conf *conf, } } - if (!strncmp(name, "ALL", strlen(name))) { - return osm_prtn_add_all(conf->p_log, conf->p_subn, p, - 0, full) == IB_SUCCESS ? 0 : -1; - } else if (!strncmp(name, "ALL_CAS", strlen(name))) { - return osm_prtn_add_all(conf->p_log, conf->p_subn, p, - IB_NODE_TYPE_CA, full) == IB_SUCCESS ? 0 : -1; - } else if (!strncmp(name, "ALL_SWITCHES", strlen(name))) { - return osm_prtn_add_all(conf->p_log, conf->p_subn, p, - IB_NODE_TYPE_SWITCH, full) == IB_SUCCESS ? 0 : -1; - } else if (!strncmp(name, "ALL_ROUTERS", strlen(name))) { - return osm_prtn_add_all(conf->p_log, conf->p_subn, p, - IB_NODE_TYPE_ROUTER, full) == IB_SUCCESS ? 0 : -1; - } else if (!strncmp(name, "SELF", strlen(name))) { + if (!strncmp(name, "ALL", strlen(name))) + return partition_add_all(conf, p, 0, membership); + else if (!strncmp(name, "ALL_CAS", strlen(name))) + return partition_add_all(conf, p, IB_NODE_TYPE_CA, membership); + else if (!strncmp(name, "ALL_SWITCHES", strlen(name))) + return partition_add_all(conf, p, IB_NODE_TYPE_SWITCH, + membership); + else if (!strncmp(name, "ALL_ROUTERS", strlen(name))) + return partition_add_all(conf, p, IB_NODE_TYPE_ROUTER, + membership); + else if (!strncmp(name, "SELF", strlen(name))) { guid = cl_ntoh64(conf->p_subn->sm_port_guid); } else { char *end; @@ -231,10 +257,14 @@ static int partition_add_port(unsigned lineno, struct part_conf *conf, return -1; } - if (osm_prtn_add_port(conf->p_log, conf->p_subn, p, - cl_hton64(guid), full) != IB_SUCCESS) + if (membership != LIMITED && + osm_prtn_add_port(conf->p_log, conf->p_subn, p, + cl_hton64(guid), TRUE) != IB_SUCCESS) + return -1; + if (membership != FULL && + osm_prtn_add_port(conf->p_log, conf->p_subn, p, + cl_hton64(guid), FALSE) != IB_SUCCESS) return -1; - return 0; } @@ -299,7 +329,7 @@ static struct part_conf *new_part_conf(osm_log_t * p_log, osm_subn_t * p_subn) conf->p_prtn = NULL; conf->is_ipoib = 0; conf->sl = OSM_DEFAULT_SL; - conf->full = FALSE; + conf->membership = LIMITED; return conf; } diff --git a/opensm/osm_subnet.c b/opensm/osm_subnet.c index 2e94aa1..a15eafd 100644 --- a/opensm/osm_subnet.c +++ b/opensm/osm_subnet.c @@ -340,6 +340,7 @@ static const opt_rec_t opt_tbl[] = { { "accum_log_file", OPT_OFFSET(accum_log_file), opts_parse_boolean, opts_setup_accum_log_file, 1 }, { "partition_config_file", OPT_OFFSET(partition_config_file), opts_parse_charp, NULL, 0 }, { "no_partition_enforcement", OPT_OFFSET(no_partition_enforcement), opts_parse_boolean, NULL, 1 }, + { "allow_both_pkeys", OPT_OFFSET(allow_both_pkeys), opts_parse_boolean, NULL, 1 }, { "qos", OPT_OFFSET(qos), opts_parse_boolean, NULL, 1 }, { "qos_policy_file", OPT_OFFSET(qos_policy_file), opts_parse_charp, NULL, 0 }, { "dump_files_dir", OPT_OFFSET(dump_files_dir), opts_parse_charp, NULL, 0 }, @@ -755,6 +756,7 @@ void osm_subn_set_default_opt(IN osm_subn_opt_t * p_opt) p_opt->log_max_size = 0; p_opt->partition_config_file = strdup(OSM_DEFAULT_PARTITION_CONFIG_FILE); p_opt->no_partition_enforcement = FALSE; + p_opt->allow_both_pkeys = FALSE; p_opt->qos = FALSE; p_opt->qos_policy_file = strdup(OSM_DEFAULT_QOS_POLICY_FILE); p_opt->accum_log_file = TRUE; @@ -1360,9 +1362,12 @@ int osm_subn_output_conf(FILE *out, IN osm_subn_opt_t * p_opts) "# Partition configuration file to be used\n" "partition_config_file %s\n\n" "# Disable partition enforcement by switches\n" - "no_partition_enforcement %s\n\n", + "no_partition_enforcement %s\n\n" + "# Allow both full and limited membership on the same partition\n" + "allow_both_pkeys %s\n\n", p_opts->partition_config_file, - p_opts->no_partition_enforcement ? "TRUE" : "FALSE"); + p_opts->no_partition_enforcement ? "TRUE" : "FALSE", + p_opts->allow_both_pkeys ? "TRUE" : "FALSE"); fprintf(out, "#\n# SWEEP OPTIONS\n#\n" -- 1.7.6.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
