rdsib_ib.c revision 00d1d19828f3122eb24ae7a68175ba64744f8366
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 2N/A * Copyright (c) 2005 SilverStorm Technologies, Inc. All rights reserved. 2N/A * This software is available to you under a choice of one of two 2N/A * licenses. You may choose to be licensed under the terms of the GNU 2N/A * General Public License (GPL) Version 2, available from the file 2N/A * COPYING in the main directory of this source tree, or the 2N/A * OpenIB.org BSD license below: 2N/A * Redistribution and use in source and binary forms, with or 2N/A * without modification, are permitted provided that the following 2N/A * conditions are met: 2N/A * - Redistributions of source code must retain the above 2N/A * copyright notice, this list of conditions and the following 2N/A * - Redistributions in binary form must reproduce the above 2N/A * copyright notice, this list of conditions and the following 2N/A * disclaimer in the documentation and/or other materials 2N/A * provided with the distribution. 2N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2N/A * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2N/A * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2N/A * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 2N/A * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 2N/A * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2N/A * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * Sun elects to include this software in Sun product * under the OpenIB BSD license. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. /* performance tunables */ /* The SQ size should not be more than that supported by the HCA */ "than that supported by the HCA driver " "(%d + %d > %d or %d), lowering it to a supported value.",
/* The RQ size should not be more than that supported by the HCA */ RDS_DPRINTF2(
"RDSIB",
"MaxDataRecvBuffers is greater than that " "supported by the HCA driver (%d > %d or %d), lowering it " /* The SQ size should not be more than that supported by the HCA */ RDS_DPRINTF2(
"RDSIB",
"MaxCtrlSendBuffers is greater than that " "supported by the HCA driver (%d > %d or %d), lowering it " /* The RQ size should not be more than that supported by the HCA */ RDS_DPRINTF2(
"RDSIB",
"MaxCtrlRecvBuffers is greater than that " "supported by the HCA driver (%d > %d or %d), lowering it " /* The MaxRecvMemory should be less than that supported by the HCA */ "supported by the HCA driver (%d > %d), lowering it to %d",
/* Return hcap, given the hca guid */ * This can happen if we get IBT_HCA_ATTACH_EVENT on an HCA * that we have already opened. Just return NULL so that * we'll not end up reinitializing the HCA again. "ibt_open_hca: 0x%llx returned IBT_HCA_IN_USE",
"Query HCA 0x%llx ports failed: %d",
hca_guid,
/* Only one PD per HCA is allocated, so do it here */ /* To minimize stale connections after ungraceful reboots */ /* this is a new HCA, add it to the list */ "RDS Statep not initialized");
/* How many hcas are there? */ RDS_DPRINTF2(
"rdsib_initialize_ib",
"No IB HCAs Available");
RDS_DPRINTF2(
"rdsib_initialize_ib",
"ibt_attach failed: %d",
* Open each HCA and gather its information. Don't care about HCAs * that cannot be opened. It is OK as long as atleast one HCA can be * Initialize a HCA only if all the information is available. /* free the HCA list, we are done with it */ /* Failed to Initialize even one HCA */ RDS_DPRINTF2(
"rdsib_initialize_ib",
"No HCAs are initialized");
RDS_DPRINTF2(
"rdsib_open_ib",
"HCAs %d/%d failed to initialize",
/* close and destroy all the sessions */ /* Release all HCA resources */ RDS_DPRINTF2(
"rdsib_deinitialize_ib",
"HCA List: %p, NHCA: %d",
/* Deregister with IBTF */ * Called on open of first RDS socket /* Enable incoming connection requests */ "Service registration failed");
/* bind the service on all available ports */ "Bind service failed: %d",
ret);
* Called when all ports are closed. /* Disable incoming connection requests */ "ibt_unbind_all_services failed: %d\n",
ret);
"ibt_deregister_service failed: %d\n",
ret);
/* Return hcap, given the hca guid */ RDS_DPRINTF4(
"rds_get_hcap",
"rds_get_hcap: Enter: statep: 0x%p " * don't let anyone use this HCA until the RECV memory * is registered with this HCA /* Return hcap, given a gid */ RDS_DPRINTF4(
"rds_gid_to_hcap",
"Enter: statep: 0x%p gid: %llx:%llx",
* don't let anyone use this HCA until the RECV memory * is registered with this HCA "HCA (0x%p, 0x%llx) is not initialized",
"gid found in hcap: 0x%p",
hcap);
/* This is called from the send CQ handler */ * The previous ACK completed successfully, send the next one * if more messages were received after sending the last ACK /* send acknowledgement */ "EP(%p): ibt_post_send for acknowledgement " "failed: %d, SQ depth: %d",
/* ACKed all messages, no more to ACK */ "returned: IBT_CQ_EMPTY",
ep,
cq);
/* Receive completion failure */ "EP(%p) CQ(%p) BP(%p): WC Error Status: %d",
/* there is one less in the RQ */ /* Time to post more buffers into the RQ */ /* Post recv WRs into the RQ. Assumes the ep->refcnt is already incremented */ /* get the hcap for the HCA hosting this channel */ /* Make sure the session is still connected */ /* how many can be posted */ "EP(%p) Failed to post %d WRs",
ep,
npost);
* sometimes, the recv WRs can get consumed as soon as they are * posted. In that case, taskq thread to post more WRs to the RQ will * not be scheduled as the taskqpending flag is still set. "ddi_taskq_dispatch failed: %d",
ret);
"returned: IBT_CQ_EMPTY",
ep,
cq);
/* Receive completion failure */ "EP(%p) CQ(%p) BP(%p): WC Error Status: %d",
/* there is one less in the RQ */ /* Time to post more buffers into the RQ */ "sendport: %d recvport: %d npkts: %d pktno: %d",
ep->
ep_remip,
/* single pkt or last packet */ /* last packet of a segmented message */ /* intermediate packet */ "ibt_poll_cq returned: %d",
ep,
cq,
ret);
"ibt_poll_cq returned: IBT_CQ_EMPTY",
"EP(%p): WC ID: %p ERROR: %d",
ep,
"EP(%p): WC ID: %p ERROR: %d",
ep,
/* don't let anyone send anymore */ /* Make this the active end */ RDS_DPRINTF5(
"rds_poll_send_completions",
"Npolled: %d send_error: %d",
/* put the buffers to the pool */ /* wait until the RQ is empty */ "ibt_free_channel returned: %d",
ep,
ret);
"EP(%p) Channel is ALREADY FREE",
ep);
"EP(%p) - for sendcq, ibt_free_cq returned %d",
"EP(%p) SendCQ is ALREADY FREE",
ep);
"EP(%p) - for recvcq, ibt_free_cq returned %d",
"EP(%p) RecvCQ is ALREADY FREE",
ep);
/* Allocate resources for RC channel */ RDS_DPRINTF4(
"rds_ep_alloc_rc_channel",
"Enter: 0x%p port: %d",
/* Update the EP with the right IP address and HCA guid */ /* reset taskqpending flag here */ /* returned size is always greater than the requested size */ "ibt_enable_cq_notify failed: %d",
ret);
/* returned size is always greater than the requested size */ "ibt_enable_cq_notify failed: %d",
ret);
/* Chan private should contain the ep */ /* Return node guid given a port gid */ RDS_DPRINTF4(
"rds_gid_to_node_guid",
"Enter: gid: %llx:%llx",
RDS_DPRINTF4(
"rds_gid_to_node_guid",
"Return: Node guid: %llx",
/* If RDS service is not registered then no bind is needed */ "RDS Service is not registered, so no action needed");
* If the service was previously bound on this port and * if this port has changed state down and now up, we do not * need to bind the service again. The bind is expected to * persist across state changes. If the service was never bound * before then we bind it this time. /* bind RDS service on the port, pass statep as cm_private */ "Bind service for HCA: 0x%llx Port: %d " RDS_DPRINTF2(
"rds_handle_portup_event",
"Return: GUID: 0x%llx",
/* register the recv memory with this hca */ /* no memory to register */ * This should be a write lock as we don't want anyone to get access * to the hcap while we are modifing its contents /* Prevent initiating any new activity on this HCA */ * stop the outgoing traffic and close any active sessions on this hca. * Any pending messages in the SQ will be allowed to complete. * We are changing the session state in advance. This prevents * further messages to be posted to the SQ. We then * send a control message to the remote and tell it close "RDS_SESSION_STATE_PASSIVE_CLOSING",
sp);
* wait until the sendq is empty then tell the remote to * close this session. This enables for graceful shutdown of /* wait until all the sessions are off this HCA */ * if rdsib_close_ib was called before this, then that would have * unbound the service on all ports. In that case, the HCA structs * will contain stale bindhdls. Hence, we do not call unbind unless * the service is still registered. /* unbind RDS service on all ports on this HCA */ "Unbinding Service: port: %d, bindhdl: %p",
"ibt_deregister_mr failed: %d",
ret);
"ibt_free_pd failed: %d",
ret);
"ibt_close_hca failed: %d",
ret);
* This should be a write lock as we don't want anyone to get access * to the hcap while we are modifing its contents * NOTE: In some error recovery paths, it is possible to * receive IBT_HCA_ATTACH_EVENTs on already known HCAs. * This routine exists to minimize stale connections across ungraceful * reboots of nodes in a cluster. "ibt_alloc_cq failed: %d",
ret);
for (i = 0; i <
rand1 +
3; i++) {
for (j = 0; j <
rand2 +
3; j++) {
"Bailing at i: %d j: %d", i, j);