public inbox for linux-rdma@vger.kernel.org
 help / color / mirror / Atom feed
From: Ira Weiny <weiny2-i2BcT+NCU+M@public.gmane.org>
To: Tamir Ronen <tamirr-smomgflXvOZWk0Htik3J/w@public.gmane.org>
Cc: "linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
	<linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Subject: Re: [PATCH] infiniband-diags: add support for ibnetdiscover grouping for Mellanox switches
Date: Mon, 14 Feb 2011 16:06:36 -0800	[thread overview]
Message-ID: <20110214160636.117b3e1e.weiny2@llnl.gov> (raw)
In-Reply-To: <4D52B595.3020302-smomgflXvOZWk0Htik3J/w@public.gmane.org>

Tamir,

I have this in a for-next branch.  Can someone from Mellanox verify this will work on all their switches.  I did not think they always labeled their switches this way but perhaps they do.

Can the user program node descriptors in those chassis?  I thought this was possible but I am unable to verify this today.

Ira


On Wed, 9 Feb 2011 07:41:09 -0800
Tamir Ronen <tamirr-smomgflXvOZWk0Htik3J/w@public.gmane.org> wrote:

> 
> From f1c92f4cae5605dec338b52ac6b261ddbe6e5609 Mon Sep 17 00:00:00 2001
> From: Tamir Ronen <tamirr-smomgflXvOZWk0Htik3J/w@public.gmane.org>
> Date: Tue, 8 Feb 2011 13:01:22 +0200
> Subject: [PATCH] add support for ibnetdiscover grouping for Mellanox switches
> 
> Group Mellanox switches to the same chassis using SYSTEM_GUID
> Use the node description format:
> 'MF0;<system name>:<system type>/<system slot name>[:board type]/U<node index>'
> to identify system type, slot type Line/Spine, slotnum and anafanum.
> Map Line ports 1-18 as external ports 1-18.
> ---
>  .../libibnetdisc/include/infiniband/ibnetdisc.h    |    3 +
>  infiniband-diags/libibnetdisc/src/chassis.c        |  220 ++++++++++++++++++-
>  infiniband-diags/libibnetdisc/src/chassis.h        |    3 +
>  3 files changed, 214 insertions(+), 12 deletions(-)
> 
> diff --git a/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h b/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h
> index 935e427..1efd1d6 100644
> --- a/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h
> +++ b/infiniband-diags/libibnetdisc/include/infiniband/ibnetdisc.h
> @@ -43,6 +43,8 @@
>  struct ibnd_chassis;		/* forward declare */
>  struct ibnd_port;		/* forward declare */
>  
> +#define CHASSIS_TYPE_SIZE 20
> +
>  /** =========================================================================
>   * Node
>   */
> @@ -80,6 +82,7 @@ typedef struct ibnd_node {
>  	struct ibnd_node *next_chassis_node;	/* next node in ibnd_chassis_t->nodes */
>  	struct ibnd_chassis *chassis;	/* if != NULL the chassis this node belongs to */
>  	unsigned char ch_type;
> +	char ch_type_str[CHASSIS_TYPE_SIZE];
>  	unsigned char ch_anafanum;
>  	unsigned char ch_slotnum;
>  	unsigned char ch_slot;
> diff --git a/infiniband-diags/libibnetdisc/src/chassis.c b/infiniband-diags/libibnetdisc/src/chassis.c
> index 6bfc45b..3d90034 100644
> --- a/infiniband-diags/libibnetdisc/src/chassis.c
> +++ b/infiniband-diags/libibnetdisc/src/chassis.c
> @@ -62,30 +62,53 @@ typedef struct chassis_scan {
>  
>  char *ibnd_get_chassis_type(ibnd_node_t * node)
>  {
> +	int chassis_type;
> +
>  	if (!node) {
>  		IBND_DEBUG("node parameter NULL\n");
>  		return NULL;
>  	}
>  
> -	/* Currently, only if Voltaire chassis */
> -	if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) != VTR_VENDOR_ID)
> -		return NULL;
>  	if (!node->chassis)
>  		return NULL;
> -	if (node->ch_type == UNRESOLVED_CT || node->ch_type > ISR4200_CT)
> -		return NULL;
> -	return ChassisTypeStr[node->ch_type];
> +
> +	chassis_type = mad_get_field(node->info, 0, IB_NODE_VENDORID_F);
> +
> +	switch (chassis_type)
> +	{
> +		case VTR_VENDOR_ID: /* Voltaire chassis */
> +		{
> +			if (node->ch_type == UNRESOLVED_CT || node->ch_type > ISR4200_CT)
> +				return NULL;
> +			return ChassisTypeStr[node->ch_type];
> +		}
> +		case MLX_VENDOR_ID:
> +		{
> +			if (node->ch_type_str[0] == '\0')
> +				return NULL;
> +			return node->ch_type_str;
> +		}
> +		default:
> +		{
> +			break;
> +		}
> +	}
> +	return NULL;
>  }
>  
>  char *ibnd_get_chassis_slot_str(ibnd_node_t * node, char *str, size_t size)
>  {
> +	int vendor_id;
> +
>  	if (!node) {
>  		IBND_DEBUG("node parameter NULL\n");
>  		return NULL;
>  	}
>  
> -	/* Currently, only if Voltaire chassis */
> -	if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) != VTR_VENDOR_ID)
> +	/* Currently, only if Voltaire or Mellanox chassis */
> +	vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
> +
> +	if ((vendor_id != VTR_VENDOR_ID) && (vendor_id != MLX_VENDOR_ID))
>  		return NULL;
>  	if (!node->chassis)
>  		return NULL;
> @@ -574,6 +597,166 @@ static int get_slb_slot(ibnd_node_t * n, ibnd_port_t * spineport)
>  	return 0;
>  }
>  
> +
> +/*
> +	This function called for every Mellanox node in fabric
> +*/
> +static int fill_mellanox_chassis_record(ibnd_node_t * node)
> +{
> +	int p = 0;
> +	ibnd_port_t *port;
> +
> +	char node_desc[IB_SMP_DATA_SIZE];
> +	char *system_name;
> +	char *system_type;
> +	char *system_slot_name;
> +	char *node_index;
> +	char *iter;
> +	int dev_id;
> +
> +	/*
> +	The node description has the following format:
> +
> +	'MF0;<system name>:<system type>/<system slot name>[:board type]/U<node index>'
> +
> +     - System slot name in our systems can be L[01-36] , S[01-18]
> +     - Node index is always 1 (we don.t have boards with multiple IS4 chips).
> +     - System name is taken from the currently configured host name.
> +     -The board type is optional and we don.t set it currently  - A leaf or spine slot can currently hold a single type of board.
> +	 */
> +
> +	memcpy(node_desc, node->nodedesc, IB_SMP_DATA_SIZE);
> +
> +	IBND_DEBUG("fill_mellanox_chassis_record: node_desc:%s \n",node_desc);
> +
> +	if (node->ch_found)	/* somehow this node has already been passed */
> +		return 0;
> +
> +	/* All mellanox IS4 switches have the same vendor id*/
> +	dev_id = mad_get_field(node->info, 0,IB_NODE_DEVID_F);
> +	if (dev_id != MLX_DEVID_IS4)
> +		return 0;
> +
> +	if((node_desc[0] != 'M') ||
> +	   (node_desc[1] != 'F') ||
> +	   (node_desc[2] != '0') ||
> +	   (node_desc[3] != ';')) {
> +		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s \n",node_desc);
> +		return 0;
> +	}
> +
> +	/* parse system name*/
> +	system_name = &node_desc[4];
> +	for (iter = system_name ; (*iter != ':') && (*iter != '\0') ; iter++);
> +	if(*iter == '\0'){
> +		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_name failed) \n",node_desc);
> +		return 0;
> +	}
> +	*iter = '\0';
> +	iter++;
> +	/* parse system type*/
> +	system_type = iter;
> +	for ( ; (*iter != '/') && (*iter != '\0') ; iter++);
> +	if(*iter == '\0'){
> +		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_type failed) \n",node_desc);
> +		return 0;
> +	}
> +	*iter = '\0';
> +	iter++;
> +	/* parse system slot name*/
> +	system_slot_name = iter;
> +	for ( ; (*iter != '/') && (*iter != ':') && (*iter != '\0') ; iter++);
> +	if(*iter == '\0'){
> +		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_slot_name failed) \n",node_desc);
> +		return 0;
> +	}
> +	if(*iter == ':'){
> +		*iter = '\0';
> +		iter++;
> +		for ( ; (*iter != '/') && (*iter != '\0') ; iter++);
> +		if(*iter == '\0'){
> +			IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get board type failed) \n",node_desc);
> +			return 0;
> +		}
> +	}
> +	*iter = '\0';
> +	iter++;
> +	node_index = iter;
> +	if(node_index[0] != 'U'){
> +		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get node index) \n",node_desc);
> +		return 0;
> +	}
> +
> +	/* set Chip number (node index) */
> +	node->ch_anafanum = atoi(&node_index[1]);
> +	if(node->ch_anafanum != 1){
> +		IBND_DEBUG("Unexpected Chip number:%d \n",node->ch_anafanum);
> +	}
> +
> +
> +	/* set Line Spine numbers */
> +	if(system_slot_name[0] == 'L')
> +		node->ch_slot = LINE_CS;
> +	else if(system_slot_name[0] == 'S')
> +		node->ch_slot = SPINE_CS;
> +	else{
> +		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported system_slot_name:%s \n",system_slot_name);
> +		return 0;
> +	}
> +
> +	/* The switch will be displayed under Line or Spine and not under Chassis switches */
> +	node->ch_found = 1;
> +
> +	node->ch_slotnum = atoi(&system_slot_name[1]);
> +	if((node->ch_slot == LINE_CS && (node->ch_slotnum >  (LINES_MAX_NUM + 1))) ||
> +	   (node->ch_slot == SPINE_CS && (node->ch_slotnum > (SPINES_MAX_NUM + 1)))){
> +		IBND_ERROR("fill_mellanox_chassis_record: invalid slot number:%d \n",node->ch_slotnum);
> +		node->ch_slotnum = 0;
> +		return 0;
> +	}
> +
> +	/*set ch_type_str*/
> +	strncpy(node->ch_type_str , system_type, sizeof(node->ch_type_str)-1);
> +
> +	/* Line ports 1-18 are mapped to external ports 1-18*/
> +	if(node->ch_slot == LINE_CS)
> +	{
> +		for (p = 1; p <= node->numports && p <= 18 ; p++) {
> +			port = node->ports[p];
> +			if (!port)
> +				continue;
> +			port->ext_portnum = p;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int insert_mellanox_line_and_spine(ibnd_node_t * node, ibnd_chassis_t * chassis)
> +{
> +	if (node->ch_slot == LINE_CS){
> +
> +		if (chassis->linenode[node->ch_slotnum])
> +			return 0;	/* already filled slot */
> +
> +		chassis->linenode[node->ch_slotnum] = node;
> +	}
> +	else if (node->ch_slot == SPINE_CS){
> +
> +		if (chassis->spinenode[node->ch_slotnum])
> +			return 0;	/* already filled slot */
> +
> +		chassis->spinenode[node->ch_slotnum] = node;
> +	}
> +	else
> +		return 0;
> +
> +	node->chassis = chassis;
> +
> +	return 0;
> +}
> +
> +
>  /* forward declare this */
>  static void voltaire_portmap(ibnd_port_t * port);
>  /*
> @@ -1064,15 +1247,23 @@ int group_nodes(ibnd_fabric_t * fabric)
>  	chassis_scan.current_chassis = NULL;
>  	chassis_scan.last_chassis = NULL;
>  
> +	int vendor_id;
> +
>  	/* first pass on switches and build for every Voltaire node */
>  	/* an appropriate chassis record (slotnum and position) */
>  	/* according to internal connectivity */
>  	/* not very efficient but clear code so... */
>  	for (node = fabric->switches; node; node = node->type_next) {
> -		if (mad_get_field(node->info, 0,
> -				  IB_NODE_VENDORID_F) == VTR_VENDOR_ID
> +
> +		vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
> +
> +		if (vendor_id == VTR_VENDOR_ID
>  		    && fill_voltaire_chassis_record(node))
>  			goto cleanup;
> +		else if (vendor_id == MLX_VENDOR_ID
> +			&& fill_mellanox_chassis_record(node))
> +			goto cleanup;
> +
>  	}
>  
>  	/* separate every Voltaire chassis from each other and build linked list of them */
> @@ -1118,8 +1309,10 @@ int group_nodes(ibnd_fabric_t * fabric)
>  	/* now, make another pass to see which nodes are part of chassis */
>  	/* (defined as chassis->nodecount > 1) */
>  	for (node = fabric->nodes; node; node = node->next) {
> -		if (mad_get_field(node->info, 0,
> -				  IB_NODE_VENDORID_F) == VTR_VENDOR_ID)
> +
> +		vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
> +
> +		if (vendor_id == VTR_VENDOR_ID)
>  			continue;
>  		if (mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F)) {
>  			chassis = find_chassisguid(fabric, node);
> @@ -1130,6 +1323,9 @@ int group_nodes(ibnd_fabric_t * fabric)
>  					node->ch_found = 1;
>  					add_node_to_chassis(chassis, node);
>  				}
> +				else if (vendor_id == MLX_VENDOR_ID){
> +					insert_mellanox_line_and_spine(node, chassis);
> +				}
>  			}
>  		}
>  	}
> diff --git a/infiniband-diags/libibnetdisc/src/chassis.h b/infiniband-diags/libibnetdisc/src/chassis.h
> index 004156e..7a91be3 100644
> --- a/infiniband-diags/libibnetdisc/src/chassis.h
> +++ b/infiniband-diags/libibnetdisc/src/chassis.h
> @@ -75,8 +75,11 @@
>  #define VTR_DEVID_SFB4700X2		0x5a5d
>  #define VTR_DEVID_SFB4200		0x5a60
>  
> +#define MLX_DEVID_IS4			0xbd36
> +
>  /* Vendor IDs (for chassis based systems) */
>  #define VTR_VENDOR_ID			0x8f1	/* Voltaire */
> +#define MLX_VENDOR_ID			0x2c9	/* Mellanox */
>  #define TS_VENDOR_ID			0x5ad	/* Cisco */
>  #define SS_VENDOR_ID			0x66a	/* InfiniCon */
>  #define XS_VENDOR_ID			0x1397	/* Xsigo */
> -- 
> 1.5.5.6
> 


-- 
Ira Weiny
Math Programmer/Computer Scientist
Lawrence Livermore National Lab
925-423-8008
weiny2-i2BcT+NCU+M@public.gmane.org
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2011-02-15  0:06 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-09 15:41 [PATCH] infiniband-diags: add support for ibnetdiscover grouping for Mellanox switches Tamir Ronen
     [not found] ` <4D52B595.3020302-smomgflXvOZWk0Htik3J/w@public.gmane.org>
2011-02-15  0:06   ` Ira Weiny [this message]
  -- strict thread matches above, loose matches on Subject: below --
2011-02-15 12:10 Tamir Ronen
     [not found] ` <AA090FF3B57CA34BBC78B3CE7624333AB376-FXD4EHQYOQ+layAChLZOBkEOCMrvLtNR@public.gmane.org>
2011-02-25 23:38   ` Ira Weiny

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110214160636.117b3e1e.weiny2@llnl.gov \
    --to=weiny2-i2bct+ncu+m@public.gmane.org \
    --cc=linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=tamirr-smomgflXvOZWk0Htik3J/w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox