c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota */
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota/*
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri * This file contains code imported from the OFED rds source file
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri * rdma_transport.c * Oracle elects to have and use the contents of
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri * rdma_transport.c under and governed by the OpenIB.org BSD license
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri * (see below for full license text). However, the following notice
16e76cdd6e3cfaac7d91c3b0644ee1bc6cf52347agiri * accompanied the original version of this file:
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) {
6e18d381c642549b8bb1774a803d3510aec6baafagiri RDSV3_DPRINTF2("rdsv3_rdma_cm_event_handler",
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota "RDS/RDMA: DISCONNECT event - dropping connection "
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji 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? */
6e18d381c642549b8bb1774a803d3510aec6baafagiri RDSV3_DPRINTF2("rdsv3_rdma_cm_event_handler",
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota "unknown event %u!\n", event->event);
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota RDSV3_PANIC();
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota break;
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota }
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Otaout:
cadbfdc3bdb156e92d7a88978bc98ea87f6e037fEiji Ota if (conn)
c0dd49bdd68c0d758a67d56f07826f3b45cfc664Eiji Ota mutex_exit(&conn->c_cm_lock);
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);
6e18d381c642549b8bb1774a803d3510aec6baafagiri RDSV3_DPRINTF2("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) {
6e18d381c642549b8bb1774a803d3510aec6baafagiri RDSV3_DPRINTF2("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) {
6e18d381c642549b8bb1774a803d3510aec6baafagiri RDSV3_DPRINTF2("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 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) {
3f756f37bfdcab561a4d84fb80f41f1e1a15c135agiri RDSV3_DPRINTF5("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}