|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2002-2008 Mellanox Technologies LTD. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 1996-2003 Intel Corporation. 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 osm_lid_mgr_t.
|
|
Packit Service |
54dbc3 |
* This file implements the LID Manager object which is responsible for
|
|
Packit Service |
54dbc3 |
* assigning LIDs to all ports on the subnet.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* DATA STRUCTURES:
|
|
Packit Service |
54dbc3 |
* p_subn->port_lid_tbl : a vector pointing from lid to its port.
|
|
Packit Service |
54dbc3 |
* osm db guid2lid domain : a hash from guid to lid (min lid).
|
|
Packit Service |
54dbc3 |
* p_subn->port_guid_tbl : a map from guid to discovered port obj.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* ALGORITHM:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* 0. we define a function to obtain the correct port lid:
|
|
Packit Service |
54dbc3 |
* lid_mgr_get_port_lid( p_mgr, port, &min_lid, &max_lid ):
|
|
Packit Service |
54dbc3 |
* 0.1 if the port info lid matches the guid2lid return 0
|
|
Packit Service |
54dbc3 |
* 0.2 if the port info has a lid and that range is empty in
|
|
Packit Service |
54dbc3 |
* port_lid_tbl, return 0 and update the port_lid_tbl and
|
|
Packit Service |
54dbc3 |
* guid2lid
|
|
Packit Service |
54dbc3 |
* 0.3 else find an empty space in port_lid_tbl, update the
|
|
Packit Service |
54dbc3 |
* port_lid_tbl and guid2lid, return 1 to flag a change required.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* 1. During initialization:
|
|
Packit Service |
54dbc3 |
* 1.1 initialize the guid2lid database domain.
|
|
Packit Service |
54dbc3 |
* 1.2 if reassign_lid is not set:
|
|
Packit Service |
54dbc3 |
* 1.2.1 read the persistent data for the domain.
|
|
Packit Service |
54dbc3 |
* 1.2.2 validate no duplicate use of lids and lids are 2^(lmc-1)
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* 2. During SM port lid assignment:
|
|
Packit Service |
54dbc3 |
* 2.1 if reassign_lids is set, make it 2^lmc
|
|
Packit Service |
54dbc3 |
* 2.2 cleanup all port_lid_tbl and re-fill it according to guid2lid
|
|
Packit Service |
54dbc3 |
* 2.3 call lid_mgr_get_port_lid for the SM port
|
|
Packit Service |
54dbc3 |
* 2.4 set the port info
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* 3. During all other ports lid assignment:
|
|
Packit Service |
54dbc3 |
* 3.1 go through all ports in the subnet
|
|
Packit Service |
54dbc3 |
* 3.1.1 call lid_mgr_get_port_lid
|
|
Packit Service |
54dbc3 |
* 3.1.2 if a change required send the port info
|
|
Packit Service |
54dbc3 |
* 3.2 if any change send the signal PENDING...
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* 4. Store the guid2lid
|
|
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 <stdlib.h>
|
|
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_LID_MGR_C
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_lid_mgr.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_sm.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_log.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_node.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_switch.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_helper.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_msgdef.h>
|
|
Packit Service |
54dbc3 |
#include <vendor/osm_vendor_api.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_db_pack.h>
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
lid range item of qlist
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
typedef struct osm_lid_mgr_range {
|
|
Packit Service |
54dbc3 |
cl_list_item_t item;
|
|
Packit Service |
54dbc3 |
uint16_t min_lid;
|
|
Packit Service |
54dbc3 |
uint16_t max_lid;
|
|
Packit Service |
54dbc3 |
} osm_lid_mgr_range_t;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_lid_mgr_construct(IN osm_lid_mgr_t * p_mgr)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
memset(p_mgr, 0, sizeof(*p_mgr));
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_lid_mgr_destroy(IN osm_lid_mgr_t * p_mgr)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
cl_list_item_t *p_item;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
while ((p_item = cl_qlist_remove_head(&p_mgr->free_ranges)) !=
|
|
Packit Service |
54dbc3 |
cl_qlist_end(&p_mgr->free_ranges))
|
|
Packit Service |
54dbc3 |
free((osm_lid_mgr_range_t *) p_item);
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
Validate the guid to lid data by making sure that under the current
|
|
Packit Service |
54dbc3 |
LMC we did not get duplicates. If we do flag them as errors and remove
|
|
Packit Service |
54dbc3 |
the entry.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static void lid_mgr_validate_db(IN osm_lid_mgr_t * p_mgr)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
cl_qlist_t guids;
|
|
Packit Service |
54dbc3 |
osm_db_guid_elem_t *p_item;
|
|
Packit Service |
54dbc3 |
uint16_t lid;
|
|
Packit Service |
54dbc3 |
uint16_t min_lid;
|
|
Packit Service |
54dbc3 |
uint16_t max_lid;
|
|
Packit Service |
54dbc3 |
uint16_t lmc_mask;
|
|
Packit Service |
54dbc3 |
boolean_t lids_ok;
|
|
Packit Service |
54dbc3 |
uint8_t lmc_num_lids = (uint8_t) (1 << p_mgr->p_subn->opt.lmc);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
lmc_mask = ~(lmc_num_lids - 1);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_qlist_init(&guids);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (osm_db_guid2lid_guids(p_mgr->p_g2l, &guids)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 0310: "
|
|
Packit Service |
54dbc3 |
"could not get guid list\n");
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
while ((p_item = (osm_db_guid_elem_t *) cl_qlist_remove_head(&guids))
|
|
Packit Service |
54dbc3 |
!= (osm_db_guid_elem_t *) cl_qlist_end(&guids)) {
|
|
Packit Service |
54dbc3 |
if (osm_db_guid2lid_get(p_mgr->p_g2l, p_item->guid,
|
|
Packit Service |
54dbc3 |
&min_lid, &max_lid))
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 0311: "
|
|
Packit Service |
54dbc3 |
"could not get lid for guid:0x%016" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
p_item->guid);
|
|
Packit Service |
54dbc3 |
else {
|
|
Packit Service |
54dbc3 |
lids_ok = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (min_lid > max_lid || min_lid == 0
|
|
Packit Service |
54dbc3 |
|| p_item->guid == 0
|
|
Packit Service |
54dbc3 |
|| max_lid > p_mgr->p_subn->max_ucast_lid_ho) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"ERR 0312: "
|
|
Packit Service |
54dbc3 |
"Illegal LID range [%u:%u] for "
|
|
Packit Service |
54dbc3 |
"guid:0x%016" PRIx64 "\n", min_lid,
|
|
Packit Service |
54dbc3 |
max_lid, p_item->guid);
|
|
Packit Service |
54dbc3 |
lids_ok = FALSE;
|
|
Packit Service |
54dbc3 |
} else if (min_lid != max_lid
|
|
Packit Service |
54dbc3 |
&& (min_lid & lmc_mask) != min_lid) {
|
|
Packit Service |
54dbc3 |
/* check that if the lids define a range that is
|
|
Packit Service |
54dbc3 |
valid for the current LMC mask */
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"ERR 0313: "
|
|
Packit Service |
54dbc3 |
"LID range [%u:%u] for guid:0x%016"
|
|
Packit Service |
54dbc3 |
PRIx64
|
|
Packit Service |
54dbc3 |
" is not aligned according to mask:0x%04x\n",
|
|
Packit Service |
54dbc3 |
min_lid, max_lid, p_item->guid,
|
|
Packit Service |
54dbc3 |
lmc_mask);
|
|
Packit Service |
54dbc3 |
lids_ok = FALSE;
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
/* check if the lids were not previously assigned */
|
|
Packit Service |
54dbc3 |
for (lid = min_lid; lid <= max_lid; lid++) {
|
|
Packit Service |
54dbc3 |
if (p_mgr->used_lids[lid]) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log,
|
|
Packit Service |
54dbc3 |
OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"ERR 0314: "
|
|
Packit Service |
54dbc3 |
"0x%04x for guid:0x%016"
|
|
Packit Service |
54dbc3 |
PRIx64
|
|
Packit Service |
54dbc3 |
" was previously used\n",
|
|
Packit Service |
54dbc3 |
lid, p_item->guid);
|
|
Packit Service |
54dbc3 |
lids_ok = FALSE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (lids_ok)
|
|
Packit Service |
54dbc3 |
/* mark that it was visited */
|
|
Packit Service |
54dbc3 |
for (lid = min_lid; lid <= max_lid; lid++) {
|
|
Packit Service |
54dbc3 |
if (lid < min_lid + lmc_num_lids)
|
|
Packit Service |
54dbc3 |
p_mgr->used_lids[lid] = 1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
else if (osm_db_guid2lid_delete(p_mgr->p_g2l,
|
|
Packit Service |
54dbc3 |
p_item->guid))
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"ERR 0315: failed to delete entry for "
|
|
Packit Service |
54dbc3 |
"guid:0x%016" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
p_item->guid);
|
|
Packit Service |
54dbc3 |
} /* got a lid */
|
|
Packit Service |
54dbc3 |
free(p_item);
|
|
Packit Service |
54dbc3 |
} /* all guids */
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ib_api_status_t osm_lid_mgr_init(IN osm_lid_mgr_t * p_mgr, IN osm_sm_t * sm)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(sm->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_lid_mgr_construct(p_mgr);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_mgr->sm = sm;
|
|
Packit Service |
54dbc3 |
p_mgr->p_log = sm->p_log;
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn = sm->p_subn;
|
|
Packit Service |
54dbc3 |
p_mgr->p_db = sm->p_db;
|
|
Packit Service |
54dbc3 |
p_mgr->p_lock = sm->p_lock;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we initialize and restore the db domain of guid to lid map */
|
|
Packit Service |
54dbc3 |
p_mgr->p_g2l = osm_db_domain_init(p_mgr->p_db, "guid2lid");
|
|
Packit Service |
54dbc3 |
if (!p_mgr->p_g2l) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 0316: "
|
|
Packit Service |
54dbc3 |
"Error initializing Guid-to-Lid persistent database\n");
|
|
Packit Service |
54dbc3 |
status = IB_ERROR;
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
cl_qlist_init(&p_mgr->free_ranges);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we use the stored guid to lid table if not forced to reassign */
|
|
Packit Service |
54dbc3 |
if (!p_mgr->p_subn->opt.reassign_lids) {
|
|
Packit Service |
54dbc3 |
if (osm_db_restore(p_mgr->p_g2l)) {
|
|
Packit Service |
54dbc3 |
#ifndef __WIN__
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* When Windows is BSODing, it might corrupt files that
|
|
Packit Service |
54dbc3 |
* were previously opened for writing, even if the files
|
|
Packit Service |
54dbc3 |
* are closed, so we might see corrupted guid2lid file.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (p_mgr->p_subn->opt.exit_on_fatal) {
|
|
Packit Service |
54dbc3 |
osm_log_v2(p_mgr->p_log, OSM_LOG_SYS, FILE_ID,
|
|
Packit Service |
54dbc3 |
"FATAL: Error restoring Guid-to-Lid "
|
|
Packit Service |
54dbc3 |
"persistent database\n");
|
|
Packit Service |
54dbc3 |
status = IB_ERROR;
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
#endif
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"ERR 0317: Error restoring Guid-to-Lid "
|
|
Packit Service |
54dbc3 |
"persistent database\n");
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we need to make sure we did not get duplicates with
|
|
Packit Service |
54dbc3 |
current lmc */
|
|
Packit Service |
54dbc3 |
lid_mgr_validate_db(p_mgr);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
return status;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static uint16_t trim_lid(IN uint16_t lid)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
if (lid > IB_LID_UCAST_END_HO || lid < IB_LID_UCAST_START_HO)
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
return lid;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
initialize the manager for a new sweep:
|
|
Packit Service |
54dbc3 |
scans the known persistent assignment and port_lid_tbl
|
|
Packit Service |
54dbc3 |
re-calculate all empty ranges.
|
|
Packit Service |
54dbc3 |
cleanup invalid port_lid_tbl entries
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static int lid_mgr_init_sweep(IN osm_lid_mgr_t * p_mgr)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
cl_ptr_vector_t *p_discovered_vec = &p_mgr->p_subn->port_lid_tbl;
|
|
Packit Service |
54dbc3 |
uint16_t max_defined_lid, max_persistent_lid, max_discovered_lid;
|
|
Packit Service |
54dbc3 |
uint16_t disc_min_lid, disc_max_lid, db_min_lid, db_max_lid;
|
|
Packit Service |
54dbc3 |
int status = 0;
|
|
Packit Service |
54dbc3 |
cl_list_item_t *p_item;
|
|
Packit Service |
54dbc3 |
boolean_t is_free;
|
|
Packit Service |
54dbc3 |
osm_lid_mgr_range_t *p_range = NULL;
|
|
Packit Service |
54dbc3 |
osm_port_t *p_port;
|
|
Packit Service |
54dbc3 |
cl_qmap_t *p_port_guid_tbl;
|
|
Packit Service |
54dbc3 |
uint8_t lmc_num_lids = (uint8_t) (1 << p_mgr->p_subn->opt.lmc);
|
|
Packit Service |
54dbc3 |
uint16_t lmc_mask, req_lid, num_lids, lid;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
lmc_mask = ~((1 << p_mgr->p_subn->opt.lmc) - 1);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* We must discard previous guid2lid db if this is the first master
|
|
Packit Service |
54dbc3 |
* sweep and reassign_lids option is TRUE.
|
|
Packit Service |
54dbc3 |
* If we came out of standby and honor_guid2lid_file option is TRUE, we
|
|
Packit Service |
54dbc3 |
* must restore guid2lid db. Otherwise if honor_guid2lid_file option is
|
|
Packit Service |
54dbc3 |
* FALSE we must discard previous guid2lid db.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (p_mgr->p_subn->first_time_master_sweep == TRUE &&
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn->opt.reassign_lids == TRUE) {
|
|
Packit Service |
54dbc3 |
osm_db_clear(p_mgr->p_g2l);
|
|
Packit Service |
54dbc3 |
memset(p_mgr->used_lids, 0, sizeof(p_mgr->used_lids));
|
|
Packit Service |
54dbc3 |
} else if (p_mgr->p_subn->coming_out_of_standby == TRUE) {
|
|
Packit Service |
54dbc3 |
osm_db_clear(p_mgr->p_g2l);
|
|
Packit Service |
54dbc3 |
memset(p_mgr->used_lids, 0, sizeof(p_mgr->used_lids));
|
|
Packit Service |
54dbc3 |
if (p_mgr->p_subn->opt.honor_guid2lid_file == FALSE)
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Ignore guid2lid file when coming out of standby\n");
|
|
Packit Service |
54dbc3 |
else {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Honor current guid2lid file when coming out "
|
|
Packit Service |
54dbc3 |
"of standby\n");
|
|
Packit Service |
54dbc3 |
if (osm_db_restore(p_mgr->p_g2l))
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"ERR 0306: "
|
|
Packit Service |
54dbc3 |
"Error restoring Guid-to-Lid "
|
|
Packit Service |
54dbc3 |
"persistent database. Ignoring it\n");
|
|
Packit Service |
54dbc3 |
lid_mgr_validate_db(p_mgr);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we need to cleanup the empty ranges list */
|
|
Packit Service |
54dbc3 |
while ((p_item = cl_qlist_remove_head(&p_mgr->free_ranges)) !=
|
|
Packit Service |
54dbc3 |
cl_qlist_end(&p_mgr->free_ranges))
|
|
Packit Service |
54dbc3 |
free((osm_lid_mgr_range_t *) p_item);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* first clean up the port_by_lid_tbl */
|
|
Packit Service |
54dbc3 |
for (lid = 0; lid < cl_ptr_vector_get_size(p_discovered_vec); lid++)
|
|
Packit Service |
54dbc3 |
cl_ptr_vector_set(p_discovered_vec, lid, NULL);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we if are in the first sweep and in reassign lids mode
|
|
Packit Service |
54dbc3 |
we should ignore all the available info and simply define one
|
|
Packit Service |
54dbc3 |
huge empty range */
|
|
Packit Service |
54dbc3 |
if (p_mgr->p_subn->first_time_master_sweep == TRUE &&
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn->opt.reassign_lids == TRUE) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Skipping all lids as we are reassigning them\n");
|
|
Packit Service |
54dbc3 |
p_range = malloc(sizeof(osm_lid_mgr_range_t));
|
|
Packit Service |
54dbc3 |
if (p_range)
|
|
Packit Service |
54dbc3 |
p_range->min_lid = 1;
|
|
Packit Service |
54dbc3 |
goto AfterScanningLids;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* go over all discovered ports and mark their entries */
|
|
Packit Service |
54dbc3 |
p_port_guid_tbl = &p_mgr->p_subn->port_guid_tbl;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (p_port = (osm_port_t *) cl_qmap_head(p_port_guid_tbl);
|
|
Packit Service |
54dbc3 |
p_port != (osm_port_t *) cl_qmap_end(p_port_guid_tbl);
|
|
Packit Service |
54dbc3 |
p_port = (osm_port_t *) cl_qmap_next(&p_port->map_item)) {
|
|
Packit Service |
54dbc3 |
osm_port_get_lid_range_ho(p_port, &disc_min_lid, &disc_max_lid);
|
|
Packit Service |
54dbc3 |
disc_min_lid = trim_lid(disc_min_lid);
|
|
Packit Service |
54dbc3 |
disc_max_lid = trim_lid(disc_max_lid);
|
|
Packit Service |
54dbc3 |
for (lid = disc_min_lid; lid <= disc_max_lid; lid++) {
|
|
Packit Service |
54dbc3 |
if (lid < disc_min_lid + lmc_num_lids)
|
|
Packit Service |
54dbc3 |
cl_ptr_vector_set(p_discovered_vec, lid, p_port);
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
cl_ptr_vector_set(p_discovered_vec, lid, NULL);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
/* make sure the guid2lid entry is valid. If not, clean it. */
|
|
Packit Service |
54dbc3 |
if (osm_db_guid2lid_get(p_mgr->p_g2l,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_port_get_guid(p_port)),
|
|
Packit Service |
54dbc3 |
&db_min_lid, &db_max_lid))
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!p_port->p_node->sw ||
|
|
Packit Service |
54dbc3 |
osm_switch_sp0_is_lmc_capable(p_port->p_node->sw,
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn))
|
|
Packit Service |
54dbc3 |
num_lids = lmc_num_lids;
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
num_lids = 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (num_lids != 1 &&
|
|
Packit Service |
54dbc3 |
((db_min_lid & lmc_mask) != db_min_lid ||
|
|
Packit Service |
54dbc3 |
db_max_lid - db_min_lid + 1 < num_lids)) {
|
|
Packit Service |
54dbc3 |
/* Not aligned, or not wide enough, then remove the entry */
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Cleaning persistent entry for guid:"
|
|
Packit Service |
54dbc3 |
"0x%016" PRIx64 " illegal range:[0x%x:0x%x]\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_port_get_guid(p_port)),
|
|
Packit Service |
54dbc3 |
db_min_lid, db_max_lid);
|
|
Packit Service |
54dbc3 |
osm_db_guid2lid_delete(p_mgr->p_g2l,
|
|
Packit Service |
54dbc3 |
cl_ntoh64
|
|
Packit Service |
54dbc3 |
(osm_port_get_guid(p_port)));
|
|
Packit Service |
54dbc3 |
for (lid = db_min_lid; lid <= db_max_lid; lid++)
|
|
Packit Service |
54dbc3 |
p_mgr->used_lids[lid] = 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Our task is to find free lid ranges.
|
|
Packit Service |
54dbc3 |
A lid can be used if
|
|
Packit Service |
54dbc3 |
1. a persistent assignment exists
|
|
Packit Service |
54dbc3 |
2. the lid is used by a discovered port that does not have a
|
|
Packit Service |
54dbc3 |
persistent assignment.
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
scan through all lid values of both the persistent table and
|
|
Packit Service |
54dbc3 |
discovered table.
|
|
Packit Service |
54dbc3 |
If the lid has an assigned port in the discovered table:
|
|
Packit Service |
54dbc3 |
* make sure the lid matches the persistent table, or
|
|
Packit Service |
54dbc3 |
* there is no other persistent assignment for that lid.
|
|
Packit Service |
54dbc3 |
* else cleanup the port_by_lid_tbl, mark this as empty range.
|
|
Packit Service |
54dbc3 |
Else if the lid does not have an entry in the persistent table
|
|
Packit Service |
54dbc3 |
mark it as free.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* find the range of lids to scan */
|
|
Packit Service |
54dbc3 |
max_discovered_lid =
|
|
Packit Service |
54dbc3 |
(uint16_t) cl_ptr_vector_get_size(p_discovered_vec);
|
|
Packit Service |
54dbc3 |
max_persistent_lid = sizeof(p_mgr->used_lids) - 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* but the vectors have one extra entry for lid=0 */
|
|
Packit Service |
54dbc3 |
if (max_discovered_lid)
|
|
Packit Service |
54dbc3 |
max_discovered_lid--;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (max_persistent_lid > max_discovered_lid)
|
|
Packit Service |
54dbc3 |
max_defined_lid = max_persistent_lid;
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
max_defined_lid = max_discovered_lid;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (lid = 1; lid <= max_defined_lid; lid++) {
|
|
Packit Service |
54dbc3 |
is_free = TRUE;
|
|
Packit Service |
54dbc3 |
/* first check to see if the lid is used by a persistent assignment */
|
|
Packit Service |
54dbc3 |
if (lid <= max_persistent_lid && p_mgr->used_lids[lid]) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"0x%04x is not free as its mapped by the "
|
|
Packit Service |
54dbc3 |
"persistent db\n", lid);
|
|
Packit Service |
54dbc3 |
is_free = FALSE;
|
|
Packit Service |
54dbc3 |
/* check this is a discovered port */
|
|
Packit Service |
54dbc3 |
} else if (lid <= max_discovered_lid &&
|
|
Packit Service |
54dbc3 |
(p_port = cl_ptr_vector_get(p_discovered_vec,
|
|
Packit Service |
54dbc3 |
lid))) {
|
|
Packit Service |
54dbc3 |
/* we have a port. Now lets see if we can preserve its lid range. */
|
|
Packit Service |
54dbc3 |
/* For that, we need to make sure:
|
|
Packit Service |
54dbc3 |
1. The port has a (legal) persistency entry. Then the
|
|
Packit Service |
54dbc3 |
local lid is free (we will use the persistency value).
|
|
Packit Service |
54dbc3 |
2. Can the port keep its local assignment?
|
|
Packit Service |
54dbc3 |
a. Make sure the lid is aligned.
|
|
Packit Service |
54dbc3 |
b. Make sure all needed lids (for the lmc) are free
|
|
Packit Service |
54dbc3 |
according to persistency table.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
/* qualify the guid of the port is not persistently
|
|
Packit Service |
54dbc3 |
mapped to another range */
|
|
Packit Service |
54dbc3 |
if (!osm_db_guid2lid_get(p_mgr->p_g2l,
|
|
Packit Service |
54dbc3 |
cl_ntoh64
|
|
Packit Service |
54dbc3 |
(osm_port_get_guid(p_port)),
|
|
Packit Service |
54dbc3 |
&db_min_lid, &db_max_lid)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"0x%04x is free as it was "
|
|
Packit Service |
54dbc3 |
"discovered but mapped by the "
|
|
Packit Service |
54dbc3 |
"persistent db to [0x%04x:0x%04x]\n",
|
|
Packit Service |
54dbc3 |
lid, db_min_lid, db_max_lid);
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
/* can the port keep its assignment ? */
|
|
Packit Service |
54dbc3 |
/* get the lid range of that port, and the
|
|
Packit Service |
54dbc3 |
required number of lids we are about to
|
|
Packit Service |
54dbc3 |
assign to it */
|
|
Packit Service |
54dbc3 |
osm_port_get_lid_range_ho(p_port,
|
|
Packit Service |
54dbc3 |
&disc_min_lid,
|
|
Packit Service |
54dbc3 |
&disc_max_lid);
|
|
Packit Service |
54dbc3 |
if (!p_port->p_node->sw ||
|
|
Packit Service |
54dbc3 |
osm_switch_sp0_is_lmc_capable
|
|
Packit Service |
54dbc3 |
(p_port->p_node->sw, p_mgr->p_subn)) {
|
|
Packit Service |
54dbc3 |
disc_max_lid =
|
|
Packit Service |
54dbc3 |
disc_min_lid + lmc_num_lids - 1;
|
|
Packit Service |
54dbc3 |
num_lids = lmc_num_lids;
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
num_lids = 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Make sure the lid is aligned */
|
|
Packit Service |
54dbc3 |
if (num_lids != 1
|
|
Packit Service |
54dbc3 |
&& (disc_min_lid & lmc_mask) !=
|
|
Packit Service |
54dbc3 |
disc_min_lid) {
|
|
Packit Service |
54dbc3 |
/* The lid cannot be used */
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"0x%04x is free as it was "
|
|
Packit Service |
54dbc3 |
"discovered but not aligned\n",
|
|
Packit Service |
54dbc3 |
lid);
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
/* check that all needed lids are not persistently mapped */
|
|
Packit Service |
54dbc3 |
is_free = FALSE;
|
|
Packit Service |
54dbc3 |
for (req_lid = disc_min_lid + 1;
|
|
Packit Service |
54dbc3 |
req_lid <= disc_max_lid;
|
|
Packit Service |
54dbc3 |
req_lid++) {
|
|
Packit Service |
54dbc3 |
if (req_lid <=
|
|
Packit Service |
54dbc3 |
max_persistent_lid &&
|
|
Packit Service |
54dbc3 |
p_mgr->used_lids[req_lid]) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log,
|
|
Packit Service |
54dbc3 |
OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"0x%04x is free as it was discovered "
|
|
Packit Service |
54dbc3 |
"but mapped\n",
|
|
Packit Service |
54dbc3 |
lid);
|
|
Packit Service |
54dbc3 |
is_free = TRUE;
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (is_free == FALSE) {
|
|
Packit Service |
54dbc3 |
/* This port will use its local lid, and consume the entire required lid range.
|
|
Packit Service |
54dbc3 |
Thus we can skip that range. */
|
|
Packit Service |
54dbc3 |
/* If the disc_max_lid is greater then lid, we can skip right to it,
|
|
Packit Service |
54dbc3 |
since we've done all neccessary checks on the lids in between. */
|
|
Packit Service |
54dbc3 |
if (disc_max_lid > lid)
|
|
Packit Service |
54dbc3 |
lid = disc_max_lid;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (is_free) {
|
|
Packit Service |
54dbc3 |
if (p_range)
|
|
Packit Service |
54dbc3 |
p_range->max_lid = lid;
|
|
Packit Service |
54dbc3 |
else {
|
|
Packit Service |
54dbc3 |
p_range = malloc(sizeof(osm_lid_mgr_range_t));
|
|
Packit Service |
54dbc3 |
if (p_range) {
|
|
Packit Service |
54dbc3 |
p_range->min_lid = lid;
|
|
Packit Service |
54dbc3 |
p_range->max_lid = lid;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
/* this lid is used so we need to finalize the previous free range */
|
|
Packit Service |
54dbc3 |
} else if (p_range) {
|
|
Packit Service |
54dbc3 |
cl_qlist_insert_tail(&p_mgr->free_ranges,
|
|
Packit Service |
54dbc3 |
&p_range->item);
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"new free lid range [%u:%u]\n",
|
|
Packit Service |
54dbc3 |
p_range->min_lid, p_range->max_lid);
|
|
Packit Service |
54dbc3 |
p_range = NULL;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
AfterScanningLids:
|
|
Packit Service |
54dbc3 |
/* after scanning all known lids we need to extend the last range
|
|
Packit Service |
54dbc3 |
to the max allowed lid */
|
|
Packit Service |
54dbc3 |
if (!p_range) {
|
|
Packit Service |
54dbc3 |
p_range = malloc(sizeof(osm_lid_mgr_range_t));
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
The p_range can be NULL in one of 2 cases:
|
|
Packit Service |
54dbc3 |
1. If max_defined_lid == 0. In this case, we want the
|
|
Packit Service |
54dbc3 |
entire range.
|
|
Packit Service |
54dbc3 |
2. If all lids discovered in the loop where mapped. In this
|
|
Packit Service |
54dbc3 |
case, no free range exists and we want to define it after the
|
|
Packit Service |
54dbc3 |
last mapped lid.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (p_range)
|
|
Packit Service |
54dbc3 |
p_range->min_lid = lid;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
if (p_range) {
|
|
Packit Service |
54dbc3 |
p_range->max_lid = p_mgr->p_subn->max_ucast_lid_ho;
|
|
Packit Service |
54dbc3 |
cl_qlist_insert_tail(&p_mgr->free_ranges, &p_range->item);
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"final free lid range [%u:%u]\n",
|
|
Packit Service |
54dbc3 |
p_range->min_lid, p_range->max_lid);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
return status;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
check if the given range of lids is free
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static boolean_t lid_mgr_is_range_not_persistent(IN osm_lid_mgr_t * p_mgr,
|
|
Packit Service |
54dbc3 |
IN uint16_t lid,
|
|
Packit Service |
54dbc3 |
IN uint16_t num_lids)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
uint16_t i;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = lid; i < lid + num_lids; i++)
|
|
Packit Service |
54dbc3 |
if (p_mgr->used_lids[i])
|
|
Packit Service |
54dbc3 |
return FALSE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return TRUE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
find a free lid range
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static void lid_mgr_find_free_lid_range(IN osm_lid_mgr_t * p_mgr,
|
|
Packit Service |
54dbc3 |
IN uint8_t num_lids,
|
|
Packit Service |
54dbc3 |
OUT uint16_t * p_min_lid,
|
|
Packit Service |
54dbc3 |
OUT uint16_t * p_max_lid)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
uint16_t lid;
|
|
Packit Service |
54dbc3 |
cl_list_item_t *p_item;
|
|
Packit Service |
54dbc3 |
cl_list_item_t *p_next_item;
|
|
Packit Service |
54dbc3 |
osm_lid_mgr_range_t *p_range = NULL;
|
|
Packit Service |
54dbc3 |
uint8_t lmc_num_lids;
|
|
Packit Service |
54dbc3 |
uint16_t lmc_mask;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "LMC = %u, number LIDs = %u\n",
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn->opt.lmc, num_lids);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
lmc_num_lids = (1 << p_mgr->p_subn->opt.lmc);
|
|
Packit Service |
54dbc3 |
lmc_mask = ~((1 << p_mgr->p_subn->opt.lmc) - 1);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Search the list of free lid ranges for a range which is big enough
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_item = cl_qlist_head(&p_mgr->free_ranges);
|
|
Packit Service |
54dbc3 |
while (p_item != cl_qlist_end(&p_mgr->free_ranges)) {
|
|
Packit Service |
54dbc3 |
p_next_item = cl_qlist_next(p_item);
|
|
Packit Service |
54dbc3 |
p_range = (osm_lid_mgr_range_t *) p_item;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
lid = p_range->min_lid;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* if we require more then one lid we must align to LMC */
|
|
Packit Service |
54dbc3 |
if (num_lids > 1) {
|
|
Packit Service |
54dbc3 |
if ((lid & lmc_mask) != lid)
|
|
Packit Service |
54dbc3 |
lid = (lid + lmc_num_lids) & lmc_mask;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* but we can be out of the range */
|
|
Packit Service |
54dbc3 |
if (lid + num_lids - 1 <= p_range->max_lid) {
|
|
Packit Service |
54dbc3 |
/* ok let us use that range */
|
|
Packit Service |
54dbc3 |
if (lid + num_lids - 1 == p_range->max_lid) {
|
|
Packit Service |
54dbc3 |
/* we consumed the entire range */
|
|
Packit Service |
54dbc3 |
cl_qlist_remove_item(&p_mgr->free_ranges,
|
|
Packit Service |
54dbc3 |
p_item);
|
|
Packit Service |
54dbc3 |
free(p_item);
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
/* only update the available range */
|
|
Packit Service |
54dbc3 |
p_range->min_lid = lid + num_lids;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
*p_min_lid = lid;
|
|
Packit Service |
54dbc3 |
*p_max_lid = (uint16_t) (lid + num_lids - 1);
|
|
Packit Service |
54dbc3 |
return;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
p_item = p_next_item;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Couldn't find a free range of lids.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
*p_min_lid = *p_max_lid = 0;
|
|
Packit Service |
54dbc3 |
/* if we run out of lids, give an error and abort! */
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 0307: "
|
|
Packit Service |
54dbc3 |
"OPENSM RAN OUT OF LIDS!!!\n");
|
|
Packit Service |
54dbc3 |
CL_ASSERT(0);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void lid_mgr_cleanup_discovered_port_lid_range(IN osm_lid_mgr_t * p_mgr,
|
|
Packit Service |
54dbc3 |
IN osm_port_t * p_port)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
cl_ptr_vector_t *p_discovered_vec = &p_mgr->p_subn->port_lid_tbl;
|
|
Packit Service |
54dbc3 |
uint16_t lid, min_lid, max_lid;
|
|
Packit Service |
54dbc3 |
uint16_t max_tbl_lid =
|
|
Packit Service |
54dbc3 |
(uint16_t) (cl_ptr_vector_get_size(p_discovered_vec));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_port_get_lid_range_ho(p_port, &min_lid, &max_lid);
|
|
Packit Service |
54dbc3 |
min_lid = trim_lid(min_lid);
|
|
Packit Service |
54dbc3 |
max_lid = trim_lid(max_lid);
|
|
Packit Service |
54dbc3 |
for (lid = min_lid; lid <= max_lid; lid++)
|
|
Packit Service |
54dbc3 |
if (lid < max_tbl_lid &&
|
|
Packit Service |
54dbc3 |
p_port == cl_ptr_vector_get(p_discovered_vec, lid))
|
|
Packit Service |
54dbc3 |
cl_ptr_vector_set(p_discovered_vec, lid, NULL);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
0.1 if the port info lid matches the guid2lid return 0
|
|
Packit Service |
54dbc3 |
0.2 if the port info has a lid and that range is empty in
|
|
Packit Service |
54dbc3 |
port_lid_tbl, return 0 and update the port_lid_tbl and
|
|
Packit Service |
54dbc3 |
guid2lid
|
|
Packit Service |
54dbc3 |
0.3 else find an empty space in port_lid_tbl, update the
|
|
Packit Service |
54dbc3 |
port_lid_tbl and guid2lid, return 1 to flag a change required.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static int lid_mgr_get_port_lid(IN osm_lid_mgr_t * p_mgr,
|
|
Packit Service |
54dbc3 |
IN osm_port_t * p_port,
|
|
Packit Service |
54dbc3 |
OUT uint16_t * p_min_lid,
|
|
Packit Service |
54dbc3 |
OUT uint16_t * p_max_lid)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
uint16_t lid, min_lid, max_lid;
|
|
Packit Service |
54dbc3 |
uint64_t guid;
|
|
Packit Service |
54dbc3 |
uint8_t num_lids = (1 << p_mgr->p_subn->opt.lmc);
|
|
Packit Service |
54dbc3 |
int lid_changed = 0;
|
|
Packit Service |
54dbc3 |
uint16_t lmc_mask;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* get the lid from the guid2lid */
|
|
Packit Service |
54dbc3 |
guid = cl_ntoh64(osm_port_get_guid(p_port));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* if the port is a base switch port 0 then we only need one lid */
|
|
Packit Service |
54dbc3 |
if (p_port->p_node->sw &&
|
|
Packit Service |
54dbc3 |
!osm_switch_sp0_is_lmc_capable(p_port->p_node->sw, p_mgr->p_subn))
|
|
Packit Service |
54dbc3 |
num_lids = 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_mgr->p_subn->first_time_master_sweep == TRUE &&
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn->opt.reassign_lids == TRUE)
|
|
Packit Service |
54dbc3 |
goto AssignLid;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
lmc_mask = ~(num_lids - 1);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* if the port matches the guid2lid */
|
|
Packit Service |
54dbc3 |
if (!osm_db_guid2lid_get(p_mgr->p_g2l, guid, &min_lid, &max_lid)) {
|
|
Packit Service |
54dbc3 |
*p_min_lid = min_lid;
|
|
Packit Service |
54dbc3 |
*p_max_lid = min_lid + num_lids - 1;
|
|
Packit Service |
54dbc3 |
if (min_lid == cl_ntoh16(osm_port_get_base_lid(p_port)))
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "0x%016" PRIx64
|
|
Packit Service |
54dbc3 |
" matches its known lid:%u\n", guid, min_lid);
|
|
Packit Service |
54dbc3 |
else {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"0x%016" PRIx64 " with lid:%u "
|
|
Packit Service |
54dbc3 |
"does not match its known lid:%u\n",
|
|
Packit Service |
54dbc3 |
guid, cl_ntoh16(osm_port_get_base_lid(p_port)),
|
|
Packit Service |
54dbc3 |
min_lid);
|
|
Packit Service |
54dbc3 |
lid_mgr_cleanup_discovered_port_lid_range(p_mgr,
|
|
Packit Service |
54dbc3 |
p_port);
|
|
Packit Service |
54dbc3 |
/* we still need to send the setting to the target port */
|
|
Packit Service |
54dbc3 |
lid_changed = 1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
goto NewLidSet;
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"0x%016" PRIx64 " has no persistent lid assigned\n",
|
|
Packit Service |
54dbc3 |
guid);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* if the port info carries a lid it must be lmc aligned and not mapped
|
|
Packit Service |
54dbc3 |
by the persistent storage */
|
|
Packit Service |
54dbc3 |
min_lid = cl_ntoh16(osm_port_get_base_lid(p_port));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we want to ignore the discovered lid if we are also on first sweep of
|
|
Packit Service |
54dbc3 |
reassign lids flow */
|
|
Packit Service |
54dbc3 |
if (min_lid) {
|
|
Packit Service |
54dbc3 |
/* make sure lid is valid */
|
|
Packit Service |
54dbc3 |
if ((min_lid & lmc_mask) == min_lid) {
|
|
Packit Service |
54dbc3 |
/* is it free */
|
|
Packit Service |
54dbc3 |
if (lid_mgr_is_range_not_persistent
|
|
Packit Service |
54dbc3 |
(p_mgr, min_lid, num_lids)) {
|
|
Packit Service |
54dbc3 |
*p_min_lid = min_lid;
|
|
Packit Service |
54dbc3 |
*p_max_lid = min_lid + num_lids - 1;
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"0x%016" PRIx64
|
|
Packit Service |
54dbc3 |
" lid range:[%u-%u] is free\n",
|
|
Packit Service |
54dbc3 |
guid, *p_min_lid, *p_max_lid);
|
|
Packit Service |
54dbc3 |
goto NewLidSet;
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"0x%016" PRIx64 " existing lid "
|
|
Packit Service |
54dbc3 |
"range:[%u:%u] is not free\n",
|
|
Packit Service |
54dbc3 |
guid, min_lid, min_lid + num_lids - 1);
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"0x%016" PRIx64 " existing lid range:"
|
|
Packit Service |
54dbc3 |
"[%u:%u] is not lmc aligned\n",
|
|
Packit Service |
54dbc3 |
guid, min_lid, min_lid + num_lids - 1);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
AssignLid:
|
|
Packit Service |
54dbc3 |
/* first cleanup the existing discovered lid range */
|
|
Packit Service |
54dbc3 |
lid_mgr_cleanup_discovered_port_lid_range(p_mgr, p_port);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* find an empty space */
|
|
Packit Service |
54dbc3 |
lid_mgr_find_free_lid_range(p_mgr, num_lids, p_min_lid, p_max_lid);
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"0x%016" PRIx64 " assigned a new lid range:[%u-%u]\n",
|
|
Packit Service |
54dbc3 |
guid, *p_min_lid, *p_max_lid);
|
|
Packit Service |
54dbc3 |
lid_changed = 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
NewLidSet:
|
|
Packit Service |
54dbc3 |
/* update the guid2lid db and used_lids */
|
|
Packit Service |
54dbc3 |
osm_db_guid2lid_set(p_mgr->p_g2l, guid, *p_min_lid, *p_max_lid);
|
|
Packit Service |
54dbc3 |
for (lid = *p_min_lid; lid <= *p_max_lid; lid++)
|
|
Packit Service |
54dbc3 |
p_mgr->used_lids[lid] = 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* make sure the assigned lids are marked in port_lid_tbl */
|
|
Packit Service |
54dbc3 |
for (lid = *p_min_lid; lid <= *p_max_lid; lid++)
|
|
Packit Service |
54dbc3 |
cl_ptr_vector_set(&p_mgr->p_subn->port_lid_tbl, lid, p_port);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
return lid_changed;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
Set to INIT the remote port of the given physical port
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static void lid_mgr_set_remote_pi_state_to_init(IN osm_lid_mgr_t * p_mgr,
|
|
Packit Service |
54dbc3 |
IN osm_physp_t * p_physp)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_physp_t *p_rem_physp = osm_physp_get_remote(p_physp);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_rem_physp == NULL)
|
|
Packit Service |
54dbc3 |
return;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* but in some rare cases the remote side might be non responsive */
|
|
Packit Service |
54dbc3 |
ib_port_info_set_port_state(&p_rem_physp->port_info, IB_LINK_INIT);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static int lid_mgr_set_physp_pi(IN osm_lid_mgr_t * p_mgr,
|
|
Packit Service |
54dbc3 |
IN osm_port_t * p_port,
|
|
Packit Service |
54dbc3 |
IN osm_physp_t * p_physp, IN ib_net16_t lid)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
uint8_t payload[IB_SMP_DATA_SIZE];
|
|
Packit Service |
54dbc3 |
ib_port_info_t *p_pi = (ib_port_info_t *) payload;
|
|
Packit Service |
54dbc3 |
const ib_port_info_t *p_old_pi;
|
|
Packit Service |
54dbc3 |
osm_madw_context_t context;
|
|
Packit Service |
54dbc3 |
osm_node_t *p_node;
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
uint8_t mtu;
|
|
Packit Service |
54dbc3 |
uint8_t op_vls;
|
|
Packit Service |
54dbc3 |
uint8_t port_num;
|
|
Packit Service |
54dbc3 |
boolean_t send_set = FALSE;
|
|
Packit Service |
54dbc3 |
boolean_t send_client_rereg = FALSE;
|
|
Packit Service |
54dbc3 |
boolean_t update_mkey = FALSE;
|
|
Packit Service |
54dbc3 |
int ret = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Don't bother doing anything if this Physical Port is not valid.
|
|
Packit Service |
54dbc3 |
This allows simplified code in the caller.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (!p_physp)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
port_num = osm_physp_get_port_num(p_physp);
|
|
Packit Service |
54dbc3 |
p_node = osm_physp_get_node_ptr(p_physp);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH && port_num != 0) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Switch ports that are not numbered 0 should not be set
|
|
Packit Service |
54dbc3 |
with the following attributes as they are set later
|
|
Packit Service |
54dbc3 |
(during NO_CHANGE state in link mgr).
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Skipping switch port %u, GUID 0x%016" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
port_num, cl_ntoh64(osm_physp_get_port_guid(p_physp)));
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_old_pi = &p_physp->port_info;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
First, copy existing parameters from the PortInfo attribute we
|
|
Packit Service |
54dbc3 |
already have for this node.
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Second, update with default values that we know must be set for
|
|
Packit Service |
54dbc3 |
every Physical Port and the LID and set the neighbor MTU field
|
|
Packit Service |
54dbc3 |
appropriately.
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Third, send the SMP to this physical port.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memcpy(payload, p_old_pi, sizeof(ib_port_info_t));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Should never write back a value that is bigger then 3 in
|
|
Packit Service |
54dbc3 |
the PortPhysicalState field, so cannot simply copy!
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Actually we want to write there:
|
|
Packit Service |
54dbc3 |
port physical state - no change
|
|
Packit Service |
54dbc3 |
link down default state = polling
|
|
Packit Service |
54dbc3 |
port state - no change
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_pi->state_info2 = 0x02;
|
|
Packit Service |
54dbc3 |
ib_port_info_set_port_state(p_pi, IB_LINK_NO_CHANGE);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (ib_port_info_get_link_down_def_state(p_pi) !=
|
|
Packit Service |
54dbc3 |
ib_port_info_get_link_down_def_state(p_old_pi))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* didn't get PortInfo before */
|
|
Packit Service |
54dbc3 |
if (!ib_port_info_get_port_state(p_old_pi))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_pi->m_key = p_mgr->p_subn->opt.m_key;
|
|
Packit Service |
54dbc3 |
if (memcmp(&p_pi->m_key, &p_old_pi->m_key, sizeof(p_pi->m_key))) {
|
|
Packit Service |
54dbc3 |
update_mkey = TRUE;
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_pi->subnet_prefix = p_mgr->p_subn->opt.subnet_prefix;
|
|
Packit Service |
54dbc3 |
if (memcmp(&p_pi->subnet_prefix, &p_old_pi->subnet_prefix,
|
|
Packit Service |
54dbc3 |
sizeof(p_pi->subnet_prefix)))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_port->lid = lid;
|
|
Packit Service |
54dbc3 |
p_pi->base_lid = lid;
|
|
Packit Service |
54dbc3 |
if (memcmp(&p_pi->base_lid, &p_old_pi->base_lid,
|
|
Packit Service |
54dbc3 |
sizeof(p_pi->base_lid))) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Reset stored base_lid.
|
|
Packit Service |
54dbc3 |
* On successful send, we'll update it when we'll get a reply.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
osm_physp_set_base_lid(p_physp, 0);
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
p_mgr->dirty = TRUE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
We are updating the ports with our local sm_base_lid
|
|
Packit Service |
54dbc3 |
if for some reason currently received SM LID is different from our SM LID,
|
|
Packit Service |
54dbc3 |
need to send client reregister to this port
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_pi->master_sm_base_lid = p_mgr->p_subn->sm_base_lid;
|
|
Packit Service |
54dbc3 |
if (memcmp(&p_pi->master_sm_base_lid, &p_old_pi->master_sm_base_lid,
|
|
Packit Service |
54dbc3 |
sizeof(p_pi->master_sm_base_lid))) {
|
|
Packit Service |
54dbc3 |
send_client_rereg = TRUE;
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_pi->m_key_lease_period = p_mgr->p_subn->opt.m_key_lease_period;
|
|
Packit Service |
54dbc3 |
if (memcmp(&p_pi->m_key_lease_period, &p_old_pi->m_key_lease_period,
|
|
Packit Service |
54dbc3 |
sizeof(p_pi->m_key_lease_period)))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_pi->mkey_lmc = 0;
|
|
Packit Service |
54dbc3 |
ib_port_info_set_mpb(p_pi, p_mgr->p_subn->opt.m_key_protect_bits);
|
|
Packit Service |
54dbc3 |
if (ib_port_info_get_mpb(p_pi) != ib_port_info_get_mpb(p_old_pi))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
we want to set the timeout for both the switch port 0
|
|
Packit Service |
54dbc3 |
and the CA ports
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
ib_port_info_set_timeout(p_pi, p_mgr->p_subn->opt.subnet_timeout);
|
|
Packit Service |
54dbc3 |
if (ib_port_info_get_timeout(p_pi) !=
|
|
Packit Service |
54dbc3 |
ib_port_info_get_timeout(p_old_pi))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (port_num != 0) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
CAs don't have a port 0, and for switch port 0,
|
|
Packit Service |
54dbc3 |
the state bits are ignored.
|
|
Packit Service |
54dbc3 |
This is not the switch management port
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* p_pi->mkey_lmc is initialized earlier */
|
|
Packit Service |
54dbc3 |
ib_port_info_set_lmc(p_pi, p_mgr->p_subn->opt.lmc);
|
|
Packit Service |
54dbc3 |
if (ib_port_info_get_lmc(p_pi) !=
|
|
Packit Service |
54dbc3 |
ib_port_info_get_lmc(p_old_pi))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* calc new op_vls and mtu */
|
|
Packit Service |
54dbc3 |
op_vls = osm_physp_calc_link_op_vls(p_mgr->p_log, p_mgr->p_subn,
|
|
Packit Service |
54dbc3 |
p_physp,
|
|
Packit Service |
54dbc3 |
ib_port_info_get_op_vls(p_old_pi));
|
|
Packit Service |
54dbc3 |
mtu = osm_physp_calc_link_mtu(p_mgr->p_log, p_physp,
|
|
Packit Service |
54dbc3 |
ib_port_info_get_neighbor_mtu(p_old_pi));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ib_port_info_set_neighbor_mtu(p_pi, mtu);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (ib_port_info_get_neighbor_mtu(p_pi) !=
|
|
Packit Service |
54dbc3 |
ib_port_info_get_neighbor_mtu(p_old_pi))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ib_port_info_set_op_vls(p_pi, op_vls);
|
|
Packit Service |
54dbc3 |
if (ib_port_info_get_op_vls(p_pi) !=
|
|
Packit Service |
54dbc3 |
ib_port_info_get_op_vls(p_old_pi))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Several timeout mechanisms:
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
ib_port_info_set_phy_and_overrun_err_thd(p_pi,
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn->opt.
|
|
Packit Service |
54dbc3 |
local_phy_errors_threshold,
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn->opt.
|
|
Packit Service |
54dbc3 |
overrun_errors_threshold);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_pi->error_threshold != p_old_pi->error_threshold)
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
To reset the port state machine we can send
|
|
Packit Service |
54dbc3 |
PortInfo.State = DOWN. (see: 7.2.7 p171 lines:10-19)
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (mtu != ib_port_info_get_neighbor_mtu(p_old_pi) ||
|
|
Packit Service |
54dbc3 |
op_vls != ib_port_info_get_op_vls(p_old_pi)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Sending Link Down to GUID 0x%016"
|
|
Packit Service |
54dbc3 |
PRIx64 " port %d due to op_vls or "
|
|
Packit Service |
54dbc3 |
"mtu change. MTU:%u,%u VL_CAP:%u,%u\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_physp_get_port_guid(p_physp)),
|
|
Packit Service |
54dbc3 |
port_num, mtu,
|
|
Packit Service |
54dbc3 |
ib_port_info_get_neighbor_mtu(p_old_pi),
|
|
Packit Service |
54dbc3 |
op_vls, ib_port_info_get_op_vls(p_old_pi));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
we need to make sure the internal DB will follow the
|
|
Packit Service |
54dbc3 |
fact that the remote port is also going through
|
|
Packit Service |
54dbc3 |
"down" state into "init"...
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
lid_mgr_set_remote_pi_state_to_init(p_mgr, p_physp);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ib_port_info_set_port_state(p_pi, IB_LINK_DOWN);
|
|
Packit Service |
54dbc3 |
if (ib_port_info_get_port_state(p_pi) !=
|
|
Packit Service |
54dbc3 |
ib_port_info_get_port_state(p_old_pi))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} else if (ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info)) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Configure Enh. SP0:
|
|
Packit Service |
54dbc3 |
* Set MTU according to the mtu_cap.
|
|
Packit Service |
54dbc3 |
* Set LMC if lmc_esp0 is defined.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
ib_port_info_set_neighbor_mtu(p_pi,
|
|
Packit Service |
54dbc3 |
ib_port_info_get_mtu_cap
|
|
Packit Service |
54dbc3 |
(p_old_pi));
|
|
Packit Service |
54dbc3 |
if (ib_port_info_get_neighbor_mtu(p_pi) !=
|
|
Packit Service |
54dbc3 |
ib_port_info_get_neighbor_mtu(p_old_pi))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Updating neighbor_mtu on switch GUID 0x%016" PRIx64
|
|
Packit Service |
54dbc3 |
" port 0 to:%u\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_physp_get_port_guid(p_physp)),
|
|
Packit Service |
54dbc3 |
ib_port_info_get_neighbor_mtu(p_pi));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Configure LMC on enhanced SP0 */
|
|
Packit Service |
54dbc3 |
if (p_mgr->p_subn->opt.lmc_esp0) {
|
|
Packit Service |
54dbc3 |
/* p_pi->mkey_lmc is initialized earlier */
|
|
Packit Service |
54dbc3 |
ib_port_info_set_lmc(p_pi, p_mgr->p_subn->opt.lmc);
|
|
Packit Service |
54dbc3 |
if (ib_port_info_get_lmc(p_pi) !=
|
|
Packit Service |
54dbc3 |
ib_port_info_get_lmc(p_old_pi))
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
context.pi_context.node_guid = osm_node_get_node_guid(p_node);
|
|
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 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
For ports supporting the ClientReregistration Vol1 (v1.2) p811 14.4.11:
|
|
Packit Service |
54dbc3 |
need to set the cli_rereg bit when current SM LID at the Host
|
|
Packit Service |
54dbc3 |
is different from our SM LID,
|
|
Packit Service |
54dbc3 |
also if we are in first_time_master_sweep,
|
|
Packit Service |
54dbc3 |
also if this port was just now discovered, then we should also set
|
|
Packit Service |
54dbc3 |
the cli_rereg bit (we know that the port was just discovered
|
|
Packit Service |
54dbc3 |
if its is_new field is set).
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if ((send_client_rereg ||
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn->first_time_master_sweep == TRUE || p_port->is_new)
|
|
Packit Service |
54dbc3 |
&& !p_mgr->p_subn->opt.no_clients_rereg
|
|
Packit Service |
54dbc3 |
&& (p_old_pi->capability_mask & IB_PORT_CAP_HAS_CLIENT_REREG)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Setting client rereg on %s, port %d\n",
|
|
Packit Service |
54dbc3 |
p_port->p_node->print_desc, p_port->p_physp->port_num);
|
|
Packit Service |
54dbc3 |
ib_port_info_set_client_rereg(p_pi, 1);
|
|
Packit Service |
54dbc3 |
context.pi_context.client_rereg = TRUE;
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
ib_port_info_set_client_rereg(p_pi, 0);
|
|
Packit Service |
54dbc3 |
context.pi_context.client_rereg = FALSE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* We need to send the PortInfo Set request with the new sm_lid
|
|
Packit Service |
54dbc3 |
in the following cases:
|
|
Packit Service |
54dbc3 |
1. There is a change in the values (send_set == TRUE)
|
|
Packit Service |
54dbc3 |
2. first_time_master_sweep flag on the subnet is TRUE. This means the
|
|
Packit Service |
54dbc3 |
SM just became master, and it then needs to send a PortInfo Set to
|
|
Packit Service |
54dbc3 |
every port.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (p_mgr->p_subn->first_time_master_sweep == TRUE)
|
|
Packit Service |
54dbc3 |
send_set = TRUE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!send_set)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = osm_req_set(p_mgr->sm, osm_physp_get_dr_path_ptr(p_physp),
|
|
Packit Service |
54dbc3 |
payload, sizeof(payload), IB_MAD_ATTR_PORT_INFO,
|
|
Packit Service |
54dbc3 |
cl_hton32(osm_physp_get_port_num(p_physp)),
|
|
Packit Service |
54dbc3 |
FALSE, ib_port_info_get_m_key(&p_physp->port_info),
|
|
Packit Service |
54dbc3 |
0, CL_DISP_MSGID_NONE, &context);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
/* If we sent a new mkey above, update our guid2mkey map
|
|
Packit Service |
54dbc3 |
now, on the assumption that the SubnSet succeeds
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (update_mkey)
|
|
Packit Service |
54dbc3 |
osm_db_guid2mkey_set(p_mgr->p_subn->p_g2m,
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_physp->port_guid),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(p_pi->m_key));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
Processes our own node
|
|
Packit Service |
54dbc3 |
Lock must already be held.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
static int lid_mgr_process_our_sm_node(IN osm_lid_mgr_t * p_mgr)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_port_t *p_port;
|
|
Packit Service |
54dbc3 |
uint16_t min_lid_ho;
|
|
Packit Service |
54dbc3 |
uint16_t max_lid_ho;
|
|
Packit Service |
54dbc3 |
int ret;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Acquire our own port object.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_port = osm_get_port_by_guid(p_mgr->p_subn,
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn->sm_port_guid);
|
|
Packit Service |
54dbc3 |
if (!p_port) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 0308: "
|
|
Packit Service |
54dbc3 |
"Can't acquire SM's port object, GUID 0x%016" PRIx64
|
|
Packit Service |
54dbc3 |
"\n", cl_ntoh64(p_mgr->p_subn->sm_port_guid));
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Determine the LID this SM will use for its own port.
|
|
Packit Service |
54dbc3 |
Be careful. With an LMC > 0, the bottom of the LID range becomes
|
|
Packit Service |
54dbc3 |
unusable, since port hardware will mask off least significant bits,
|
|
Packit Service |
54dbc3 |
leaving a LID of 0 (invalid). Therefore, make sure that we always
|
|
Packit Service |
54dbc3 |
configure the SM with a LID that has non-zero bits, even after
|
|
Packit Service |
54dbc3 |
LMC masking by hardware.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
lid_mgr_get_port_lid(p_mgr, p_port, &min_lid_ho, &max_lid_ho);
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Current base LID is %u\n", min_lid_ho);
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Update subnet object.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn->master_sm_base_lid = cl_hton16(min_lid_ho);
|
|
Packit Service |
54dbc3 |
p_mgr->p_subn->sm_base_lid = cl_hton16(min_lid_ho);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_VERBOSE,
|
|
Packit Service |
54dbc3 |
"Assigning SM's port 0x%016" PRIx64
|
|
Packit Service |
54dbc3 |
"\n\t\t\t\tto LID range [%u,%u]\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(osm_port_get_guid(p_port)), min_lid_ho, max_lid_ho);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Set the PortInfo the Physical Port associated with this Port.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
ret = lid_mgr_set_physp_pi(p_mgr, p_port, p_port->p_physp,
|
|
Packit Service |
54dbc3 |
cl_hton16(min_lid_ho));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
int osm_lid_mgr_process_sm(IN osm_lid_mgr_t * p_mgr)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
int ret;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_mgr->p_subn->sm_port_guid);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_PLOCK_EXCL_ACQUIRE(p_mgr->p_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* initialize the port_lid_tbl and empty ranges list following the
|
|
Packit Service |
54dbc3 |
persistent db */
|
|
Packit Service |
54dbc3 |
lid_mgr_init_sweep(p_mgr);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ret = lid_mgr_process_our_sm_node(p_mgr);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_PLOCK_RELEASE(p_mgr->p_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
1 go through all ports in the subnet.
|
|
Packit Service |
54dbc3 |
1.1 call lid_mgr_get_port_lid
|
|
Packit Service |
54dbc3 |
1.2 if a change is required send the port info
|
|
Packit Service |
54dbc3 |
2 if any change send the signal PENDING...
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
int osm_lid_mgr_process_subnet(IN osm_lid_mgr_t * p_mgr)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
cl_qmap_t *p_port_guid_tbl;
|
|
Packit Service |
54dbc3 |
osm_port_t *p_port;
|
|
Packit Service |
54dbc3 |
ib_net64_t port_guid;
|
|
Packit Service |
54dbc3 |
int lid_changed, ret = 0;
|
|
Packit Service |
54dbc3 |
uint16_t min_lid_ho, max_lid_ho;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_mgr);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_PLOCK_EXCL_ACQUIRE(p_mgr->p_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_mgr->p_subn->sm_port_guid);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_port_guid_tbl = &p_mgr->p_subn->port_guid_tbl;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (p_port = (osm_port_t *) cl_qmap_head(p_port_guid_tbl);
|
|
Packit Service |
54dbc3 |
p_port != (osm_port_t *) cl_qmap_end(p_port_guid_tbl);
|
|
Packit Service |
54dbc3 |
p_port = (osm_port_t *) cl_qmap_next(&p_port->map_item)) {
|
|
Packit Service |
54dbc3 |
port_guid = osm_port_get_guid(p_port);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Our own port is a special case in that we want to
|
|
Packit Service |
54dbc3 |
assign a LID to ourselves first, since we have to
|
|
Packit Service |
54dbc3 |
advertise that LID value to the other ports.
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
For that reason, our node is treated separately and
|
|
Packit Service |
54dbc3 |
we will not add it to any of these lists.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (port_guid == p_mgr->p_subn->sm_port_guid) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"Skipping our own port 0x%016" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(port_guid));
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
get the port lid range - we need to send it on first active
|
|
Packit Service |
54dbc3 |
sweep or if there was a change (the result of
|
|
Packit Service |
54dbc3 |
lid_mgr_get_port_lid)
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
lid_changed = lid_mgr_get_port_lid(p_mgr, p_port,
|
|
Packit Service |
54dbc3 |
&min_lid_ho, &max_lid_ho);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we can call the function to update the port info as it known
|
|
Packit Service |
54dbc3 |
to look for any field change and will only send an updated
|
|
Packit Service |
54dbc3 |
if required */
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_mgr->p_log, OSM_LOG_VERBOSE,
|
|
Packit Service |
54dbc3 |
"Assigned port 0x%016" PRIx64 ", %s LID [%u,%u]\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(port_guid), lid_changed ? "new" : "",
|
|
Packit Service |
54dbc3 |
min_lid_ho, max_lid_ho);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* the proc returns the fact it sent a set port info */
|
|
Packit Service |
54dbc3 |
if (lid_mgr_set_physp_pi(p_mgr, p_port, p_port->p_physp,
|
|
Packit Service |
54dbc3 |
cl_hton16(min_lid_ho)))
|
|
Packit Service |
54dbc3 |
ret = -1;
|
|
Packit Service |
54dbc3 |
} /* all ports */
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* store the guid to lid table in persistent db */
|
|
Packit Service |
54dbc3 |
osm_db_store(p_mgr->p_g2l, p_mgr->p_subn->opt.fsync_high_avail_files);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_PLOCK_RELEASE(p_mgr->p_lock);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_mgr->p_log);
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|