From patchwork Fri Mar 1 01:05:26 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Weiny X-Patchwork-Id: 2200121 X-Patchwork-Delegate: hal@mellanox.com Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id BD5AADF2A2 for ; Fri, 1 Mar 2013 01:05:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752015Ab3CABF2 (ORCPT ); Thu, 28 Feb 2013 20:05:28 -0500 Received: from prdiron-3.llnl.gov ([128.15.143.173]:64894 "EHLO prdiron-3.llnl.gov" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751886Ab3CABF1 (ORCPT ); Thu, 28 Feb 2013 20:05:27 -0500 X-Attachments: Received: from eris.llnl.gov (HELO trebuchet.chaos) ([128.115.7.7]) by prdiron-3.llnl.gov with SMTP; 28 Feb 2013 17:05:27 -0800 Date: Thu, 28 Feb 2013 17:05:26 -0800 From: Ira Weiny To: "linux-rdma@vger.kernel.org" Cc: Hal Rosenstock Subject: [PATCH V4 02/07] opensm/perfmgr: clean up: break out redirect processing from pc_recv_process Message-Id: <20130228170526.97fbdd98d3dd8dd747dd5673@llnl.gov> X-Mailer: Sylpheed 3.3.0 (GTK+ 2.18.9; x86_64-unknown-linux-gnu) Mime-Version: 1.0 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org Changes from V1: Cleaned up processing when CPI redirect is invalid Changes from V2: cpi_valid should not be set to false when redirect is invalid If CPI is a redirection only set cpi_valid if the redirection was valid (Also set cpi_valid on all ports for a switch) Changes from V3: Reissue original query on redirect if query_cpi is not enabled Signed-off-by: Ira Weiny --- opensm/osm_perfmgr.c | 240 ++++++++++++++++++++++++------------------------- 1 files changed, 118 insertions(+), 122 deletions(-) diff --git a/opensm/osm_perfmgr.c b/opensm/osm_perfmgr.c index b19933e..b507408 100644 --- a/opensm/osm_perfmgr.c +++ b/opensm/osm_perfmgr.c @@ -1266,6 +1266,112 @@ Exit: return pkey_ix; } +static boolean_t handle_redirect(osm_perfmgr_t *pm, + ib_class_port_info_t *cpi, + monitored_node_t *p_mon_node, + uint8_t port, + osm_madw_context_t *mad_context) +{ + char gid_str[INET6_ADDRSTRLEN]; + ib_api_status_t status; + boolean_t valid = TRUE; + int16_t pkey_ix = 0; + uint8_t mad_method; + + OSM_LOG(pm->log, OSM_LOG_VERBOSE, + "Redirection to LID %u GID %s QP 0x%x received\n", + cl_ntoh16(cpi->redir_lid), + inet_ntop(AF_INET6, cpi->redir_gid.raw, gid_str, + sizeof gid_str), cl_ntoh32(cpi->redir_qp)); + + if (!pm->subn->opt.perfmgr_redir) { + OSM_LOG(pm->log, OSM_LOG_VERBOSE, + "Redirection requested but disabled\n"); + valid = FALSE; + } + + /* valid redirection ? */ + if (cpi->redir_lid == 0) { + if (!ib_gid_is_notzero(&cpi->redir_gid)) { + OSM_LOG(pm->log, OSM_LOG_VERBOSE, + "Invalid redirection " + "(both redirect LID and GID are zero)\n"); + valid = FALSE; + } + } + if (cpi->redir_qp == 0) { + OSM_LOG(pm->log, OSM_LOG_VERBOSE, "Invalid RedirectQP\n"); + valid = FALSE; + } + if (cpi->redir_pkey == 0) { + OSM_LOG(pm->log, OSM_LOG_VERBOSE, "Invalid RedirectP_Key\n"); + valid = FALSE; + } + if (cpi->redir_qkey != IB_QP1_WELL_KNOWN_Q_KEY) { + OSM_LOG(pm->log, OSM_LOG_VERBOSE, "Invalid RedirectQ_Key\n"); + valid = FALSE; + } + + pkey_ix = validate_redir_pkey(pm, cpi->redir_pkey); + if (pkey_ix == -1) { + OSM_LOG(pm->log, OSM_LOG_VERBOSE, + "Index for Pkey 0x%x not found\n", + cl_ntoh16(cpi->redir_pkey)); + valid = FALSE; + } + + if (cpi->redir_lid == 0) { + /* GID redirection: get PathRecord information */ + OSM_LOG(pm->log, OSM_LOG_VERBOSE, + "GID redirection not currently supported\n"); + goto Exit; + } + + if (!valid) + goto Exit; + + /* LID redirection support (easier than GID redirection) */ + cl_plock_acquire(&pm->osm->lock); + p_mon_node->port[port].redirection = TRUE; + p_mon_node->port[port].valid = valid; + memcpy(&p_mon_node->port[port].gid, &cpi->redir_gid, + sizeof(ib_gid_t)); + p_mon_node->port[port].lid = cpi->redir_lid; + p_mon_node->port[port].qp = cpi->redir_qp; + p_mon_node->port[port].pkey = cpi->redir_pkey; + if (pkey_ix != -1) + p_mon_node->port[port].pkey_ix = pkey_ix; + cl_plock_release(&pm->osm->lock); + + /* either */ + if (pm->query_cpi) + { + /* issue a CPI query to the redirected location */ + mad_method = IB_MAD_METHOD_GET; + p_mon_node->port[port].cpi_valid = FALSE; + status = perfmgr_send_cpi_mad(pm, cpi->redir_lid, + cpi->redir_qp, pkey_ix, + port, mad_context, + 0); /* FIXME SL != 0 */ + } else { + /* reissue the original query to the redirected location */ + mad_method = mad_context->perfmgr_context.mad_method; + status = perfmgr_send_pc_mad(pm, cpi->redir_lid, cpi->redir_qp, + pkey_ix, port, + mad_method, + mad_context, + 0); /* FIXME SL != 0 */ + } + if (status != IB_SUCCESS) + OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR 5414: " + "Failed to send redirected MAD " + "with method 0x%x for node %s " + "(NodeGuid 0x%" PRIx64 ") port %d\n", + mad_method, p_mon_node->name, p_mon_node->guid, port); +Exit: + return (valid); +} + /********************************************************************** * The dispatcher uses a thread pool which will call this function when * there is a thread available to process the mad received on the wire. @@ -1284,8 +1390,6 @@ static void pc_recv_process(void *context, void *data) perfmgr_db_data_cnt_reading_t data_reading; cl_map_item_t *p_node; monitored_node_t *p_mon_node; - int16_t pkey_ix = 0; - boolean_t valid = TRUE; ib_class_port_info_t *cpi = NULL; OSM_LOG_ENTER(pm->log); @@ -1323,10 +1427,17 @@ static void pc_recv_process(void *context, void *data) /* capture CLASS_PORT_INFO data */ if (p_mad->attr_id == IB_MAD_ATTR_CLASS_PORT_INFO) { + boolean_t cpi_valid = TRUE; + cpi = (ib_class_port_info_t *) & (osm_madw_get_perfmgt_mad_ptr(p_madw)->data); - if (pm->query_cpi) { + /* Response could be redirection (IBM eHCA PMA does this) */ + if (p_mad->status & IB_MAD_STATUS_REDIRECT) + cpi_valid = handle_redirect(pm, cpi, p_mon_node, port, + mad_context); + + if (pm->query_cpi && cpi_valid) { cl_plock_acquire(&pm->osm->lock); if (p_mon_node->node_type == IB_NODE_TYPE_SWITCH) { int i = 0; @@ -1334,133 +1445,17 @@ static void pc_recv_process(void *context, void *data) i < p_mon_node->num_ports; i++) { p_mon_node->port[i].cap_mask = cpi->cap_mask; - p_mon_node->port[i].cpi_valid = TRUE; + p_mon_node->port[i].cpi_valid = cpi_valid; } } else { p_mon_node->port[port].cap_mask = cpi->cap_mask; - p_mon_node->port[port].cpi_valid = TRUE; - } - cl_plock_release(&pm->osm->lock); - } - } - - /* Response could also be redirection (IBM eHCA PMA does this) */ - if (p_mad->status & IB_MAD_STATUS_REDIRECT) { - char gid_str[INET6_ADDRSTRLEN]; - ib_api_status_t status; - uint8_t mad_method; - - CL_ASSERT(cpi); /* Redirect should have returned CPI - (processed in previous block) */ - - OSM_LOG(pm->log, OSM_LOG_VERBOSE, - "Redirection to LID %u GID %s QP 0x%x received\n", - cl_ntoh16(cpi->redir_lid), - inet_ntop(AF_INET6, cpi->redir_gid.raw, gid_str, - sizeof gid_str), cl_ntoh32(cpi->redir_qp)); - - if (!pm->subn->opt.perfmgr_redir) { - OSM_LOG(pm->log, OSM_LOG_VERBOSE, - "Redirection requested but disabled\n"); - valid = FALSE; - } - - /* valid redirection ? */ - if (cpi->redir_lid == 0) { - if (!ib_gid_is_notzero(&cpi->redir_gid)) { - OSM_LOG(pm->log, OSM_LOG_VERBOSE, - "Invalid redirection " - "(both redirect LID and GID are zero)\n"); - valid = FALSE; + p_mon_node->port[port].cpi_valid = cpi_valid; } - } - if (cpi->redir_qp == 0) { - OSM_LOG(pm->log, OSM_LOG_VERBOSE, "Invalid RedirectQP\n"); - valid = FALSE; - } - if (cpi->redir_pkey == 0) { - OSM_LOG(pm->log, OSM_LOG_VERBOSE, "Invalid RedirectP_Key\n"); - valid = FALSE; - } - if (cpi->redir_qkey != IB_QP1_WELL_KNOWN_Q_KEY) { - OSM_LOG(pm->log, OSM_LOG_VERBOSE, "Invalid RedirectQ_Key\n"); - valid = FALSE; - } - - pkey_ix = validate_redir_pkey(pm, cpi->redir_pkey); - if (pkey_ix == -1) { - OSM_LOG(pm->log, OSM_LOG_VERBOSE, - "Index for Pkey 0x%x not found\n", - cl_ntoh16(cpi->redir_pkey)); - valid = FALSE; - } - - if (cpi->redir_lid == 0) { - /* GID redirection: get PathRecord information */ - OSM_LOG(pm->log, OSM_LOG_VERBOSE, - "GID redirection not currently supported\n"); - goto Exit; - } - - /* LID redirection support (easier than GID redirection) */ - cl_plock_acquire(&pm->osm->lock); - /* Now, validate port number */ - if (port >= p_mon_node->num_ports) { cl_plock_release(&pm->osm->lock); - OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR 5413: " - "Invalid port num %d for GUID 0x%016" - PRIx64 " num ports %d\n", port, node_guid, - p_mon_node->num_ports); - goto Exit; } - p_mon_node->port[port].redirection = TRUE; - p_mon_node->port[port].valid = valid; - memcpy(&p_mon_node->port[port].gid, &cpi->redir_gid, - sizeof(ib_gid_t)); - p_mon_node->port[port].lid = cpi->redir_lid; - p_mon_node->port[port].qp = cpi->redir_qp; - p_mon_node->port[port].pkey = cpi->redir_pkey; - if (pkey_ix != -1) - p_mon_node->port[port].pkey_ix = pkey_ix; - cl_plock_release(&pm->osm->lock); - - if (!valid) - goto Exit; - - /* either */ - if (pm->query_cpi) - { - /* issue a CPI query to the redirected location */ - mad_method = IB_MAD_METHOD_GET; - p_mon_node->port[port].cpi_valid = FALSE; - status = perfmgr_send_cpi_mad(pm, cpi->redir_lid, - cpi->redir_qp, pkey_ix, - port, mad_context, - 0); /* FIXME SL != 0 */ - } else { - /* reissue the original query to the redirected location */ - mad_method = mad_context->perfmgr_context.mad_method, - status = perfmgr_send_pc_mad(pm, cpi->redir_lid, cpi->redir_qp, - pkey_ix, port, - mad_method, - mad_context, - 0); /* FIXME SL != 0 */ - } - if (status != IB_SUCCESS) - OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR 5414: " - "Failed to send redirected MAD " - "with method 0x%x for node %s " - "(NodeGuid 0x%" PRIx64 ") port %d\n", - mad_method, p_mon_node->name, node_guid, port); goto Exit; } - /* ClassPortInfo needed to process optional Redirection - * now exit normally - */ - if (p_mad->attr_id == IB_MAD_ATTR_CLASS_PORT_INFO) - goto Exit; - perfmgr_db_fill_err_read(wire_read, &err_reading); /* FIXME separate query for extended counters if they are supported * on the port. @@ -1486,7 +1481,8 @@ static void pc_recv_process(void *context, void *data) perfmgr_db_clear_prev_dc(pm->db, node_guid, port); } - perfmgr_check_overflow(pm, p_mon_node, pkey_ix, port, wire_read); + perfmgr_check_overflow(pm, p_mon_node, p_mon_node->port[port].pkey_ix, + port, wire_read); #ifdef ENABLE_OSM_PERF_MGR_PROFILE do {