|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* This software is available to you under a choice of one of two
|
|
Packit Service |
54dbc3 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit Service |
54dbc3 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit Service |
54dbc3 |
* COPYING in the main directory of this source tree, or the
|
|
Packit Service |
54dbc3 |
* OpenIB.org BSD license below:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* Redistribution and use in source and binary forms, with or
|
|
Packit Service |
54dbc3 |
* without modification, are permitted provided that the following
|
|
Packit Service |
54dbc3 |
* conditions are met:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions of source code must retain the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions in binary form must reproduce the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer in the documentation and/or other materials
|
|
Packit Service |
54dbc3 |
* provided with the distribution.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit Service |
54dbc3 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit Service |
54dbc3 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit Service |
54dbc3 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit Service |
54dbc3 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit Service |
54dbc3 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit Service |
54dbc3 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit Service |
54dbc3 |
* SOFTWARE.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Abstract:
|
|
Packit Service |
54dbc3 |
* Implementation of the P_Key Manager (Partition Manager).
|
|
Packit Service |
54dbc3 |
* This is part of the OpenSM.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#if HAVE_CONFIG_H
|
|
Packit Service |
54dbc3 |
# include <config.h>
|
|
Packit Service |
54dbc3 |
#endif /* HAVE_CONFIG_H */
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#include <string.h>
|
|
Packit Service |
54dbc3 |
#include <iba/ib_types.h>
|
|
Packit Service |
54dbc3 |
#include <complib/cl_qmap.h>
|
|
Packit Service |
54dbc3 |
#include <complib/cl_debug.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_file_ids.h>
|
|
Packit Service |
54dbc3 |
#define FILE_ID OSM_FILE_PKEY_MGR_C
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_node.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_switch.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_partition.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_opensm.h>
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void clear_accum_pkey_index(osm_pkey_tbl_t * p_pkey_tbl,
|
|
Packit Service |
54dbc3 |
uint16_t pkey_index);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
The max number of pkeys/pkey blocks for a physical port is located
|
|
Packit Service |
54dbc3 |
in a different place for switch external ports (SwitchInfo) and the
|
|
Packit Service |
54dbc3 |
rest of the ports (NodeInfo).
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static uint16_t
|
|
Packit Service |
54dbc3 |
pkey_mgr_get_physp_max_pkeys(IN const osm_physp_t * p_physp)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node = osm_physp_get_node_ptr(p_physp);
|
|
Packit Service |
54dbc3 |
uint16_t num_pkeys = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!p_node->sw || (osm_physp_get_port_num(p_physp) == 0))
|
|
Packit Service |
54dbc3 |
num_pkeys = cl_ntoh16(p_node->node_info.partition_cap);
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
num_pkeys = cl_ntoh16(p_node->sw->switch_info.enforce_cap);
|
|
Packit Service |
54dbc3 |
return num_pkeys;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static uint16_t
|
|
Packit Service |
54dbc3 |
pkey_mgr_get_physp_max_blocks(IN const osm_physp_t * p_physp)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
return ((pkey_mgr_get_physp_max_pkeys(p_physp) + 31) / 32);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Insert new pending pkey entry to the specific port pkey table
|
|
Packit Service |
54dbc3 |
* pending pkeys. New entries are inserted at the back.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static void
|
|
Packit Service |
54dbc3 |
pkey_mgr_process_physical_port(IN osm_log_t * p_log,
|
|
Packit Service |
54dbc3 |
IN osm_sm_t * sm,
|
|
Packit Service |
54dbc3 |
IN const ib_net16_t pkey,
|
|
Packit Service |
54dbc3 |
IN osm_physp_t * p_physp)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node = osm_physp_get_node_ptr(p_physp);
|
|
Packit Service |
54dbc3 |
osm_pkey_tbl_t *p_pkey_tbl;
|
|
Packit Service |
54dbc3 |
ib_net16_t *p_orig_pkey;
|
|
Packit Service |
54dbc3 |
osm_pending_pkey_t *p_pending;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_pkey_tbl = &p_physp->pkeys;
|
|
Packit Service |
54dbc3 |
p_pending = (osm_pending_pkey_t *) calloc(1, sizeof(osm_pending_pkey_t));
|
|
Packit Service |
54dbc3 |
if (!p_pending) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0502: "
|
|
Packit Service |
54dbc3 |
"Failed to allocate new pending pkey entry for node "
|
|
Packit Service |
54dbc3 |
"0x%016" PRIx64 " port %u\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp));
|
|
Packit Service |
54dbc3 |
return;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
p_pending->pkey = pkey;
|
|
Packit Service |
54dbc3 |
if (sm->p_subn->opt.allow_both_pkeys)
|
|
Packit Service |
54dbc3 |
p_orig_pkey = cl_map_get(&p_pkey_tbl->keys, pkey);
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
p_orig_pkey = cl_map_get(&p_pkey_tbl->keys,
|
|
Packit Service |
54dbc3 |
ib_pkey_get_base(pkey));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!p_orig_pkey) {
|
|
Packit Service |
54dbc3 |
p_pending->is_new = TRUE;
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
CL_ASSERT(ib_pkey_get_base(*p_orig_pkey) ==
|
|
Packit Service |
54dbc3 |
ib_pkey_get_base(pkey));
|
|
Packit Service |
54dbc3 |
p_pending->is_new = FALSE;
|
|
Packit Service |
54dbc3 |
if (osm_pkey_tbl_get_block_and_idx(p_pkey_tbl, p_orig_pkey,
|
|
Packit Service |
54dbc3 |
&p_pending->block,
|
|
Packit Service |
54dbc3 |
&p_pending->index) !=
|
|
Packit Service |
54dbc3 |
IB_SUCCESS) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0503: "
|
|
Packit Service |
54dbc3 |
"Failed to obtain P_Key 0x%04x block and index "
|
|
Packit Service |
54dbc3 |
"for node 0x%016" PRIx64 " port %u\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh16(ib_pkey_get_base(pkey)),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp));
|
|
Packit Service |
54dbc3 |
free(p_pending);
|
|
Packit Service |
54dbc3 |
return;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
if (p_physp->pkeys.indx0_pkey) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Remove the pkey that should be at index 0 from
|
|
Packit Service |
54dbc3 |
* accum pkey if current position is not index 0
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (((sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
pkey == p_physp->pkeys.indx0_pkey) ||
|
|
Packit Service |
54dbc3 |
(!sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
ib_pkey_get_base(pkey) == ib_pkey_get_base(p_physp->pkeys.indx0_pkey))) &&
|
|
Packit Service |
54dbc3 |
(p_pending->block != 0 || p_pending->index != 0)) {
|
|
Packit Service |
54dbc3 |
p_pending->is_new = TRUE;
|
|
Packit Service |
54dbc3 |
clear_accum_pkey_index(p_pkey_tbl,
|
|
Packit Service |
54dbc3 |
p_pending->block *
|
|
Packit Service |
54dbc3 |
IB_NUM_PKEY_ELEMENTS_IN_BLOCK +
|
|
Packit Service |
54dbc3 |
p_pending->index);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_pending->block == 0 && p_pending->index == 0) {
|
|
Packit Service |
54dbc3 |
/* Move the pkey away from index 0 */
|
|
Packit Service |
54dbc3 |
if ((sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
pkey != p_physp->pkeys.indx0_pkey) ||
|
|
Packit Service |
54dbc3 |
(!sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
ib_pkey_get_base(pkey) != ib_pkey_get_base(p_physp->pkeys.indx0_pkey))) {
|
|
Packit Service |
54dbc3 |
p_pending->is_new = TRUE;
|
|
Packit Service |
54dbc3 |
clear_accum_pkey_index(p_pkey_tbl, 0);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
/* If index 0 is occupied by non-default, it should reoccupied by pkey 0x7FFF */
|
|
Packit Service |
54dbc3 |
if (p_pending->block == 0 && p_pending->index == 0) {
|
|
Packit Service |
54dbc3 |
if (ib_pkey_get_base(pkey) != IB_DEFAULT_PARTIAL_PKEY) {
|
|
Packit Service |
54dbc3 |
p_pending->is_new = TRUE;
|
|
Packit Service |
54dbc3 |
clear_accum_pkey_index(p_pkey_tbl, 0);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
/* Need to move default pkey to index 0 */
|
|
Packit Service |
54dbc3 |
} else if ((sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
pkey == IB_DEFAULT_PKEY) ||
|
|
Packit Service |
54dbc3 |
(!sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
ib_pkey_get_base(pkey) == IB_DEFAULT_PARTIAL_PKEY)) {
|
|
Packit Service |
54dbc3 |
p_pending->is_new = TRUE;
|
|
Packit Service |
54dbc3 |
clear_accum_pkey_index(p_pkey_tbl,
|
|
Packit Service |
54dbc3 |
p_pending->block *
|
|
Packit Service |
54dbc3 |
IB_NUM_PKEY_ELEMENTS_IN_BLOCK +
|
|
Packit Service |
54dbc3 |
p_pending->index);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
if (p_pending->is_new == TRUE)
|
|
Packit Service |
54dbc3 |
cl_qlist_insert_tail(&p_pkey_tbl->pending,
|
|
Packit Service |
54dbc3 |
(cl_list_item_t *) p_pending);
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
cl_qlist_insert_head(&p_pkey_tbl->pending,
|
|
Packit Service |
54dbc3 |
(cl_list_item_t *) p_pending);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"pkey 0x%04x was %s for node 0x%016" PRIx64 " port %u\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh16(pkey), p_pending->is_new ? "inserted" : "updated",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp));
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void
|
|
Packit Service |
54dbc3 |
pkey_mgr_process_partition_table(osm_log_t * p_log, osm_sm_t * sm,
|
|
Packit Service |
54dbc3 |
const osm_prtn_t * p_prtn,
|
|
Packit Service |
54dbc3 |
const boolean_t full)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
const cl_map_t *p_tbl =
|
|
Packit Service |
54dbc3 |
full ? &p_prtn->full_guid_tbl : &p_prtn->part_guid_tbl;
|
|
Packit Service |
54dbc3 |
cl_map_iterator_t i, i_next;
|
|
Packit Service |
54dbc3 |
ib_net16_t pkey = p_prtn->pkey;
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (full)
|
|
Packit Service |
54dbc3 |
pkey |= cl_hton16(0x8000);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
i_next = cl_map_head(p_tbl);
|
|
Packit Service |
54dbc3 |
while (i_next != cl_map_end(p_tbl)) {
|
|
Packit Service |
54dbc3 |
i = i_next;
|
|
Packit Service |
54dbc3 |
i_next = cl_map_next(i);
|
|
Packit Service |
54dbc3 |
p_physp = cl_map_obj(i);
|
|
Packit Service |
54dbc3 |
if (p_physp)
|
|
Packit Service |
54dbc3 |
pkey_mgr_process_physical_port(p_log, sm, pkey,
|
|
Packit Service |
54dbc3 |
p_physp);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static ib_api_status_t
|
|
Packit Service |
54dbc3 |
pkey_mgr_update_pkey_entry(IN osm_sm_t * sm,
|
|
Packit Service |
54dbc3 |
IN const osm_physp_t * p_physp,
|
|
Packit Service |
54dbc3 |
IN const ib_pkey_table_t * block,
|
|
Packit Service |
54dbc3 |
IN const uint16_t block_index)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_madw_context_t context;
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node = osm_physp_get_node_ptr(p_physp);
|
|
Packit Service |
54dbc3 |
osm_physp_t *physp0;
|
|
Packit Service |
54dbc3 |
uint32_t attr_mod;
|
|
Packit Service |
54dbc3 |
ib_net64_t m_key;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
context.pkey_context.node_guid = osm_node_get_node_guid(p_node);
|
|
Packit Service |
54dbc3 |
context.pkey_context.port_guid = osm_physp_get_port_guid(p_physp);
|
|
Packit Service |
54dbc3 |
context.pkey_context.set_method = TRUE;
|
|
Packit Service |
54dbc3 |
attr_mod = block_index;
|
|
Packit Service |
54dbc3 |
if (osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH &&
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp) != 0) {
|
|
Packit Service |
54dbc3 |
attr_mod |= osm_physp_get_port_num(p_physp) << 16;
|
|
Packit Service |
54dbc3 |
physp0 = osm_node_get_physp_ptr(p_node, 0);
|
|
Packit Service |
54dbc3 |
m_key = ib_port_info_get_m_key(&physp0->port_info);
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
m_key = ib_port_info_get_m_key(&p_physp->port_info);
|
|
Packit Service |
54dbc3 |
return osm_req_set(sm, osm_physp_get_dr_path_ptr(p_physp),
|
|
Packit Service |
54dbc3 |
(uint8_t *) block, sizeof(*block),
|
|
Packit Service |
54dbc3 |
IB_MAD_ATTR_P_KEY_TABLE,
|
|
Packit Service |
54dbc3 |
cl_hton32(attr_mod), FALSE, m_key,
|
|
Packit Service |
54dbc3 |
0, CL_DISP_MSGID_NONE, &context);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static ib_api_status_t
|
|
Packit Service |
54dbc3 |
pkey_mgr_enforce_partition(IN osm_log_t * p_log, osm_sm_t * sm,
|
|
Packit Service |
54dbc3 |
IN osm_physp_t * p_physp,
|
|
Packit Service |
54dbc3 |
IN osm_partition_enforce_type_enum enforce_type)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_madw_context_t context;
|
|
Packit Service |
54dbc3 |
uint8_t payload[IB_SMP_DATA_SIZE];
|
|
Packit Service |
54dbc3 |
ib_port_info_t *p_pi;
|
|
Packit Service |
54dbc3 |
ib_net64_t m_key;
|
|
Packit Service |
54dbc3 |
osm_physp_t *physp0;
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
uint8_t enforce_bits;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_pi = &p_physp->port_info;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (enforce_type == OSM_PARTITION_ENFORCE_TYPE_BOTH)
|
|
Packit Service |
54dbc3 |
enforce_bits = 0xc;
|
|
Packit Service |
54dbc3 |
else if (enforce_type == OSM_PARTITION_ENFORCE_TYPE_IN)
|
|
Packit Service |
54dbc3 |
enforce_bits = 0x8;
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
enforce_bits = 0x4;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if ((p_pi->vl_enforce & 0xc) == enforce_bits *
|
|
Packit Service |
54dbc3 |
(enforce_type != OSM_PARTITION_ENFORCE_TYPE_OFF)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"No need to update PortInfo for "
|
|
Packit Service |
54dbc3 |
"node 0x%016" PRIx64 " port %u (%s)\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid
|
|
Packit Service |
54dbc3 |
(osm_physp_get_node_ptr(p_physp))),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp),
|
|
Packit Service |
54dbc3 |
p_physp->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
return IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memcpy(payload, p_pi, sizeof(ib_port_info_t));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_pi = (ib_port_info_t *) payload;
|
|
Packit Service |
54dbc3 |
p_pi->vl_enforce &= ~0xc;
|
|
Packit Service |
54dbc3 |
if (enforce_type != OSM_PARTITION_ENFORCE_TYPE_OFF)
|
|
Packit Service |
54dbc3 |
p_pi->vl_enforce |= enforce_bits;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_pi->state_info2 = 0;
|
|
Packit Service |
54dbc3 |
ib_port_info_set_port_state(p_pi, IB_LINK_NO_CHANGE);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
physp0 = osm_node_get_physp_ptr(p_physp->p_node, 0);
|
|
Packit Service |
54dbc3 |
m_key = ib_port_info_get_m_key(&physp0->port_info);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
context.pi_context.node_guid =
|
|
Packit Service |
54dbc3 |
osm_node_get_node_guid(osm_physp_get_node_ptr(p_physp));
|
|
Packit Service |
54dbc3 |
context.pi_context.port_guid = osm_physp_get_port_guid(p_physp);
|
|
Packit Service |
54dbc3 |
context.pi_context.set_method = TRUE;
|
|
Packit Service |
54dbc3 |
context.pi_context.light_sweep = FALSE;
|
|
Packit Service |
54dbc3 |
context.pi_context.active_transition = FALSE;
|
|
Packit Service |
54dbc3 |
context.pi_context.client_rereg = FALSE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = osm_req_set(sm, osm_physp_get_dr_path_ptr(p_physp),
|
|
Packit Service |
54dbc3 |
payload, sizeof(payload),
|
|
Packit Service |
54dbc3 |
IB_MAD_ATTR_PORT_INFO,
|
|
Packit Service |
54dbc3 |
cl_hton32(osm_physp_get_port_num(p_physp)),
|
|
Packit Service |
54dbc3 |
FALSE, m_key,
|
|
Packit Service |
54dbc3 |
0, CL_DISP_MSGID_NONE, &context);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0511: "
|
|
Packit Service |
54dbc3 |
"Failed to set PortInfo for "
|
|
Packit Service |
54dbc3 |
"node 0x%016" PRIx64 " port %u (%s)\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid
|
|
Packit Service |
54dbc3 |
(osm_physp_get_node_ptr(p_physp))),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp),
|
|
Packit Service |
54dbc3 |
p_physp->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Set PortInfo for node 0x%016" PRIx64 " port %u (%s)\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid
|
|
Packit Service |
54dbc3 |
(osm_physp_get_node_ptr(p_physp))),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp),
|
|
Packit Service |
54dbc3 |
p_physp->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
return status;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void clear_accum_pkey_index(osm_pkey_tbl_t * p_pkey_tbl,
|
|
Packit Service |
54dbc3 |
uint16_t pkey_index)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
uint16_t pkey_idx_bias, pkey_idx;
|
|
Packit Service |
54dbc3 |
void *ptr;
|
|
Packit Service |
54dbc3 |
uintptr_t pkey_idx_ptr;
|
|
Packit Service |
54dbc3 |
cl_map_iterator_t map_iter, map_iter_temp;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
map_iter = cl_map_head(&p_pkey_tbl->accum_pkeys);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
pkey_idx_bias = pkey_index + 1; // adjust for pkey index bias in accum_pkeys
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
while (map_iter != cl_map_end(&p_pkey_tbl->accum_pkeys)) {
|
|
Packit Service |
54dbc3 |
map_iter_temp = cl_map_next(map_iter);
|
|
Packit Service |
54dbc3 |
ptr = (uint16_t *) cl_map_obj(map_iter);
|
|
Packit Service |
54dbc3 |
CL_ASSERT(ptr);
|
|
Packit Service |
54dbc3 |
pkey_idx_ptr = (uintptr_t) ptr;
|
|
Packit Service |
54dbc3 |
pkey_idx = pkey_idx_ptr;
|
|
Packit Service |
54dbc3 |
if (pkey_idx == pkey_idx_bias) {
|
|
Packit Service |
54dbc3 |
cl_map_remove_item(&p_pkey_tbl->accum_pkeys, map_iter);
|
|
Packit Service |
54dbc3 |
if (p_pkey_tbl->last_pkey_idx == pkey_idx)
|
|
Packit Service |
54dbc3 |
osm_pkey_find_last_accum_pkey_index(p_pkey_tbl);
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
map_iter = map_iter_temp;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static int last_accum_pkey_index(osm_pkey_tbl_t * p_pkey_tbl,
|
|
Packit Service |
54dbc3 |
uint16_t * p_block_idx,
|
|
Packit Service |
54dbc3 |
uint8_t * p_pkey_idx)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
if (p_pkey_tbl->last_pkey_idx) {
|
|
Packit Service |
54dbc3 |
*p_block_idx = (p_pkey_tbl->last_pkey_idx - 1) / IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
|
|
Packit Service |
54dbc3 |
*p_pkey_idx = (p_pkey_tbl->last_pkey_idx - 1) % IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
|
|
Packit Service |
54dbc3 |
return 1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static int pkey_mgr_update_port(osm_log_t * p_log, osm_sm_t * sm,
|
|
Packit Service |
54dbc3 |
const osm_port_t * const p_port)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp;
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node;
|
|
Packit Service |
54dbc3 |
ib_pkey_table_t *block, *new_block;
|
|
Packit Service |
54dbc3 |
osm_pkey_tbl_t *p_pkey_tbl;
|
|
Packit Service |
54dbc3 |
uint16_t block_index;
|
|
Packit Service |
54dbc3 |
uint8_t pkey_index;
|
|
Packit Service |
54dbc3 |
uint16_t last_free_block_index = 0;
|
|
Packit Service |
54dbc3 |
uint8_t last_free_pkey_index = 0;
|
|
Packit Service |
54dbc3 |
uint16_t num_of_blocks;
|
|
Packit Service |
54dbc3 |
uint16_t max_num_of_blocks;
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
osm_pending_pkey_t *p_pending;
|
|
Packit Service |
54dbc3 |
boolean_t found;
|
|
Packit Service |
54dbc3 |
ib_pkey_table_t empty_block;
|
|
Packit Service |
54dbc3 |
int ret = 0, full = 0;
|
|
Packit Service |
54dbc3 |
void *ptr;
|
|
Packit Service |
54dbc3 |
uintptr_t pkey_idx_ptr;
|
|
Packit Service |
54dbc3 |
uint16_t pkey_idx;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_physp = p_port->p_physp;
|
|
Packit Service |
54dbc3 |
if (!p_physp)
|
|
Packit Service |
54dbc3 |
return FALSE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memset(&empty_block, 0, sizeof(ib_pkey_table_t));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_node = osm_physp_get_node_ptr(p_physp);
|
|
Packit Service |
54dbc3 |
p_pkey_tbl = &p_physp->pkeys;
|
|
Packit Service |
54dbc3 |
num_of_blocks = osm_pkey_tbl_get_num_blocks(p_pkey_tbl);
|
|
Packit Service |
54dbc3 |
max_num_of_blocks = pkey_mgr_get_physp_max_blocks(p_physp);
|
|
Packit Service |
54dbc3 |
if (p_pkey_tbl->max_blocks > max_num_of_blocks) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_INFO,
|
|
Packit Service |
54dbc3 |
"Max number of blocks reduced from %u to %u "
|
|
Packit Service |
54dbc3 |
"for node 0x%016" PRIx64 " port %u (%s)\n",
|
|
Packit Service |
54dbc3 |
p_pkey_tbl->max_blocks, max_num_of_blocks,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp),
|
|
Packit Service |
54dbc3 |
p_physp->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
p_pkey_tbl->max_blocks = max_num_of_blocks;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_pkey_tbl_init_new_blocks(p_pkey_tbl);
|
|
Packit Service |
54dbc3 |
p_pkey_tbl->used_blocks = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
process every pending pkey in order -
|
|
Packit Service |
54dbc3 |
first must be "updated" last are "new"
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_pending =
|
|
Packit Service |
54dbc3 |
(osm_pending_pkey_t *) cl_qlist_remove_head(&p_pkey_tbl->pending);
|
|
Packit Service |
54dbc3 |
while (p_pending !=
|
|
Packit Service |
54dbc3 |
(osm_pending_pkey_t *) cl_qlist_end(&p_pkey_tbl->pending)) {
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
found = FALSE;
|
|
Packit Service |
54dbc3 |
ptr = NULL;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_pending->is_new == FALSE) {
|
|
Packit Service |
54dbc3 |
block_index = p_pending->block;
|
|
Packit Service |
54dbc3 |
pkey_index = p_pending->index;
|
|
Packit Service |
54dbc3 |
found = TRUE;
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
ptr = cl_map_get(&p_pkey_tbl->accum_pkeys,p_pending->pkey);
|
|
Packit Service |
54dbc3 |
if (ptr != NULL) {
|
|
Packit Service |
54dbc3 |
pkey_idx_ptr = (uintptr_t) ptr;
|
|
Packit Service |
54dbc3 |
pkey_idx = pkey_idx_ptr;
|
|
Packit Service |
54dbc3 |
pkey_idx--; /* adjust pkey index for bias */
|
|
Packit Service |
54dbc3 |
block_index = pkey_idx / IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
|
|
Packit Service |
54dbc3 |
pkey_index = pkey_idx % IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (((sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
p_pending->pkey == p_physp->pkeys.indx0_pkey) ||
|
|
Packit Service |
54dbc3 |
(!sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
ib_pkey_get_base(p_pending->pkey) == ib_pkey_get_base(p_physp->pkeys.indx0_pkey))) ||
|
|
Packit Service |
54dbc3 |
((p_pending->pkey != p_physp->pkeys.indx0_pkey &&
|
|
Packit Service |
54dbc3 |
pkey_idx == 0))) {
|
|
Packit Service |
54dbc3 |
clear_accum_pkey_index(p_pkey_tbl, pkey_idx);
|
|
Packit Service |
54dbc3 |
cl_qlist_insert_tail(&p_pkey_tbl->pending,
|
|
Packit Service |
54dbc3 |
(cl_list_item_t *)p_pending);
|
|
Packit Service |
54dbc3 |
p_pending =
|
|
Packit Service |
54dbc3 |
(osm_pending_pkey_t *) cl_qlist_remove_head(&p_pkey_tbl->pending);
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
found = TRUE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!found) {
|
|
Packit Service |
54dbc3 |
if (!p_pkey_tbl->indx0_pkey &&
|
|
Packit Service |
54dbc3 |
((sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
p_pending->pkey == IB_DEFAULT_PKEY) ||
|
|
Packit Service |
54dbc3 |
(!sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
ib_pkey_get_base(p_pending->pkey) == IB_DEFAULT_PARTIAL_PKEY))) {
|
|
Packit Service |
54dbc3 |
block_index = 0;
|
|
Packit Service |
54dbc3 |
pkey_index = 0;
|
|
Packit Service |
54dbc3 |
} else if ((sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
p_pending->pkey == p_pkey_tbl->indx0_pkey) ||
|
|
Packit Service |
54dbc3 |
(!sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
ib_pkey_get_base(p_pending->pkey) ==
|
|
Packit Service |
54dbc3 |
ib_pkey_get_base(p_pkey_tbl->indx0_pkey))) {
|
|
Packit Service |
54dbc3 |
block_index = 0;
|
|
Packit Service |
54dbc3 |
pkey_index = 0;
|
|
Packit Service |
54dbc3 |
} else if (last_accum_pkey_index(p_pkey_tbl,
|
|
Packit Service |
54dbc3 |
&last_free_block_index,
|
|
Packit Service |
54dbc3 |
&last_free_pkey_index)) {
|
|
Packit Service |
54dbc3 |
block_index = last_free_block_index;
|
|
Packit Service |
54dbc3 |
pkey_index = last_free_pkey_index + 1;
|
|
Packit Service |
54dbc3 |
if (pkey_index >= IB_NUM_PKEY_ELEMENTS_IN_BLOCK) {
|
|
Packit Service |
54dbc3 |
block_index++;
|
|
Packit Service |
54dbc3 |
pkey_index -= IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
block_index = 0;
|
|
Packit Service |
54dbc3 |
pkey_index = 1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (block_index * IB_NUM_PKEY_ELEMENTS_IN_BLOCK + pkey_index >= pkey_mgr_get_physp_max_pkeys(p_physp)) {
|
|
Packit Service |
54dbc3 |
if ((sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
p_pending->pkey != IB_DEFAULT_PKEY) ||
|
|
Packit Service |
54dbc3 |
(!sm->p_subn->opt.allow_both_pkeys &&
|
|
Packit Service |
54dbc3 |
ib_pkey_get_base(p_pending->pkey) != IB_DEFAULT_PARTIAL_PKEY)) {
|
|
Packit Service |
54dbc3 |
last_free_block_index = 0;
|
|
Packit Service |
54dbc3 |
last_free_pkey_index = 1;
|
|
Packit Service |
54dbc3 |
found = osm_pkey_find_next_free_entry(p_pkey_tbl, &last_free_block_index, &last_free_pkey_index);
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
found = FALSE;
|
|
Packit Service |
54dbc3 |
if (!found)
|
|
Packit Service |
54dbc3 |
full = 1;
|
|
Packit Service |
54dbc3 |
else {
|
|
Packit Service |
54dbc3 |
block_index = last_free_block_index;
|
|
Packit Service |
54dbc3 |
pkey_index = last_free_pkey_index;
|
|
Packit Service |
54dbc3 |
if (block_index * IB_NUM_PKEY_ELEMENTS_IN_BLOCK + pkey_index >= pkey_mgr_get_physp_max_pkeys(p_physp)) {
|
|
Packit Service |
54dbc3 |
full = 1;
|
|
Packit Service |
54dbc3 |
found = FALSE;
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_INFO,
|
|
Packit Service |
54dbc3 |
"Reusing PKeyTable block index %u pkey index %u "
|
|
Packit Service |
54dbc3 |
"for pkey 0x%x on 0x%016" PRIx64 " port %u (%s)\n",
|
|
Packit Service |
54dbc3 |
block_index,
|
|
Packit Service |
54dbc3 |
pkey_index,
|
|
Packit Service |
54dbc3 |
cl_ntoh16(p_pending->pkey),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp),
|
|
Packit Service |
54dbc3 |
p_physp->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
clear_accum_pkey_index(p_pkey_tbl, block_index * IB_NUM_PKEY_ELEMENTS_IN_BLOCK + pkey_index);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
if (full)
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"ERR 0512: "
|
|
Packit Service |
54dbc3 |
"Failed to set PKey 0x%04x because Pkey table is full "
|
|
Packit Service |
54dbc3 |
"for node 0x%016" PRIx64 " port %u (%s)\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh16(p_pending->pkey),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp),
|
|
Packit Service |
54dbc3 |
p_physp->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
found = TRUE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (found) {
|
|
Packit Service |
54dbc3 |
if (IB_SUCCESS !=
|
|
Packit Service |
54dbc3 |
osm_pkey_tbl_set_new_entry(p_pkey_tbl, block_index,
|
|
Packit Service |
54dbc3 |
pkey_index,
|
|
Packit Service |
54dbc3 |
p_pending->pkey)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0505: "
|
|
Packit Service |
54dbc3 |
"Failed to set PKey 0x%04x in block %u idx %u "
|
|
Packit Service |
54dbc3 |
"for node 0x%016" PRIx64 " port %u (%s)\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh16(p_pending->pkey), block_index,
|
|
Packit Service |
54dbc3 |
pkey_index,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid
|
|
Packit Service |
54dbc3 |
(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp),
|
|
Packit Service |
54dbc3 |
p_physp->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
if (ptr == NULL &&
|
|
Packit Service |
54dbc3 |
CL_SUCCESS !=
|
|
Packit Service |
54dbc3 |
osm_pkey_tbl_set_accum_pkeys(p_pkey_tbl,
|
|
Packit Service |
54dbc3 |
p_pending->pkey,
|
|
Packit Service |
54dbc3 |
block_index * IB_NUM_PKEY_ELEMENTS_IN_BLOCK + pkey_index)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0508: "
|
|
Packit Service |
54dbc3 |
"Failed to set accum_pkeys PKey 0x%04x "
|
|
Packit Service |
54dbc3 |
"in block %u idx %u for node 0x%016"
|
|
Packit Service |
54dbc3 |
PRIx64 " port %u (%s)\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh16(p_pending->pkey), block_index,
|
|
Packit Service |
54dbc3 |
pkey_index,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp),
|
|
Packit Service |
54dbc3 |
p_physp->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
free(p_pending);
|
|
Packit Service |
54dbc3 |
p_pending =
|
|
Packit Service |
54dbc3 |
(osm_pending_pkey_t *) cl_qlist_remove_head(&p_pkey_tbl->
|
|
Packit Service |
54dbc3 |
pending);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_pkey_tbl->indx0_pkey = 0;
|
|
Packit Service |
54dbc3 |
/* now look for changes and store */
|
|
Packit Service |
54dbc3 |
for (block_index = 0; block_index < num_of_blocks; block_index++) {
|
|
Packit Service |
54dbc3 |
block = osm_pkey_tbl_block_get(p_pkey_tbl, block_index);
|
|
Packit Service |
54dbc3 |
new_block = osm_pkey_tbl_new_block_get(p_pkey_tbl, block_index);
|
|
Packit Service |
54dbc3 |
if (!new_block)
|
|
Packit Service |
54dbc3 |
new_block = &empty_block;
|
|
Packit Service |
54dbc3 |
if (block && !memcmp(new_block, block, sizeof(*block)))
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status =
|
|
Packit Service |
54dbc3 |
pkey_mgr_update_pkey_entry(sm, p_physp, new_block,
|
|
Packit Service |
54dbc3 |
block_index);
|
|
Packit Service |
54dbc3 |
if (status == IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Updated pkey table block %u for node 0x%016"
|
|
Packit Service |
54dbc3 |
PRIx64 " port %u (%s)\n", block_index,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp),
|
|
Packit Service |
54dbc3 |
p_physp->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
else {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0506: "
|
|
Packit Service |
54dbc3 |
"pkey_mgr_update_pkey_entry() failed to update "
|
|
Packit Service |
54dbc3 |
"pkey table block %u for node 0x%016" PRIx64
|
|
Packit Service |
54dbc3 |
" port %u (%s)\n", block_index,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(p_physp),
|
|
Packit Service |
54dbc3 |
p_physp->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static int last_used_pkey_index(const osm_port_t * const p_port,
|
|
Packit Service |
54dbc3 |
const osm_pkey_tbl_t * p_pkey_tbl,
|
|
Packit Service |
54dbc3 |
uint16_t * p_last_index)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_pkey_table_t *last_block;
|
|
Packit Service |
54dbc3 |
uint16_t index, last_index = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_last_index);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
last_block = osm_pkey_tbl_new_block_get(p_pkey_tbl,
|
|
Packit Service |
54dbc3 |
p_pkey_tbl->used_blocks - 1);
|
|
Packit Service |
54dbc3 |
if (!last_block)
|
|
Packit Service |
54dbc3 |
return 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_pkey_tbl->used_blocks == p_pkey_tbl->max_blocks)
|
|
Packit Service |
54dbc3 |
last_index = cl_ntoh16(p_port->p_node->node_info.partition_cap) % IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
|
|
Packit Service |
54dbc3 |
if (last_index == 0)
|
|
Packit Service |
54dbc3 |
last_index = IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
|
|
Packit Service |
54dbc3 |
index = last_index;
|
|
Packit Service |
54dbc3 |
do {
|
|
Packit Service |
54dbc3 |
index--;
|
|
Packit Service |
54dbc3 |
if (!ib_pkey_is_invalid(last_block->pkey_entry[index]))
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
} while (index != 0);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
*p_last_index = index;
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static int update_peer_block(osm_log_t * p_log, osm_sm_t * sm,
|
|
Packit Service |
54dbc3 |
osm_physp_t * peer,
|
|
Packit Service |
54dbc3 |
osm_pkey_tbl_t * p_peer_pkey_tbl,
|
|
Packit Service |
54dbc3 |
ib_pkey_table_t * new_peer_block,
|
|
Packit Service |
54dbc3 |
uint16_t peer_block_idx, osm_node_t * p_node)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
int ret = 0;
|
|
Packit Service |
54dbc3 |
ib_pkey_table_t *peer_block;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
peer_block = osm_pkey_tbl_block_get(p_peer_pkey_tbl, peer_block_idx);
|
|
Packit Service |
54dbc3 |
if (!peer_block ||
|
|
Packit Service |
54dbc3 |
memcmp(peer_block, new_peer_block, sizeof(*peer_block))) {
|
|
Packit Service |
54dbc3 |
if (pkey_mgr_update_pkey_entry(sm, peer, new_peer_block,
|
|
Packit Service |
54dbc3 |
peer_block_idx) != IB_SUCCESS) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0509: "
|
|
Packit Service |
54dbc3 |
"pkey_mgr_update_pkey_entry() failed to update "
|
|
Packit Service |
54dbc3 |
"pkey table block %u for node 0x%016"
|
|
Packit Service |
54dbc3 |
PRIx64 " port %u (%s)\n",
|
|
Packit Service |
54dbc3 |
peer_block_idx,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(peer),
|
|
Packit Service |
54dbc3 |
p_node->print_desc);
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static int new_pkey_exists(osm_pkey_tbl_t * p_pkey_tbl, ib_net16_t pkey)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
uint16_t num_blocks;
|
|
Packit Service |
54dbc3 |
uint16_t block_index;
|
|
Packit Service |
54dbc3 |
ib_pkey_table_t *block;
|
|
Packit Service |
54dbc3 |
uint16_t pkey_idx;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
num_blocks = (uint16_t) cl_ptr_vector_get_size(&p_pkey_tbl->new_blocks);
|
|
Packit Service |
54dbc3 |
for (block_index = 0; block_index < num_blocks; block_index++) {
|
|
Packit Service |
54dbc3 |
block = osm_pkey_tbl_new_block_get(p_pkey_tbl, block_index);
|
|
Packit Service |
54dbc3 |
if (!block)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (pkey_idx = 0; pkey_idx < IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
|
|
Packit Service |
54dbc3 |
pkey_idx++) {
|
|
Packit Service |
54dbc3 |
if (block->pkey_entry[pkey_idx] == pkey)
|
|
Packit Service |
54dbc3 |
return 1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static int pkey_mgr_update_peer_port(osm_log_t * p_log, osm_sm_t * sm,
|
|
Packit Service |
54dbc3 |
const osm_subn_t * p_subn,
|
|
Packit Service |
54dbc3 |
const osm_port_t * const p_port,
|
|
Packit Service |
54dbc3 |
osm_partition_enforce_type_enum enforce_type)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp, *peer;
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node;
|
|
Packit Service |
54dbc3 |
ib_pkey_table_t *block;
|
|
Packit Service |
54dbc3 |
const osm_pkey_tbl_t *p_pkey_tbl;
|
|
Packit Service |
54dbc3 |
osm_pkey_tbl_t *p_peer_pkey_tbl;
|
|
Packit Service |
54dbc3 |
uint16_t block_index, peer_block_idx;
|
|
Packit Service |
54dbc3 |
uint16_t peer_max_blocks;
|
|
Packit Service |
54dbc3 |
uint16_t last_index;
|
|
Packit Service |
54dbc3 |
ib_pkey_table_t new_peer_block;
|
|
Packit Service |
54dbc3 |
uint16_t pkey_idx, peer_pkey_idx;
|
|
Packit Service |
54dbc3 |
ib_net16_t pkey, full_pkey;
|
|
Packit Service |
54dbc3 |
int ret = 0, loop_exit = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_physp = p_port->p_physp;
|
|
Packit Service |
54dbc3 |
if (!p_physp)
|
|
Packit Service |
54dbc3 |
return -1;
|
|
Packit Service |
54dbc3 |
peer = osm_physp_get_remote(p_physp);
|
|
Packit Service |
54dbc3 |
if (!peer)
|
|
Packit Service |
54dbc3 |
return -1;
|
|
Packit Service |
54dbc3 |
p_node = osm_physp_get_node_ptr(peer);
|
|
Packit Service |
54dbc3 |
if (!p_node->sw || !p_node->sw->switch_info.enforce_cap)
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (enforce_type == OSM_PARTITION_ENFORCE_TYPE_OFF) {
|
|
Packit Service |
54dbc3 |
pkey_mgr_enforce_partition(p_log, sm, peer, OSM_PARTITION_ENFORCE_TYPE_OFF);
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_pkey_tbl = osm_physp_get_pkey_tbl(p_physp);
|
|
Packit Service |
54dbc3 |
peer_max_blocks = pkey_mgr_get_physp_max_blocks(peer);
|
|
Packit Service |
54dbc3 |
p_peer_pkey_tbl = &peer->pkeys;
|
|
Packit Service |
54dbc3 |
peer_block_idx = 0;
|
|
Packit Service |
54dbc3 |
peer_pkey_idx = 0;
|
|
Packit Service |
54dbc3 |
for (block_index = 0; block_index < p_pkey_tbl->used_blocks;
|
|
Packit Service |
54dbc3 |
block_index++) {
|
|
Packit Service |
54dbc3 |
if (loop_exit)
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
block = osm_pkey_tbl_new_block_get(p_pkey_tbl, block_index);
|
|
Packit Service |
54dbc3 |
if (!block)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
for (pkey_idx = 0; pkey_idx < IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
|
|
Packit Service |
54dbc3 |
pkey_idx++) {
|
|
Packit Service |
54dbc3 |
pkey = block->pkey_entry[pkey_idx];
|
|
Packit Service |
54dbc3 |
if (ib_pkey_is_invalid(pkey))
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
if (!ib_pkey_is_full_member(pkey)) {
|
|
Packit Service |
54dbc3 |
full_pkey = pkey | IB_PKEY_TYPE_MASK;
|
|
Packit Service |
54dbc3 |
if (new_pkey_exists(&p_physp->pkeys, full_pkey))
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
new_peer_block.pkey_entry[peer_pkey_idx] = pkey;
|
|
Packit Service |
54dbc3 |
if (peer_block_idx >= peer_max_blocks) {
|
|
Packit Service |
54dbc3 |
loop_exit = 1;
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
if (++peer_pkey_idx == IB_NUM_PKEY_ELEMENTS_IN_BLOCK) {
|
|
Packit Service |
54dbc3 |
if (update_peer_block(p_log, sm, peer,
|
|
Packit Service |
54dbc3 |
p_peer_pkey_tbl,
|
|
Packit Service |
54dbc3 |
&new_peer_block,
|
|
Packit Service |
54dbc3 |
peer_block_idx, p_node))
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
peer_pkey_idx = 0;
|
|
Packit Service |
54dbc3 |
peer_block_idx++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (peer_block_idx < peer_max_blocks) {
|
|
Packit Service |
54dbc3 |
if (peer_pkey_idx) {
|
|
Packit Service |
54dbc3 |
/* Handle partial last block */
|
|
Packit Service |
54dbc3 |
for (; peer_pkey_idx < IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
|
|
Packit Service |
54dbc3 |
peer_pkey_idx++)
|
|
Packit Service |
54dbc3 |
new_peer_block.pkey_entry[peer_pkey_idx] = 0;
|
|
Packit Service |
54dbc3 |
if (update_peer_block(p_log, sm, peer, p_peer_pkey_tbl,
|
|
Packit Service |
54dbc3 |
&new_peer_block, peer_block_idx,
|
|
Packit Service |
54dbc3 |
p_node))
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
peer_block_idx--;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_peer_pkey_tbl->used_blocks = peer_block_idx + 1;
|
|
Packit Service |
54dbc3 |
if (p_peer_pkey_tbl->used_blocks == peer_max_blocks) {
|
|
Packit Service |
54dbc3 |
/* Is last used pkey index beyond switch peer port capacity ? */
|
|
Packit Service |
54dbc3 |
if (!last_used_pkey_index(p_port, p_peer_pkey_tbl,
|
|
Packit Service |
54dbc3 |
&last_index)) {
|
|
Packit Service |
54dbc3 |
last_index += peer_block_idx * IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
|
|
Packit Service |
54dbc3 |
if (cl_ntoh16(p_node->sw->switch_info.enforce_cap) <= last_index) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0507: "
|
|
Packit Service |
54dbc3 |
"Not enough pkey entries (%u <= %u) on switch 0x%016"
|
|
Packit Service |
54dbc3 |
PRIx64 " port %u (%s). Clearing Enforcement bit\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh16(p_node->sw->switch_info.enforce_cap),
|
|
Packit Service |
54dbc3 |
last_index,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(peer),
|
|
Packit Service |
54dbc3 |
p_node->print_desc);
|
|
Packit Service |
54dbc3 |
enforce_type = OSM_PARTITION_ENFORCE_TYPE_OFF;
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
p_peer_pkey_tbl->used_blocks = peer_max_blocks;
|
|
Packit Service |
54dbc3 |
enforce_type = OSM_PARTITION_ENFORCE_TYPE_OFF;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!ret)
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Pkey table was successfully updated for node 0x%016"
|
|
Packit Service |
54dbc3 |
PRIx64 " port %u (%s)\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_node_get_node_guid(p_node)),
|
|
Packit Service |
54dbc3 |
osm_physp_get_port_num(peer), p_node->print_desc);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (pkey_mgr_enforce_partition(p_log, sm, peer, enforce_type))
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
int osm_pkey_mgr_process(IN osm_opensm_t * p_osm)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
cl_qmap_t *p_tbl;
|
|
Packit Service |
54dbc3 |
cl_map_item_t *p_next;
|
|
Packit Service |
54dbc3 |
osm_prtn_t *p_prtn;
|
|
Packit Service |
54dbc3 |
osm_port_t *p_port;
|
|
Packit Service |
54dbc3 |
osm_switch_t *p_sw;
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_physp;
|
|
Packit Service |
54dbc3 |
osm_pkey_tbl_t *p_pkey_tbl;
|
|
Packit Service |
54dbc3 |
osm_node_t *p_remote_node;
|
|
Packit Service |
54dbc3 |
uint8_t i;
|
|
Packit Service |
54dbc3 |
int ret = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_osm);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(&p_osm->log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_PLOCK_EXCL_ACQUIRE(&p_osm->lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (osm_prtn_make_partitions(&p_osm->log, &p_osm->subn) != IB_SUCCESS) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 0510: "
|
|
Packit Service |
54dbc3 |
"osm_prtn_make_partitions() failed\n");
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
goto _err;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!p_osm->subn.opt.keep_pkey_indexes) {
|
|
Packit Service |
54dbc3 |
p_tbl = &p_osm->subn.port_guid_tbl;
|
|
Packit Service |
54dbc3 |
p_next = cl_qmap_head(p_tbl);
|
|
Packit Service |
54dbc3 |
while (p_next != cl_qmap_end(p_tbl)) {
|
|
Packit Service |
54dbc3 |
p_port = (osm_port_t *) p_next;
|
|
Packit Service |
54dbc3 |
p_next = cl_qmap_next(p_next);
|
|
Packit Service |
54dbc3 |
if (!(p_physp = p_port->p_physp))
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
p_pkey_tbl = &p_physp->pkeys;
|
|
Packit Service |
54dbc3 |
cl_map_remove_all(&p_pkey_tbl->keys);
|
|
Packit Service |
54dbc3 |
cl_map_remove_all(&p_pkey_tbl->accum_pkeys);
|
|
Packit Service |
54dbc3 |
p_pkey_tbl->last_pkey_idx=0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* populate the pending pkey entries by scanning all partitions */
|
|
Packit Service |
54dbc3 |
p_tbl = &p_osm->subn.prtn_pkey_tbl;
|
|
Packit Service |
54dbc3 |
p_next = cl_qmap_head(p_tbl);
|
|
Packit Service |
54dbc3 |
while (p_next != cl_qmap_end(p_tbl)) {
|
|
Packit Service |
54dbc3 |
p_prtn = (osm_prtn_t *) p_next;
|
|
Packit Service |
54dbc3 |
p_next = cl_qmap_next(p_next);
|
|
Packit Service |
54dbc3 |
pkey_mgr_process_partition_table(&p_osm->log, &p_osm->sm,
|
|
Packit Service |
54dbc3 |
p_prtn, FALSE);
|
|
Packit Service |
54dbc3 |
pkey_mgr_process_partition_table(&p_osm->log, &p_osm->sm,
|
|
Packit Service |
54dbc3 |
p_prtn, TRUE);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* calculate and set new pkey tables */
|
|
Packit Service |
54dbc3 |
p_tbl = &p_osm->subn.port_guid_tbl;
|
|
Packit Service |
54dbc3 |
p_next = cl_qmap_head(p_tbl);
|
|
Packit Service |
54dbc3 |
while (p_next != cl_qmap_end(p_tbl)) {
|
|
Packit Service |
54dbc3 |
p_port = (osm_port_t *) p_next;
|
|
Packit Service |
54dbc3 |
p_next = cl_qmap_next(p_next);
|
|
Packit Service |
54dbc3 |
if (pkey_mgr_update_port(&p_osm->log, &p_osm->sm, p_port))
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
if ((osm_node_get_type(p_port->p_node) != IB_NODE_TYPE_SWITCH)
|
|
Packit Service |
54dbc3 |
&& pkey_mgr_update_peer_port(&p_osm->log, &p_osm->sm,
|
|
Packit Service |
54dbc3 |
&p_osm->subn, p_port,
|
|
Packit Service |
54dbc3 |
p_osm->subn.opt.part_enforce_enum))
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* clear partition enforcement on inter-switch links */
|
|
Packit Service |
54dbc3 |
p_tbl = &p_osm->subn.sw_guid_tbl;
|
|
Packit Service |
54dbc3 |
p_next = cl_qmap_head(p_tbl);
|
|
Packit Service |
54dbc3 |
while (p_next != cl_qmap_end(p_tbl)) {
|
|
Packit Service |
54dbc3 |
p_sw = (osm_switch_t *) p_next;
|
|
Packit Service |
54dbc3 |
p_next = cl_qmap_next(p_next);
|
|
Packit Service |
54dbc3 |
for (i = 1; i < p_sw->num_ports; i++) {
|
|
Packit Service |
54dbc3 |
p_physp = osm_node_get_physp_ptr(p_sw->p_node, i);
|
|
Packit Service |
54dbc3 |
if (p_physp && p_physp->p_remote_physp)
|
|
Packit Service |
54dbc3 |
p_remote_node = p_physp->p_remote_physp->p_node;
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (osm_node_get_type(p_remote_node) != IB_NODE_TYPE_SWITCH)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if(! (p_physp->port_info.vl_enforce & 0xc ))
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* clear partition enforcement */
|
|
Packit Service |
54dbc3 |
if (pkey_mgr_enforce_partition(&p_osm->log, &p_osm->sm, p_physp, OSM_PARTITION_ENFORCE_TYPE_OFF))
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
_err:
|
|
Packit Service |
54dbc3 |
CL_PLOCK_RELEASE(&p_osm->lock);
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(&p_osm->log);
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|