/* * Copyright (c) 2006, 2019 Oracle and/or its affiliates. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #include <linux/kernel.h> #include <linux/in.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/ratelimit.h> #include <net/addrconf.h> #include <rdma/ib_cm.h> #include "rds_single_path.h" #include "rds.h" #include "ib.h" #include "ib_mr.h" /* * Set the selected protocol version */ static void rds_ib_set_protocol(struct rds_connection *conn, unsigned int version) { … } /* * Set up flow control */ static void rds_ib_set_flow_control(struct rds_connection *conn, u32 credits) { … } /* * Connection established. * We get here for both outgoing and incoming connection. */ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_event *event) { … } static void rds_ib_cm_fill_conn_param(struct rds_connection *conn, struct rdma_conn_param *conn_param, union rds_ib_conn_priv *dp, u32 protocol_version, u32 max_responder_resources, u32 max_initiator_depth, bool isv6) { … } static void rds_ib_cq_event_handler(struct ib_event *event, void *data) { … } /* Plucking the oldest entry from the ring can be done concurrently with * the thread refilling the ring. Each ring operation is protected by * spinlocks and the transient state of refilling doesn't change the * recording of which entry is oldest. * * This relies on IB only calling one cq comp_handler for each cq so that * there will only be one caller of rds_recv_incoming() per RDS connection. */ static void rds_ib_cq_comp_handler_recv(struct ib_cq *cq, void *context) { … } static void poll_scq(struct rds_ib_connection *ic, struct ib_cq *cq, struct ib_wc *wcs) { … } static void rds_ib_tasklet_fn_send(unsigned long data) { … } static void poll_rcq(struct rds_ib_connection *ic, struct ib_cq *cq, struct ib_wc *wcs, struct rds_ib_ack_state *ack_state) { … } static void rds_ib_tasklet_fn_recv(unsigned long data) { … } static void rds_ib_qp_event_handler(struct ib_event *event, void *data) { … } static void rds_ib_cq_comp_handler_send(struct ib_cq *cq, void *context) { … } static inline int ibdev_get_unused_vector(struct rds_ib_device *rds_ibdev) { … } static inline void ibdev_put_vector(struct rds_ib_device *rds_ibdev, int index) { … } static void rds_dma_hdr_free(struct ib_device *dev, struct rds_header *hdr, dma_addr_t dma_addr, enum dma_data_direction dir) { … } static struct rds_header *rds_dma_hdr_alloc(struct ib_device *dev, dma_addr_t *dma_addr, enum dma_data_direction dir) { … } /* Free the DMA memory used to store struct rds_header. * * @dev: the RDS IB device * @hdrs: pointer to the array storing DMA memory pointers * @dma_addrs: pointer to the array storing DMA addresses * @num_hdars: number of headers to free. */ static void rds_dma_hdrs_free(struct rds_ib_device *dev, struct rds_header **hdrs, dma_addr_t *dma_addrs, u32 num_hdrs, enum dma_data_direction dir) { … } /* Allocate DMA coherent memory to be used to store struct rds_header for * sending/receiving packets. The pointers to the DMA memory and the * associated DMA addresses are stored in two arrays. * * @dev: the RDS IB device * @dma_addrs: pointer to the array for storing DMA addresses * @num_hdrs: number of headers to allocate * * It returns the pointer to the array storing the DMA memory pointers. On * error, NULL pointer is returned. */ static struct rds_header **rds_dma_hdrs_alloc(struct rds_ib_device *dev, dma_addr_t **dma_addrs, u32 num_hdrs, enum dma_data_direction dir) { … } /* * This needs to be very careful to not leave IS_ERR pointers around for * cleanup to trip over. */ static int rds_ib_setup_qp(struct rds_connection *conn) { … } static u32 rds_ib_protocol_compatible(struct rdma_cm_event *event, bool isv6) { … } #if IS_ENABLED(CONFIG_IPV6) /* Given an IPv6 address, find the net_device which hosts that address and * return its index. This is used by the rds_ib_cm_handle_connect() code to * find the interface index of where an incoming request comes from when * the request is using a link local address. * * Note one problem in this search. It is possible that two interfaces have * the same link local address. Unfortunately, this cannot be solved unless * the underlying layer gives us the interface which an incoming RDMA connect * request comes from. */ static u32 __rds_find_ifindex(struct net *net, const struct in6_addr *addr) { … } #endif int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, struct rdma_cm_event *event, bool isv6) { … } int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id, bool isv6) { … } int rds_ib_conn_path_connect(struct rds_conn_path *cp) { … } /* * This is so careful about only cleaning up resources that were built up * so that it can be called at any point during startup. In fact it * can be called multiple times for a given connection. */ void rds_ib_conn_path_shutdown(struct rds_conn_path *cp) { … } int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp) { … } /* * Free a connection. Connection must be shut down and not set for reconnect. */ void rds_ib_conn_free(void *arg) { … } /* * An error occurred on the connection */ void __rds_ib_conn_error(struct rds_connection *conn, const char *fmt, ...) { … }