From patchwork Fri May 20 19:49:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hal Rosenstock X-Patchwork-Id: 804702 X-Patchwork-Delegate: alexne@voltaire.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p4KJnt4L001499 for ; Fri, 20 May 2011 19:50:02 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757191Ab1ETTuB (ORCPT ); Fri, 20 May 2011 15:50:01 -0400 Received: from mail-ww0-f44.google.com ([74.125.82.44]:50048 "EHLO mail-ww0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757050Ab1ETTuA (ORCPT ); Fri, 20 May 2011 15:50:00 -0400 Received: by wwa36 with SMTP id 36so4356378wwa.1 for ; Fri, 20 May 2011 12:49:59 -0700 (PDT) Received: by 10.227.197.21 with SMTP id ei21mr2283836wbb.107.1305920999360; Fri, 20 May 2011 12:49:59 -0700 (PDT) Received: from [192.168.1.103] (c-71-192-10-85.hsd1.ma.comcast.net [71.192.10.85]) by mx.google.com with ESMTPS id bi13sm2492527wbb.25.2011.05.20.12.49.57 (version=SSLv3 cipher=OTHER); Fri, 20 May 2011 12:49:58 -0700 (PDT) Message-ID: <4DD6C5E3.5030106@dev.mellanox.co.il> Date: Fri, 20 May 2011 15:49:55 -0400 From: Hal Rosenstock User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.17) Gecko/20110414 Thunderbird/3.1.10 MIME-Version: 1.0 To: Alex Netes CC: "linux-rdma@vger.kernel.org" Subject: [PATCHv2 2/13] opensm: Make SA assigned guids persistent across port down/up events Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 20 May 2011 19:50:02 +0000 (UTC) Infrastructure in osm_subnet.[h c] with actual changes in opensm/osm_sa_guidinfo_record.c Signed-off-by: Hal Rosenstock --- Changes since v1: In set_guidinfo when osm_assigned_guids_new fails, send SA error and return include/opensm/osm_subnet.h | 110 ++++++++++++++++++++++++++++++++++++++- opensm/osm_sa_guidinfo_record.c | 40 +++++++++++++- opensm/osm_subnet.c | 41 ++++++++++++++- 3 files changed, 186 insertions(+), 5 deletions(-) diff --git a/include/opensm/osm_subnet.h b/include/opensm/osm_subnet.h index 914b9d4..5c19b19 100644 --- a/include/opensm/osm_subnet.h +++ b/include/opensm/osm_subnet.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. - * Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved. + * Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved. * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. * Copyright (c) 2008 Xsigo Systems Inc. All rights reserved. * Copyright (c) 2009 System Fabric Works, Inc. All rights reserved. @@ -527,6 +527,7 @@ typedef struct osm_subn { cl_qmap_t node_guid_tbl; cl_qmap_t port_guid_tbl; cl_qmap_t alias_port_guid_tbl; + cl_qmap_t assigned_guids_tbl; cl_qmap_t rtr_guid_tbl; cl_qlist_t prefix_routes_list; cl_qmap_t prtn_pkey_tbl; @@ -693,6 +694,35 @@ typedef struct osm_subn { * Subnet object *********/ +/****s* OpenSM: Subnet/osm_assigned_guids_t +* NAME +* osm_assigned_guids_t +* +* DESCRIPTION +* SA assigned GUIDs structure. +* +* SYNOPSIS +*/ +typedef struct osm_assigned_guids { + cl_map_item_t map_item; + ib_net64_t port_guid; + ib_net64_t assigned_guid[1]; +} osm_assigned_guids_t; +/* +* FIELDS +* map_item +* Linkage structure for cl_qmap. MUST BE FIRST MEMBER! +* +* port_guid +* Base port GUID. +* +* assigned_guids +* Table of persistent SA assigned GUIDs. +* +* SEE ALSO +* Subnet object +*********/ + /****f* OpenSM: Subnet/osm_subn_construct * NAME * osm_subn_construct @@ -1039,6 +1069,84 @@ struct osm_port *osm_get_port_by_alias_guid(IN osm_subn_t const *p_subn, * osm_port_t *********/ +/****f* OpenSM: Port/osm_assigned_guids_new +* NAME +* osm_assigned_guids_new +* +* DESCRIPTION +* This function allocates and initializes an assigned guids object. +* +* SYNOPSIS +*/ +osm_assigned_guids_t *osm_assigned_guids_new(IN const ib_net64_t port_guid, + IN const uint32_t num_guids); +/* +* PARAMETERS +* port_guid +* [in] Base port GUID in network order +* +* RETURN VALUE +* Pointer to the initialized assigned alias guid object. +* +* SEE ALSO +* Subnet object, osm_assigned_guids_t, osm_assigned_guids_delete, +* osm_get_assigned_guids_by_guid +*********/ + +/****f* OpenSM: Port/osm_assigned_guids_delete +* NAME +* osm_assigned_guids_delete +* +* DESCRIPTION +* This function destroys and deallocates an assigned guids object. +* +* SYNOPSIS +*/ +void osm_assigned_guids_delete(IN OUT osm_assigned_guids_t ** pp_assigned_guids); +/* +* PARAMETERS +* pp_assigned_guids +* [in][out] Pointer to a pointer to an assigned guids object to delete. +* On return, this pointer is NULL. +* +* RETURN VALUE +* This function does not return a value. +* +* NOTES +* Performs any necessary cleanup of the specified assigned guids object. +* +* SEE ALSO +* Subnet object, osm_assigned_guids_new, osm_get_assigned_guids_by_guid +*********/ + +/****f* OpenSM: Subnet/osm_get_assigned_guids_by_guid +* NAME +* osm_get_assigned_guids_by_guid +* +* DESCRIPTION +* This looks for the given port guid and returns a pointer +* to the guid table of SA assigned alias guids for that port. +* +* SYNOPSIS +*/ +osm_assigned_guids_t *osm_get_assigned_guids_by_guid(IN osm_subn_t const *p_subn, + IN ib_net64_t port_guid); +/* +* PARAMETERS +* p_subn +* [in] Pointer to an osm_subn_t object +* +* port_guid +* [in] The base port guid in network order +* +* RETURN VALUES +* The osm_assigned_guids structure pointer if found. NULL otherwise. +* +* SEE ALSO +* Subnet object, osm_assigned_guids_new, osm_assigned_guids_delete, +* osm_assigned_guids_t +*********/ + /****f* OpenSM: Port/osm_get_port_by_lid * NAME * osm_get_port_by_lid diff --git a/opensm/osm_sa_guidinfo_record.c b/opensm/osm_sa_guidinfo_record.c index 484633f..039040b 100644 --- a/opensm/osm_sa_guidinfo_record.c +++ b/opensm/osm_sa_guidinfo_record.c @@ -467,15 +467,15 @@ static void set_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw, int i, j, dirty = 0; ib_sa_mad_t *p_sa_mad; ib_guidinfo_record_t *p_rcvd_rec; + osm_assigned_guids_t *p_assigned_guids = 0; osm_alias_guid_t *p_alias_guid, *p_alias_guid_check; cl_map_item_t *p_item; ib_net64_t set_alias_guid, del_alias_guid, assigned_guid; uint8_t set_mask; + max_block = (p_port->p_physp->port_info.guid_cap + GUID_TABLE_MAX_ENTRIES - 1) / + GUID_TABLE_MAX_ENTRIES; if (!p_port->p_physp->p_guids) { - max_block = (p_port->p_physp->port_info.guid_cap + GUID_TABLE_MAX_ENTRIES - 1) / - GUID_TABLE_MAX_ENTRIES; - p_port->p_physp->p_guids = calloc(max_block * GUID_TABLE_MAX_ENTRIES, sizeof(ib_net64_t)); if (!p_port->p_physp->p_guids) { @@ -524,6 +524,18 @@ static void set_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw, p_rcvd_rec->guid_info.guid[i % 8] = set_alias_guid; continue; } + /* Is there a persistent SA assigned guid for this index ? */ + if (!p_assigned_guids) + p_assigned_guids = + osm_get_assigned_guids_by_guid(sa->p_subn, + p_port->p_physp->port_guid); + if (p_assigned_guids) { + set_alias_guid = p_assigned_guids->assigned_guid[i]; + if (set_alias_guid) { + p_rcvd_rec->guid_info.guid[i % 8] = set_alias_guid; + goto add_alias_guid; + } + } } if (!set_alias_guid) { for (j = 0; j < 1000; j++) { @@ -540,6 +552,27 @@ static void set_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw, if (p_item == cl_qmap_end(&sa->sm->p_subn->alias_port_guid_tbl)) { set_alias_guid = assigned_guid; p_rcvd_rec->guid_info.guid[i % 8] = assigned_guid; + if (!p_assigned_guids) { + p_assigned_guids = osm_assigned_guids_new(p_port->p_physp->port_guid, + max_block * GUID_TABLE_MAX_ENTRIES); + if (p_assigned_guids) { + cl_qmap_insert(&(sa->p_subn->assigned_guids_tbl), + p_assigned_guids->port_guid, + &p_assigned_guids->map_item); + } else { + OSM_LOG(sa->p_log, + OSM_LOG_ERROR, + "ERR 510D: osm_assigned_guids_new failed port GUID 0x%" PRIx64 " index %d\n", + cl_ntoh64(p_port->p_physp->port_guid), i); + osm_sa_send_error(sa, p_madw, + IB_SA_MAD_STATUS_NO_RESOURCES); + return; + } + } + if (p_assigned_guids) +{ + p_assigned_guids->assigned_guid[i] = assigned_guid; +} break; } } @@ -552,6 +585,7 @@ static void set_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw, } } +add_alias_guid: /* allocate alias guid and add to alias guid table */ p_alias_guid = osm_alias_guid_new(set_alias_guid, p_port); if (!p_alias_guid) { diff --git a/opensm/osm_subnet.c b/opensm/osm_subnet.c index 34eaf29..32b5e1e 100644 --- a/opensm/osm_subnet.c +++ b/opensm/osm_subnet.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. - * Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved. + * Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved. * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. * Copyright (c) 2008 Xsigo Systems Inc. All rights reserved. * Copyright (c) 2009 System Fabric Works, Inc. All rights reserved. @@ -420,6 +420,7 @@ void osm_subn_construct(IN osm_subn_t * p_subn) cl_qmap_init(&p_subn->node_guid_tbl); cl_qmap_init(&p_subn->port_guid_tbl); cl_qmap_init(&p_subn->alias_port_guid_tbl); + cl_qmap_init(&p_subn->assigned_guids_tbl); cl_qmap_init(&p_subn->sm_guid_tbl); cl_qlist_init(&p_subn->sa_sr_list); cl_qlist_init(&p_subn->sa_infr_list); @@ -433,6 +434,7 @@ void osm_subn_destroy(IN osm_subn_t * p_subn) { int i; osm_node_t *p_node, *p_next_node; + osm_assigned_guids_t *p_assigned_guids, *p_next_assigned_guids; osm_alias_guid_t *p_alias_guid, *p_next_alias_guid; osm_port_t *p_port, *p_next_port; osm_switch_t *p_sw, *p_next_sw; @@ -450,6 +452,14 @@ void osm_subn_destroy(IN osm_subn_t * p_subn) osm_node_delete(&p_node); } + p_next_assigned_guids = (osm_assigned_guids_t *) cl_qmap_head(&p_subn->assigned_guids_tbl); + while (p_next_assigned_guids != + (osm_assigned_guids_t *) cl_qmap_end(&p_subn->assigned_guids_tbl)) { + p_assigned_guids = p_next_assigned_guids; + p_next_assigned_guids = (osm_assigned_guids_t *) cl_qmap_next(&p_assigned_guids->map_item); + osm_assigned_guids_delete(&p_assigned_guids); + } + p_next_alias_guid = (osm_alias_guid_t *) cl_qmap_head(&p_subn->alias_port_guid_tbl); while (p_next_alias_guid != (osm_alias_guid_t *) cl_qmap_end(&p_subn->alias_port_guid_tbl)) { @@ -652,6 +662,35 @@ osm_port_t *osm_get_port_by_alias_guid(IN osm_subn_t const *p_subn, return p_alias_guid->p_base_port; } +osm_assigned_guids_t *osm_assigned_guids_new(IN const ib_net64_t port_guid, + IN const uint32_t num_guids) +{ + osm_assigned_guids_t *p_assigned_guids; + + p_assigned_guids = calloc(1, sizeof(*p_assigned_guids) + + sizeof(ib_net64_t) * (num_guids - 1)); + if (p_assigned_guids) + p_assigned_guids->port_guid = port_guid; + return p_assigned_guids; +} + +void osm_assigned_guids_delete(IN OUT osm_assigned_guids_t ** pp_assigned_guids) +{ + free(*pp_assigned_guids); + *pp_assigned_guids = NULL; +} + +osm_assigned_guids_t *osm_get_assigned_guids_by_guid(IN osm_subn_t const *p_subn, + IN ib_net64_t port_guid) +{ + osm_assigned_guids_t *p_assigned_guids; + + p_assigned_guids = (osm_assigned_guids_t *) cl_qmap_get(&(p_subn->assigned_guids_tbl), port_guid); + if (p_assigned_guids == (osm_assigned_guids_t *) cl_qmap_end(&(p_subn->assigned_guids_tbl))) + return NULL; + return p_assigned_guids; +} + osm_port_t *osm_get_port_by_lid_ho(IN osm_subn_t const * subn, IN uint16_t lid) { if (lid < cl_ptr_vector_get_size(&subn->port_lid_tbl))