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 <[EMAIL PROTECTED]>

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
_______________________________________________
openib-general mailing list
openib-general@openib.org
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to