From patchwork Mon Nov 2 21:11:56 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Chu X-Patchwork-Id: 57133 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nA2LBwxg025299 for ; Mon, 2 Nov 2009 21:11:58 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755180AbZKBVLw (ORCPT ); Mon, 2 Nov 2009 16:11:52 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755245AbZKBVLw (ORCPT ); Mon, 2 Nov 2009 16:11:52 -0500 Received: from nspiron-1.llnl.gov ([128.115.41.81]:7074 "EHLO nspiron-1.llnl.gov" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755180AbZKBVLv (ORCPT ); Mon, 2 Nov 2009 16:11:51 -0500 X-Attachments: 0002-split-out-scan-specific-data-from-ibnd_node_t.patch Received: from auk31.llnl.gov (HELO [134.9.93.159]) ([134.9.93.159]) by nspiron-1.llnl.gov with ESMTP; 02 Nov 2009 13:11:56 -0800 Subject: Re: [infiniband-diags] [PATCH] [2/2] split out scan specific data from ibnd_node_t From: Al Chu Reply-To: chu11@llnl.gov To: sashak@voltaire.com Cc: linux-rdma@vger.kernel.org In-Reply-To: <1257190401.580.31.camel@auk31.llnl.gov> References: <1257190401.580.31.camel@auk31.llnl.gov> Date: Mon, 02 Nov 2009 13:11:56 -0800 Message-Id: <1257196316.580.33.camel@auk31.llnl.gov> Mime-Version: 1.0 X-Mailer: Evolution 2.12.3 (2.12.3-19.el5) Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org diff --git a/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h b/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h index 6120453..f1cb00c 100644 --- a/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h +++ b/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h @@ -48,7 +48,6 @@ struct ibnd_port; /* forward declare */ typedef struct ibnd_node { struct ibnd_node *next; /* all node list in fabric */ - ib_portid_t path_portid; /* path from "from_node" */ int smalid; int smalmc; @@ -81,7 +80,6 @@ typedef struct ibnd_node { /* internal use only */ unsigned char ch_found; struct ibnd_node *htnext; /* hash table list */ - struct ibnd_node *dnext; /* nodesdist next */ struct ibnd_node *type_next; /* next based on type */ } ibnd_node_t; diff --git a/infiniband-diags/libibnetdisc/src/chassis.c b/infiniband-diags/libibnetdisc/src/chassis.c index 15c17d2..3bd0108 100644 --- a/infiniband-diags/libibnetdisc/src/chassis.c +++ b/infiniband-diags/libibnetdisc/src/chassis.c @@ -822,6 +822,7 @@ int group_nodes(ibnd_fabric_t * fabric, ibnd_scan_t *scan) int chassisnum = 0; ibnd_chassis_t *chassis; ibnd_chassis_t *ch, *ch_next; + ibnd_node_scan_t *node_scan; scan->first_chassis = NULL; scan->current_chassis = NULL; @@ -832,16 +833,21 @@ int group_nodes(ibnd_fabric_t * fabric, ibnd_scan_t *scan) /* according to internal connectivity */ /* not very efficient but clear code so... */ for (dist = 0; dist <= fabric->maxhops_discovered; dist++) - for (node = scan->nodesdist[dist]; node; node = node->dnext) + for (node_scan = scan->nodesdist[dist]; node_scan; node_scan = node_scan->dnext) { + node = node_scan->node; + if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) == VTR_VENDOR_ID && fill_voltaire_chassis_record(node)) goto cleanup; + } /* separate every Voltaire chassis from each other and build linked list of them */ /* algorithm: catch spine and find all surrounding nodes */ for (dist = 0; dist <= fabric->maxhops_discovered; dist++) - for (node = scan->nodesdist[dist]; node; node = node->dnext) { + for (node_scan = scan->nodesdist[dist]; node_scan; node_scan = node_scan->dnext) { + node = node_scan->node; + if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) != VTR_VENDOR_ID) continue; @@ -859,7 +865,9 @@ int group_nodes(ibnd_fabric_t * fabric, ibnd_scan_t *scan) /* now make pass on nodes for chassis which are not Voltaire */ /* grouped by common SystemImageGUID */ for (dist = 0; dist <= fabric->maxhops_discovered; dist++) - for (node = scan->nodesdist[dist]; node; node = node->dnext) { + for (node_scan = scan->nodesdist[dist]; node_scan; node_scan = node_scan->dnext) { + node = node_scan->node; + if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) == VTR_VENDOR_ID) continue; @@ -885,7 +893,9 @@ int group_nodes(ibnd_fabric_t * fabric, ibnd_scan_t *scan) /* now, make another pass to see which nodes are part of chassis */ /* (defined as chassis->nodecount > 1) */ for (dist = 0; dist <= MAXHOPS;) { - for (node = scan->nodesdist[dist]; node; node = node->dnext) { + for (node_scan = scan->nodesdist[dist]; node_scan; node_scan = node_scan->dnext) { + node = node_scan->node; + if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) == VTR_VENDOR_ID) continue; diff --git a/infiniband-diags/libibnetdisc/src/ibnetdisc.c b/infiniband-diags/libibnetdisc/src/ibnetdisc.c index ffa35e4..233654c 100644 --- a/infiniband-diags/libibnetdisc/src/ibnetdisc.c +++ b/infiniband-diags/libibnetdisc/src/ibnetdisc.c @@ -332,13 +332,26 @@ static void add_to_type_list(ibnd_node_t * node, ibnd_fabric_t * fabric) } } -static void add_to_nodedist(ibnd_node_t * node, ibnd_scan_t * scan, int dist) +static int add_to_nodedist(ibnd_node_t * node, ibnd_scan_t * scan, + ib_portid_t * path, int dist) { + ibnd_node_scan_t *node_scan; + + node_scan = malloc(sizeof(*node_scan)); + if (!node_scan) { + IBND_ERROR("OOM: node scan creation failed\n"); + return -1; + } + node_scan->node = node; + node_scan->path_portid = *path; + if (node->type != IB_NODE_SWITCH) dist = MAXHOPS; /* special Ca list */ - node->dnext = scan->nodesdist[dist]; - scan->nodesdist[dist] = node; + node_scan->dnext = scan->nodesdist[dist]; + scan->nodesdist[dist] = node_scan; + + return 0; } static ibnd_node_t *create_node(ibnd_fabric_t * fabric, ibnd_scan_t * scan, @@ -354,7 +367,6 @@ static ibnd_node_t *create_node(ibnd_fabric_t * fabric, ibnd_scan_t * scan, } memcpy(node, temp, sizeof(*node)); - node->path_portid = *path; add_to_nodeguid_hash(node, fabric->nodestbl); @@ -363,7 +375,11 @@ static ibnd_node_t *create_node(ibnd_fabric_t * fabric, ibnd_scan_t * scan, fabric->nodes = node; add_to_type_list(node, fabric); - add_to_nodedist(node, scan, dist); + + if (add_to_nodedist(node, scan, path, dist) < 0) { + free(node); + return NULL; + } return node; } @@ -483,6 +499,23 @@ error: return rc; } +static void ibnd_scan_destroy(ibnd_scan_t *scan) +{ + int dist = 0; + int max_hops = MAXHOPS - 1; + ibnd_node_scan_t *node_scan; + ibnd_node_scan_t *next; + + for (dist = 0; dist <= max_hops; dist++) { + node_scan = scan->nodesdist[dist]; + while (node_scan) { + next = node_scan->dnext; + free(node_scan); + node_scan = next; + } + } +} + ibnd_fabric_t *ibnd_discover_fabric(struct ibmad_port * ibmad_port, ib_portid_t * from, int hops) { @@ -492,6 +525,7 @@ ibnd_fabric_t *ibnd_discover_fabric(struct ibmad_port * ibmad_port, ibnd_node_t node_buf; ibnd_port_t port_buf; ibnd_node_t *node; + ibnd_node_scan_t *node_scan; ibnd_port_t *port; int i; int dist = 0; @@ -552,9 +586,10 @@ ibnd_fabric_t *ibnd_discover_fabric(struct ibmad_port * ibmad_port, for (dist = 0; dist <= max_hops; dist++) { - for (node = scan.nodesdist[dist]; node; node = node->dnext) { + for (node_scan = scan.nodesdist[dist]; node_scan; node_scan = node_scan->dnext) { + node = node_scan->node; - path = &node->path_portid; + path = &node_scan->path_portid; IBND_DEBUG("dist %d node %p\n", dist, node); dump_endnode(path, "processing", node, port); @@ -598,8 +633,10 @@ ibnd_fabric_t *ibnd_discover_fabric(struct ibmad_port * ibmad_port, if (group_nodes(fabric, &scan)) goto error; + ibnd_scan_destroy(&scan); return fabric; error: + ibnd_scan_destroy(&scan); ibnd_destroy_fabric(fabric); return NULL; } diff --git a/infiniband-diags/libibnetdisc/src/internal.h b/infiniband-diags/libibnetdisc/src/internal.h index eac1a29..d8bcf87 100644 --- a/infiniband-diags/libibnetdisc/src/internal.h +++ b/infiniband-diags/libibnetdisc/src/internal.h @@ -52,8 +52,14 @@ #define MAXHOPS 63 +typedef struct ibnd_node_scan { + ibnd_node_t *node; + ib_portid_t path_portid; /* path from "from_node" */ + struct ibnd_node_scan *dnext; /* nodesdist next */ +} ibnd_node_scan_t; + typedef struct ibnd_scan { - ibnd_node_t *nodesdist[MAXHOPS + 1]; + ibnd_node_scan_t *nodesdist[MAXHOPS + 1]; ibnd_chassis_t *first_chassis; ibnd_chassis_t *current_chassis; ibnd_chassis_t *last_chassis;