[openib-general] [PATCH 12/12] SRP: Changing ibsrpdm

Ishai Rabinovitz ishai at mellanox.co.il
Mon May 1 04:31:41 PDT 2006


The query can be improved if working against OpenSM that supports
the option to ask about a certain bit in the capability mask.

Signed-off-by: Ishai Rabinovitz <ishai at mellanox.co.il>

Index: last_stable/src/userspace/srptools/src/srp-dm.c
===================================================================
--- last_stable.orig/src/userspace/srptools/src/srp-dm.c	2006-04-21 06:26:25.000000000 +0300
+++ last_stable/src/userspace/srptools/src/srp-dm.c	2006-04-21 06:30:36.000000000 +0300
@@ -97,10 +97,16 @@ static inline uint64_t htonll(uint64_t x
 
 #define SIZE_OF_QUERY_RESPONSE (1 << 18)
 
+#define SM_SUPPORTS_QUERY_OF_PART_OF_CAP_MASK_BIT_MASK (1 << 13)
+
+#define TEST_ONLY_SET_BIT_BIT_MASK (1 << 31)
+
 #define N_COMP_MASK_NODE_TYPE htonll(1 << 4);
 
 #define N_COMP_MASK_LID htonll(1);
 
+#define N_COMP_MASK_CAPABILITY_MASK htonll(1 << 7);
+
 #define INITIAL_SIZE_OF_TARGET_TABLE 10
 
 #define SLEEP_TIME 60
@@ -180,8 +186,6 @@ static void empty_set(targets_set *set)
 
 static void destroy_set(targets_set *set)
 {
-	int i;
-
 	empty_set(set);
 	free(set->array);
 }
@@ -679,6 +683,63 @@ static int get_port_info(int fd, uint32_
 	return 0;
 }
 
+int get_class_port_info(int fd, uint32_t agent[2], uint16_t dlid,
+			int *is_mask_match_supported)
+{
+	struct ib_user_mad		out_mad, in_mad;
+	struct srp_dm_rmpp_sa_mad      *out_sa_mad, *in_sa_mad;
+	struct srp_dm_mad	       *in_dm_mad;
+	struct srp_dm_class_port_info  *class_port_info;
+
+	in_sa_mad  = (void *) in_mad.data;
+	in_dm_mad  = (void *) in_mad.data;
+	out_sa_mad = (void *) out_mad.data;
+
+	init_srp_dm_mad(&out_mad, agent[1], sm_lid, SRP_DM_ATTR_CLASS_PORT_INFO, 0);
+
+	out_sa_mad->mgmt_class 	  = SRP_MGMT_CLASS_SA;
+	out_sa_mad->class_version = 2;
+
+	if (send_and_get(fd, &out_mad, &in_mad, 0) < 0)
+		return -1;
+
+        /* TODO: to handle forwarding */
+	class_port_info = (void *) in_sa_mad->data;
+	*is_mask_match_supported =
+		!!(ntohs(class_port_info->cap_mask) &
+		   SM_SUPPORTS_QUERY_OF_PART_OF_CAP_MASK_BIT_MASK);
+
+	return 0;
+}
+
+int get_node_info(int fd, uint32_t agent[2], uint16_t dlid, uint64_t *n_guid)
+{
+	struct ib_user_mad		out_mad, in_mad;
+	struct srp_dm_rmpp_sa_mad      *out_sa_mad, *in_sa_mad;
+	struct srp_dm_mad	       *in_dm_mad;
+	struct srp_sa_node_rec         *node_info;
+
+	in_sa_mad  = (void *) in_mad.data;
+	in_dm_mad  = (void *) in_mad.data;
+	out_sa_mad = (void *) out_mad.data;
+
+	init_srp_dm_mad(&out_mad, agent[1], sm_lid, SRP_SA_ATTR_NODE, 0);
+
+	out_sa_mad->mgmt_class 	  = SRP_MGMT_CLASS_SA;
+	out_sa_mad->class_version = 2;
+	out_sa_mad->comp_mask	  = htonll((uint64_t)1); /* LID */
+	node_info		  = (void *) out_sa_mad->data;
+	node_info->lid		  = htons(dlid);
+
+	if (send_and_get(fd, &out_mad, &in_mad, 0) < 0)
+		return -1;
+
+	node_info = (void *) in_sa_mad->data;
+	*n_guid   = node_info->port_guid;
+
+	return 0;
+}
+
 static int get_port_list(int fd, uint32_t agent[2])
 {
 	uint8_t				in_mad_space[SIZE_OF_QUERY_RESPONSE];
@@ -686,19 +747,11 @@ static int get_port_list(int fd, uint32_
 	struct srp_dm_rmpp_sa_mad      *out_sa_mad, *in_sa_mad;
 	struct srp_sa_node_rec	       *node;
 	ssize_t len;
-	char val[64];
 	int size;
 	int i;
 	uint64_t subnet_prefix;
 	int isdm;
 
-	if (read_file(port_sysfs_path, "sm_lid", val, sizeof val) < 0) {
-		pr_err("Couldn't read SM LID\n");
-		return -1;
-	}
-
-	sm_lid = strtol(val, NULL, 0);
-
 	in_sa_mad  = (void *) in_mad->data;
 	out_sa_mad = (void *) out_mad.data;
 
@@ -762,6 +815,57 @@ static int get_existing_targets()
 	return 0;
 }
 
+int get_port_list_new(int fd, uint32_t agent[2])
+{
+	uint8_t in_mad_space[SIZE_OF_QUERY_RESPONSE];
+	struct ib_user_mad	    out_mad, *in_mad=(void *) in_mad_space;
+	struct srp_dm_rmpp_sa_mad   *out_sa_mad, *in_sa_mad;
+	struct srp_sa_port_info_rec *port_info;
+	ssize_t len;
+	int size;
+	int i;
+	uint64_t subnet_prefix;
+	uint16_t lid;
+	uint64_t guid;
+
+	in_sa_mad  = (void *) in_mad->data;
+	out_sa_mad = (void *) out_mad.data;
+
+	init_srp_dm_mad(&out_mad, agent[1], sm_lid, SRP_SA_ATTR_PORT_INFO,
+			TEST_ONLY_SET_BIT_BIT_MASK);
+
+	out_sa_mad->mgmt_class 	   = SRP_MGMT_CLASS_SA;
+	out_sa_mad->method     	   = SRP_SA_METHOD_GET_TABLE;
+	out_sa_mad->class_version  = 2;
+	out_sa_mad->comp_mask	   = N_COMP_MASK_CAPABILITY_MASK;
+	port_info		   = (void *) out_sa_mad->data;
+	port_info->capability_mask = htonl(IS_DM_MASK);
+
+	if ((len = send_and_get(fd, &out_mad, in_mad, SIZE_OF_QUERY_RESPONSE)) < 0)
+		return -1;
+
+	size = ntohs(in_sa_mad->attr_offset) * 8;
+
+	for (i = 0; (i + 1) * size <= len - 56 - 36; ++i) {
+		port_info = (void *) in_sa_mad->data + i * size;
+
+		if (!(ntohl(port_info->capability_mask) & IS_DM_MASK)) {
+			pr_err("Error in query %s%d\n", __func__, __LINE__);
+			return -1;
+		}
+
+		lid = ntohs(port_info->endport_lid);
+
+		if (get_node_info(fd, agent, lid, &guid))
+			continue;
+
+		subnet_prefix = ntohll(port_info->subnet_prefix);
+		do_port(fd, agent, lid, subnet_prefix, ntohll(guid));
+	}
+
+	return 0;
+}
+
 int main(int argc, char *argv[])
 {
 	int		fd;
@@ -769,6 +873,7 @@ int main(int argc, char *argv[])
 	char	       *cmd_name = strdup(argv[0]);
 	pid_t		pid, sid;
 	int		ret;
+	char 		val[64];
 
 	while (1) {
 		int c;
@@ -808,6 +913,13 @@ int main(int argc, char *argv[])
 	if (create_agent(fd, agent))
 		exit(EXIT_FAILURE);
 
+	if (read_file(port_sysfs_path, "sm_lid", val, sizeof val) < 0) {
+		fprintf(stderr, "Couldn't read SM LID\n");
+		exit(EXIT_FAILURE);
+	}
+
+	sm_lid = strtol(val, NULL, 0);
+
 	/* Daemon-specific initialization goes here */
 	targets_in_kernel_set = (targets_set *) malloc(sizeof(targets_set));
 	create_set(targets_in_kernel_set);
@@ -851,16 +963,39 @@ int main(int argc, char *argv[])
 
 	/* The Big Loop */
 	while (1) {
+ 		int is_mask_match_supported;
+
 		if (loop)
 			(void) get_existing_targets();
 
-		ret = get_port_list(fd, agent);
+		if (get_class_port_info(fd, agent, sm_lid, &is_mask_match_supported))
+			exit(EXIT_FAILURE);
+
+		if (is_mask_match_supported)
+		{
+			pr_log("SM supports query for is dm\n");
+			ret = get_port_list_new(fd, agent);
+		}
+		else
+		{
+			pr_log("SM does not supoprt query for is dm\n");
+			ret = get_port_list(fd, agent);
+		}
+
 		if (loop == 0)
 			return ret;
 
 		free_old_targets();
 
 		sleep(SLEEP_TIME); /* wait SLEEP_TIME seconds */
+
+		while (read_file(port_sysfs_path, "sm_lid", val, sizeof val) < 0) {
+			pr_err("Couldn't read SM LID\n");
+			sleep(SLEEP_TIME); /* wait another SLEEP_TIME seconds */
+		}
+
+		sm_lid = strtol(val, NULL, 0);
+
 	}
 
 	destroy_set(targets_in_kernel_set);
-- 
Ishai Rabinovitz



More information about the general mailing list