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