diff mbox

[opensm] Fix handling of get P_KeyTable on timeout

Message ID 52739A2F.9050508@dev.mellanox.co.il (mailing list archive)
State Accepted
Delegated to: Hal Rosenstock
Headers show

Commit Message

Hal Rosenstock Nov. 1, 2013, 12:10 p.m. UTC
From: Dan Ben Yosef <danby@mellanox.com>

if the get of pkey tbl times out, remove the node from the subnet
and indicate subnet initialization error so subnet is reswept

Signed-off-by: Dan Ben Yosef <danby@mellanox.com>
Signed-off-by: Hal Rosenstock <hal@mellanox.com>
---
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/include/opensm/osm_pkey.h b/include/opensm/osm_pkey.h
index 54888e6..2ba80b3 100644
--- a/include/opensm/osm_pkey.h
+++ b/include/opensm/osm_pkey.h
@@ -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
diff --git a/opensm/osm_drop_mgr.c b/opensm/osm_drop_mgr.c
index 4276fe9..85a6f58 100644
--- a/opensm/osm_drop_mgr.c
+++ b/opensm/osm_drop_mgr.c
@@ -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;
+			}
+		}
 	}
 
 	/*
diff --git a/opensm/osm_pkey.c b/opensm/osm_pkey.c
index 9e4bdd4..7a8ac0a 100644
--- a/opensm/osm_pkey.c
+++ b/opensm/osm_pkey.c
@@ -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;
 }
 
diff --git a/opensm/osm_port.c b/opensm/osm_port.c
index 6e73e66..4c42fe9 100644
--- a/opensm/osm_port.c
+++ b/opensm/osm_port.c
@@ -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);
 }
diff --git a/opensm/osm_port_info_rcv.c b/opensm/osm_port_info_rcv.c
index 1a7377a..30cd096 100644
--- a/opensm/osm_port_info_rcv.c
+++ b/opensm/osm_port_info_rcv.c
@@ -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) {