rdma_transport.c revision c0dd49bdd68c0d758a67d56f07826f3b45cfc664
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * CDDL HEADER START
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * The contents of this file are subject to the terms of the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Common Development and Distribution License (the "License").
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * You may not use this file except in compliance with the License.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * or http://www.opensolaris.org/os/licensing.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * See the License for the specific language governing permissions
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * and limitations under the License.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * When distributing Covered Code, include this CDDL HEADER in each
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * If applicable, add the following below this CDDL HEADER, with the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * fields enclosed by brackets "[]" replaced with your own identifying
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * information: Portions Copyright [yyyy] [name of copyright owner]
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * CDDL HEADER END
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Copyright (c) 2009 Oracle. All rights reserved.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * This software is available to you under a choice of one of two
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * licenses. You may choose to be licensed under the terms of the GNU
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * General Public License (GPL) Version 2, available from the file
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * COPYING in the main directory of this source tree, or the
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * OpenIB.org BSD license below:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Redistribution and use in source and binary forms, with or
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * without modification, are permitted provided that the following
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * conditions are met:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * - Redistributions of source code must retain the above
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * copyright notice, this list of conditions and the following
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * disclaimer.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * - Redistributions in binary form must reproduce the above
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * copyright notice, this list of conditions and the following
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * disclaimer in the documentation and/or other materials
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * provided with the distribution.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * SOFTWARE.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota *
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ib/clients/of/rdma/ib_verbs.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ib/clients/of/rdma/ib_addr.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ib/clients/of/rdma/rdma_cm.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ib/clients/rdsv3/ib.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ib/clients/rdsv3/rdma_transport.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#include <sys/ib/clients/rdsv3/rdsv3_debug.h>
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otakmutex_t rdsv3_rdma_listen_id_lock;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastruct rdma_cm_id *rdsv3_rdma_listen_id = NULL;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaint
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdma_cm_event *event)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* this can be null in the listening path */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdsv3_connection *conn = cm_id->context;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdsv3_transport *trans;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota int ret = 0;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_cm_event_handler",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "conn %p id %p handling event %u", conn, cm_id, event->event);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota trans = &rdsv3_ib_transport;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Prevent shutdown from tearing down the connection
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * while we're executing.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (conn) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_enter(&conn->c_cm_lock);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * If the connection is being shut down, bail out
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * right away. We return 0 so cm_id doesn't get
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * destroyed prematurely
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_conn_state(conn) == RDSV3_CONN_DISCONNECTING) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * Reject incoming connections while we're tearing
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * down an existing one.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = 1;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_cm_event_handler",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "conn %p id %p incoming event %u when "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "disconnecting", conn, cm_id, event->event);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto out;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota switch (event->event) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_CONNECT_REQUEST:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = trans->cm_handle_connect(cm_id, event);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_ADDR_RESOLVED:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* XXX do we need to clean up if this fails? */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = rdma_resolve_route(cm_id,
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_RDMA_RESOLVE_TIMEOUT_MS);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_ROUTE_RESOLVED:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* XXX worry about racing with listen acceptance */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = trans->cm_initiate_connect(cm_id);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_ESTABLISHED:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota trans->cm_connect_complete(conn, event);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_ADDR_ERROR:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_ROUTE_ERROR:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_CONNECT_ERROR:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_UNREACHABLE:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_REJECTED:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_DEVICE_REMOVAL:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_ADDR_CHANGE:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (conn)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_conn_drop(conn);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota case RDMA_CM_EVENT_DISCONNECTED:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_cm_event_handler",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "RDS/RDMA: DISCONNECT event - dropping connection "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "cm_id: %p", cm_id);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (conn) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF0("rdsv3_rdma_cm_event_handler",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "RDS/RDMA: DISCONNECT event - dropping connection "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "%u.%u.%u.%u ->%u.%u.%u.%u", NIPQUAD(conn->c_laddr),
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota NIPQUAD(conn->c_faddr));
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_conn_drop(conn);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota default:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* things like device disconnect? */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF0("rdsv3_rdma_cm_event_handler",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "unknown event %u\n", event->event);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_PANIC();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaout:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (conn) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#ifndef __lock_lint
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota // struct rds_iw_connection *ic = conn->c_transport_data;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* If we return non-zero, we must to hang on to the cm_id */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota // BUG_ON(ic->i_cm_id == cm_id && ret);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota#endif
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_exit(&conn->c_cm_lock);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_cm_event_handler",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "id %p event %u handling ret %d", cm_id, event->event, ret);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return (ret);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic int
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_rdma_listen_init(void)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct sockaddr_in sin;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota struct rdma_cm_id *cm_id;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota int ret;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_listen_init", "Enter");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cm_id = rdma_create_id(rdsv3_rdma_cm_event_handler, NULL, RDMA_PS_TCP);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (IS_ERR(cm_id)) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = PTR_ERR(cm_id);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF0("rdsv3_rdma_listen_init",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "RDS/RDMA: failed to setup listener, "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "rdma_create_id() returned %d", ret);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto out;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota sin.sin_family = PF_INET;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota sin.sin_addr.s_addr = (uint32_t)htonl(INADDR_ANY);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota sin.sin_port = (uint16_t)htons(RDSV3_PORT);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * XXX I bet this binds the cm_id to a device. If we want to support
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * fail-over we'll have to take this into consideration.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (ret) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF0("rdsv3_rdma_listen_init",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "RDS/RDMA: failed to setup listener, "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "rdma_bind_addr() returned %d", ret);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto out;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = rdma_listen(cm_id, 128);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (ret) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF0("rdsv3_rdma_listen_init",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "RDS/RDMA: failed to setup listener, "
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "rdma_listen() returned %d", ret);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota goto out;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF5("rdsv3_rdma_listen_init",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "cm %p listening on port %u", cm_id, RDSV3_PORT);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_rdma_listen_id = cm_id;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota cm_id = NULL;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_listen_init",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "Return: rdsv3_rdma_listen_id: %p", rdsv3_rdma_listen_id);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaout:
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (cm_id)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdma_destroy_id(cm_id);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return (ret);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otastatic void rdsv3_rdma_listen_stop(void)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_listen_stop", "cm %p", rdsv3_rdma_listen_id);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdma_destroy_id(rdsv3_rdma_listen_id);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_listen_stop", "Return");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * This function can be called via two routes.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * 1. During attach on a worker thread.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota * 2. From rdsv3_create() for 1st socket.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_rdma_init()
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota int ret;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_init", "Enter");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_enter(&rdsv3_rdma_listen_id_lock);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_rdma_listen_id != NULL) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_init",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "rdsv3_rdma_listen_id is already initialized: %p",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_rdma_listen_id);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_exit(&rdsv3_rdma_listen_id_lock);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = rdsv3_rdma_listen_init();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (ret) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_exit(&rdsv3_rdma_listen_id_lock);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota return;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota ret = rdsv3_ib_init();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (ret) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_rdma_listen_stop();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_exit(&rdsv3_rdma_listen_id_lock);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_init", "Return");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*ARGSUSED*/
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otavoid
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otardsv3_rdma_exit(void *arg)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota{
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_exit", "Enter");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota /* stop listening first to ensure no new connections are attempted */
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota if (rdsv3_rdma_listen_id) {
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_rdma_listen_stop();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_ib_exit();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota rdsv3_rdma_listen_id = NULL;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_DPRINTF2("rdsv3_rdma_exit", "Return");
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota}