@@ -90,6 +90,7 @@ typedef struct osm_pkeybl {
uint16_t last_pkey_idx;
uint16_t used_blocks;
uint16_t max_blocks;
+ uint16_t rcv_blocks_cnt;
} osm_pkey_tbl_t;
/*
* FIELDS
@@ -119,6 +120,11 @@ typedef struct osm_pkeybl {
* switch_info updated on receiving the node_info or switch_info
* GetResp
*
+* rcv_blocks_cnt
+* Counter for the received GetPKeyTable mads.
+* For every GetPKeyTable mad we send, increase the counter,
+* and for every GetRespPKeyTable we decrease the counter.
+*
* NOTES
* 'blocks' vector should be used to store pkey values obtained from
* the port and SM pkey manager should not change it directly, for this
@@ -500,6 +500,9 @@ void osm_drop_mgr_process(osm_sm_t * sm)
cl_qmap_t *p_node_guid_tbl, *p_port_guid_tbl;
osm_port_t *p_port, *p_next_port;
osm_node_t *p_node, *p_next_node;
+ int max_ports, port_num;
+ osm_physp_t *p_physp;
+ ib_net64_t port_guid;
CL_ASSERT(sm);
@@ -530,6 +533,28 @@ void osm_drop_mgr_process(osm_sm_t * sm)
*/
if (p_node->discovery_count == 0)
drop_mgr_process_node(sm, p_node);
+ else {
+ /*
+ * Drop port if there was timeout for GetPKeyTable
+ */
+ if (osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH)
+ port_num = 0;
+ else
+ port_num = 1;
+ max_ports = osm_node_get_num_physp(p_node);
+ for (; port_num < max_ports; port_num++) {
+ p_physp = osm_node_get_physp_ptr(p_node, port_num);
+ if (!p_physp || p_physp->pkeys.rcv_blocks_cnt == 0)
+ continue;
+ sm->p_subn->subnet_initialization_error = TRUE;
+ if (!port_num || osm_node_get_type(p_node) != IB_NODE_TYPE_SWITCH) {
+ port_guid = osm_physp_get_port_guid(p_physp);
+ p_port = osm_get_port_by_guid(sm->p_subn, port_guid);
+ p_port->discovery_count = 0;
+ } else
+ p_node->physp_discovered[port_num] = 0;
+ }
+ }
}
/*
@@ -98,6 +98,7 @@ ib_api_status_t osm_pkey_tbl_init(IN osm_pkey_tbl_t * p_pkey_tbl)
p_pkey_tbl->last_pkey_idx = 0;
p_pkey_tbl->used_blocks = 0;
p_pkey_tbl->max_blocks = 0;
+ p_pkey_tbl->rcv_blocks_cnt = 0;
return IB_SUCCESS;
}
@@ -639,6 +639,8 @@ void osm_physp_set_pkey_tbl(IN osm_log_t * p_log, IN const osm_subn_t * p_subn,
return;
}
+ /* decrement block received counter */
+ p_physp->pkeys.rcv_blocks_cnt--;
osm_pkey_tbl_set(&p_physp->pkeys, block_num, p_pkey_tbl,
p_subn->opt.allow_both_pkeys);
}
@@ -431,6 +431,7 @@ static void get_pkey_table(IN osm_log_t * p_log, IN osm_sm_t * sm,
1) / IB_NUM_PKEY_ELEMENTS_IN_BLOCK;
}
+ p_physp->pkeys.rcv_blocks_cnt = max_blocks;
for (block_num = 0; block_num < max_blocks; block_num++) {
if (osm_node_get_type(p_node) != IB_NODE_TYPE_SWITCH ||
osm_physp_get_port_num(p_physp) == 0) {