[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