^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This software is available to you under a choice of one of two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * licenses. You may choose to be licensed under the terms of the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * General Public License (GPL) Version 2, available from the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * COPYING in the main directory of this source tree, or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * OpenIB.org BSD license below:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Redistribution and use in source and binary forms, with or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * without modification, are permitted provided that the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * conditions are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * - Redistributions of source code must retain the above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * copyright notice, this list of conditions and the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * - Redistributions in binary form must reproduce the above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * copyright notice, this list of conditions and the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * disclaimer in the documentation and/or other materials
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "rds.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * All of connection management is simplified by serializing it through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * work queues that execute in a connection managing thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * TCP wants to send acks through sendpage() in response to data_ready(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * but it needs a process context to do so.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * The receive paths need to allocate but can't drop packets (!) so we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * a thread around to block allocating if the receive fast path sees an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * allocation failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* Grand Unified Theory of connection life cycle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * At any point in time, the connection can be in one of these states:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * DOWN, CONNECTING, UP, DISCONNECTING, ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * The following transitions are possible:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * ANY -> ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * UP -> DISCONNECTING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * ERROR -> DISCONNECTING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * DISCONNECTING -> DOWN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * DOWN -> CONNECTING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * CONNECTING -> UP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Transition to state DISCONNECTING/DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * - Inside the shutdown worker; synchronizes with xmit path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * through RDS_IN_XMIT, and with connection management callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * via c_cm_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * For receive callbacks, we rely on the underlying transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * (TCP, IB/RDMA) to provide the necessary synchronisation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct workqueue_struct *rds_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) EXPORT_SYMBOL_GPL(rds_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) void rds_connect_path_complete(struct rds_conn_path *cp, int curr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (!rds_conn_path_transition(cp, curr, RDS_CONN_UP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) printk(KERN_WARNING "%s: Cannot transition to state UP, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) "current state is %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) atomic_read(&cp->cp_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) rds_conn_path_drop(cp, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) rdsdebug("conn %p for %pI6c to %pI6c complete\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) cp->cp_conn, &cp->cp_conn->c_laddr, &cp->cp_conn->c_faddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) cp->cp_reconnect_jiffies = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) set_bit(0, &cp->cp_conn->c_map_queued);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (!rds_destroy_pending(cp->cp_conn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) queue_delayed_work(rds_wq, &cp->cp_send_w, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) queue_delayed_work(rds_wq, &cp->cp_recv_w, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) cp->cp_conn->c_proposed_version = RDS_PROTOCOL_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) EXPORT_SYMBOL_GPL(rds_connect_path_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void rds_connect_complete(struct rds_connection *conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) rds_connect_path_complete(&conn->c_path[0], RDS_CONN_CONNECTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) EXPORT_SYMBOL_GPL(rds_connect_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * This random exponential backoff is relied on to eventually resolve racing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * connects.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * If connect attempts race then both parties drop both connections and come
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * here to wait for a random amount of time before trying again. Eventually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * the backoff range will be so much greater than the time it takes to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * establish a connection that one of the pair will establish the connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * before the other's random delay fires.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * Connection attempts that arrive while a connection is already established
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * are also considered to be racing connects. This lets a connection from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * a rebooted machine replace an existing stale connection before the transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * notices that the connection has failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * We should *always* start with a random backoff; otherwise a broken connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * will always take several iterations to be re-established.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) void rds_queue_reconnect(struct rds_conn_path *cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned long rand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct rds_connection *conn = cp->cp_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) rdsdebug("conn %p for %pI6c to %pI6c reconnect jiffies %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) conn, &conn->c_laddr, &conn->c_faddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) cp->cp_reconnect_jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* let peer with smaller addr initiate reconnect, to avoid duels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (conn->c_trans->t_type == RDS_TRANS_TCP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) rds_addr_cmp(&conn->c_laddr, &conn->c_faddr) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) set_bit(RDS_RECONNECT_PENDING, &cp->cp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (cp->cp_reconnect_jiffies == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) cp->cp_reconnect_jiffies = rds_sysctl_reconnect_min_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (!rds_destroy_pending(cp->cp_conn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) queue_delayed_work(rds_wq, &cp->cp_conn_w, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) get_random_bytes(&rand, sizeof(rand));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) rdsdebug("%lu delay %lu ceil conn %p for %pI6c -> %pI6c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) rand % cp->cp_reconnect_jiffies, cp->cp_reconnect_jiffies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) conn, &conn->c_laddr, &conn->c_faddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (!rds_destroy_pending(cp->cp_conn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) queue_delayed_work(rds_wq, &cp->cp_conn_w,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) rand % cp->cp_reconnect_jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) cp->cp_reconnect_jiffies = min(cp->cp_reconnect_jiffies * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) rds_sysctl_reconnect_max_jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) void rds_connect_worker(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct rds_conn_path *cp = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct rds_conn_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) cp_conn_w.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct rds_connection *conn = cp->cp_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (cp->cp_index > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) rds_addr_cmp(&cp->cp_conn->c_laddr, &cp->cp_conn->c_faddr) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) clear_bit(RDS_RECONNECT_PENDING, &cp->cp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ret = rds_conn_path_transition(cp, RDS_CONN_DOWN, RDS_CONN_CONNECTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ret = conn->c_trans->conn_path_connect(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) rdsdebug("conn %p for %pI6c to %pI6c dispatched, ret %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) conn, &conn->c_laddr, &conn->c_faddr, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (rds_conn_path_transition(cp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) RDS_CONN_CONNECTING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) RDS_CONN_DOWN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) rds_queue_reconnect(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) rds_conn_path_error(cp, "connect failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) void rds_send_worker(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct rds_conn_path *cp = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct rds_conn_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) cp_send_w.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (rds_conn_path_state(cp) == RDS_CONN_UP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) clear_bit(RDS_LL_SEND_FULL, &cp->cp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ret = rds_send_xmit(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) rdsdebug("conn %p ret %d\n", cp->cp_conn, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case -EAGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) rds_stats_inc(s_send_immediate_retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) queue_delayed_work(rds_wq, &cp->cp_send_w, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case -ENOMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) rds_stats_inc(s_send_delayed_retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) queue_delayed_work(rds_wq, &cp->cp_send_w, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) void rds_recv_worker(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct rds_conn_path *cp = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct rds_conn_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) cp_recv_w.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (rds_conn_path_state(cp) == RDS_CONN_UP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = cp->cp_conn->c_trans->recv_path(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) rdsdebug("conn %p ret %d\n", cp->cp_conn, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case -EAGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) rds_stats_inc(s_recv_immediate_retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) queue_delayed_work(rds_wq, &cp->cp_recv_w, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) case -ENOMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) rds_stats_inc(s_recv_delayed_retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) queue_delayed_work(rds_wq, &cp->cp_recv_w, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) void rds_shutdown_worker(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct rds_conn_path *cp = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct rds_conn_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) cp_down_w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) rds_conn_shutdown(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) void rds_threads_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) destroy_workqueue(rds_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int rds_threads_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) rds_wq = create_singlethread_workqueue("krdsd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (!rds_wq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* Compare two IPv6 addresses. Return 0 if the two addresses are equal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * Return 1 if the first is greater. Return -1 if the second is greater.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int rds_addr_cmp(const struct in6_addr *addr1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) const struct in6_addr *addr2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) const __be64 *a1, *a2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) u64 x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) a1 = (__be64 *)addr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) a2 = (__be64 *)addr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (*a1 != *a2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (be64_to_cpu(*a1) < be64_to_cpu(*a2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) x = be64_to_cpu(*++a1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) y = be64_to_cpu(*++a2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (x < y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) else if (x > y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u32 a, b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (addr1->s6_addr32[i] != addr2->s6_addr32[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) a = ntohl(addr1->s6_addr32[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) b = ntohl(addr2->s6_addr32[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (a < b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) else if (a > b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) EXPORT_SYMBOL_GPL(rds_addr_cmp);