Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * RDMA Transport Layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (c) 2014 - 2018 ProfitBricks GmbH. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (c) 2018 - 2019 1&1 IONOS Cloud GmbH. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Copyright (c) 2019 - 2020 1&1 IONOS SE. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #undef pr_fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include "rtrs-clt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include "rtrs-log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #define RTRS_CONNECT_TIMEOUT_MS 30000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  * Wait a bit before trying to reconnect after a failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  * in order to give server time to finish clean up which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  * leads to "false positives" failed reconnect attempts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #define RTRS_RECONNECT_BACKOFF 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  * Wait for additional random time between 0 and 8 seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  * before starting to reconnect to avoid clients reconnecting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  * all at once in case of a major network outage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define RTRS_RECONNECT_SEED 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define FIRST_CONN 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) MODULE_DESCRIPTION("RDMA Transport Client");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) static const struct rtrs_rdma_dev_pd_ops dev_pd_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) static struct rtrs_rdma_dev_pd dev_pd = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	.ops = &dev_pd_ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) static struct workqueue_struct *rtrs_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) static struct class *rtrs_clt_dev_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) static inline bool rtrs_clt_is_connected(const struct rtrs_clt *clt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	struct rtrs_clt_sess *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	bool connected = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	list_for_each_entry_rcu(sess, &clt->paths_list, s.entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 		connected |= READ_ONCE(sess->state) == RTRS_CLT_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	return connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) static struct rtrs_permit *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) __rtrs_get_permit(struct rtrs_clt *clt, enum rtrs_clt_con_type con_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	size_t max_depth = clt->queue_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	struct rtrs_permit *permit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	int bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	 * Adapted from null_blk get_tag(). Callers from different cpus may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	 * grab the same bit, since find_first_zero_bit is not atomic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	 * But then the test_and_set_bit_lock will fail for all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	 * callers but one, so that they will loop again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	 * This way an explicit spinlock is not required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 		bit = find_first_zero_bit(clt->permits_map, max_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 		if (unlikely(bit >= max_depth))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	} while (unlikely(test_and_set_bit_lock(bit, clt->permits_map)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	permit = get_permit(clt, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	WARN_ON(permit->mem_id != bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	permit->cpu_id = raw_smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	permit->con_type = con_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	return permit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) static inline void __rtrs_put_permit(struct rtrs_clt *clt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 				      struct rtrs_permit *permit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	clear_bit_unlock(permit->mem_id, clt->permits_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95)  * rtrs_clt_get_permit() - allocates permit for future RDMA operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96)  * @clt:	Current session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97)  * @con_type:	Type of connection to use with the permit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98)  * @can_wait:	Wait type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)  *    Allocates permit for the following RDMA operation.  Permit is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102)  *    to preallocate all resources and to propagate memory pressure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)  *    up earlier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)  *    Can sleep if @wait == RTRS_TAG_WAIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) struct rtrs_permit *rtrs_clt_get_permit(struct rtrs_clt *clt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 					  enum rtrs_clt_con_type con_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 					  int can_wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	struct rtrs_permit *permit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	DEFINE_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	permit = __rtrs_get_permit(clt, con_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	if (likely(permit) || !can_wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		return permit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 		prepare_to_wait(&clt->permits_wait, &wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 				TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 		permit = __rtrs_get_permit(clt, con_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		if (likely(permit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		io_schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	} while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	finish_wait(&clt->permits_wait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	return permit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) EXPORT_SYMBOL(rtrs_clt_get_permit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136)  * rtrs_clt_put_permit() - puts allocated permit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137)  * @clt:	Current session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138)  * @permit:	Permit to be freed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141)  *    Does not matter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) void rtrs_clt_put_permit(struct rtrs_clt *clt, struct rtrs_permit *permit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	if (WARN_ON(!test_bit(permit->mem_id, clt->permits_map)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	__rtrs_put_permit(clt, permit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	 * rtrs_clt_get_permit() adds itself to the &clt->permits_wait list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	 * before calling schedule(). So if rtrs_clt_get_permit() is sleeping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	 * it must have added itself to &clt->permits_wait before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	 * __rtrs_put_permit() finished.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	 * Hence it is safe to guard wake_up() with a waitqueue_active() test.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	if (waitqueue_active(&clt->permits_wait))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 		wake_up(&clt->permits_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) EXPORT_SYMBOL(rtrs_clt_put_permit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) void *rtrs_permit_to_pdu(struct rtrs_permit *permit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	return permit + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) EXPORT_SYMBOL(rtrs_permit_to_pdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  * rtrs_permit_to_clt_con() - returns RDMA connection pointer by the permit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  * @sess: client session pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)  * @permit: permit for the allocation of the RDMA buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172)  * Note:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173)  *     IO connection starts from 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174)  *     0 connection is for user messages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) struct rtrs_clt_con *rtrs_permit_to_clt_con(struct rtrs_clt_sess *sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 					    struct rtrs_permit *permit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	int id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	if (likely(permit->con_type == RTRS_IO_CON))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		id = (permit->cpu_id % (sess->s.con_num - 1)) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	return to_clt_con(sess->s.con[id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) }
^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)  * __rtrs_clt_change_state() - change the session state through session state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)  * machine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192)  * @sess: client session to change the state of.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)  * @new_state: state to change to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195)  * returns true if successful, false if the requested state can not be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197)  * Locks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198)  * state_wq lock must be hold.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) static bool __rtrs_clt_change_state(struct rtrs_clt_sess *sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 				     enum rtrs_clt_state new_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	enum rtrs_clt_state old_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	lockdep_assert_held(&sess->state_wq.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	old_state = sess->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	switch (new_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	case RTRS_CLT_CONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		switch (old_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		case RTRS_CLT_RECONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 			changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	case RTRS_CLT_RECONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		switch (old_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		case RTRS_CLT_CONNECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		case RTRS_CLT_CONNECTING_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		case RTRS_CLT_CLOSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 			changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	case RTRS_CLT_CONNECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		switch (old_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		case RTRS_CLT_CONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 			changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 			fallthrough;
^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) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	case RTRS_CLT_CONNECTING_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		switch (old_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		case RTRS_CLT_CONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 			changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	case RTRS_CLT_CLOSING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		switch (old_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		case RTRS_CLT_CONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		case RTRS_CLT_CONNECTING_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		case RTRS_CLT_RECONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		case RTRS_CLT_CONNECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 			changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	case RTRS_CLT_CLOSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		switch (old_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		case RTRS_CLT_CLOSING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 			changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	case RTRS_CLT_DEAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		switch (old_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		case RTRS_CLT_CLOSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 			changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		sess->state = new_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		wake_up_locked(&sess->state_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) static bool rtrs_clt_change_state_from_to(struct rtrs_clt_sess *sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 					   enum rtrs_clt_state old_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 					   enum rtrs_clt_state new_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	spin_lock_irq(&sess->state_wq.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	if (sess->state == old_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		changed = __rtrs_clt_change_state(sess, new_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	spin_unlock_irq(&sess->state_wq.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) static void rtrs_rdma_error_recovery(struct rtrs_clt_con *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	if (rtrs_clt_change_state_from_to(sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 					   RTRS_CLT_CONNECTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 					   RTRS_CLT_RECONNECTING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		struct rtrs_clt *clt = sess->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		unsigned int delay_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		 * Normal scenario, reconnect if we were successfully connected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		delay_ms = clt->reconnect_delay_sec * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		queue_delayed_work(rtrs_wq, &sess->reconnect_dwork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 				   msecs_to_jiffies(delay_ms +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 						    prandom_u32() % RTRS_RECONNECT_SEED));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		 * Error can happen just on establishing new connection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		 * so notify waiter with error state, waiter is responsible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		 * for cleaning the rest and reconnect if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		rtrs_clt_change_state_from_to(sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 					       RTRS_CLT_CONNECTING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 					       RTRS_CLT_CONNECTING_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) static void rtrs_clt_fast_reg_done(struct ib_cq *cq, struct ib_wc *wc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	struct rtrs_clt_con *con = cq->cq_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		rtrs_err(con->c.sess, "Failed IB_WR_REG_MR: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 			  ib_wc_status_msg(wc->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		rtrs_rdma_error_recovery(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) static struct ib_cqe fast_reg_cqe = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	.done = rtrs_clt_fast_reg_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) static void complete_rdma_req(struct rtrs_clt_io_req *req, int errno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 			      bool notify, bool can_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) static void rtrs_clt_inv_rkey_done(struct ib_cq *cq, struct ib_wc *wc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	struct rtrs_clt_io_req *req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		container_of(wc->wr_cqe, typeof(*req), inv_cqe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	struct rtrs_clt_con *con = cq->cq_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		rtrs_err(con->c.sess, "Failed IB_WR_LOCAL_INV: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 			  ib_wc_status_msg(wc->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		rtrs_rdma_error_recovery(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	req->need_inv = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	if (likely(req->need_inv_comp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		complete(&req->inv_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		/* Complete request from INV callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		complete_rdma_req(req, req->inv_errno, true, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) static int rtrs_inv_rkey(struct rtrs_clt_io_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	struct rtrs_clt_con *con = req->con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	struct ib_send_wr wr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 		.opcode		    = IB_WR_LOCAL_INV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		.wr_cqe		    = &req->inv_cqe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		.send_flags	    = IB_SEND_SIGNALED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		.ex.invalidate_rkey = req->mr->rkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	req->inv_cqe.done = rtrs_clt_inv_rkey_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	return ib_post_send(con->c.qp, &wr, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) static void complete_rdma_req(struct rtrs_clt_io_req *req, int errno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 			      bool notify, bool can_wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	struct rtrs_clt_con *con = req->con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	struct rtrs_clt_sess *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	if (WARN_ON(!req->in_use))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	if (WARN_ON(!req->con))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	if (req->sg_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		if (unlikely(req->dir == DMA_FROM_DEVICE && req->need_inv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 			 * We are here to invalidate read requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 			 * ourselves.  In normal scenario server should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 			 * send INV for all read requests, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 			 * we are here, thus two things could happen:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 			 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 			 *    1.  this is failover, when errno != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 			 *        and can_wait == 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 			 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			 *    2.  something totally bad happened and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			 *        server forgot to send INV, so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			 *        should do that ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 			if (likely(can_wait)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 				req->need_inv_comp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 				/* This should be IO path, so always notify */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 				WARN_ON(!notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 				/* Save errno for INV callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 				req->inv_errno = errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 			err = rtrs_inv_rkey(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 			if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 				rtrs_err(con->c.sess, "Send INV WR key=%#x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 					  req->mr->rkey, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 			} else if (likely(can_wait)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 				wait_for_completion(&req->inv_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 				 * Something went wrong, so request will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 				 * completed from INV callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 				WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		ib_dma_unmap_sg(sess->s.dev->ib_dev, req->sglist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 				req->sg_cnt, req->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	if (sess->clt->mp_policy == MP_POLICY_MIN_INFLIGHT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		atomic_dec(&sess->stats->inflight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	req->in_use = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	req->con = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	if (notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		req->conf(req->priv, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) static int rtrs_post_send_rdma(struct rtrs_clt_con *con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 				struct rtrs_clt_io_req *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 				struct rtrs_rbuf *rbuf, u32 off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 				u32 imm, struct ib_send_wr *wr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	enum ib_send_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	struct ib_sge sge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	if (unlikely(!req->sg_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		rtrs_wrn(con->c.sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 			 "Doing RDMA Write failed, no data supplied\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	/* user data and user message in the first list element */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	sge.addr   = req->iu->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	sge.length = req->sg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	sge.lkey   = sess->s.dev->ib_pd->local_dma_lkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	 * From time to time we have to post signalled sends,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	 * or send queue will fill up and only QP reset can help.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	flags = atomic_inc_return(&con->io_cnt) % sess->queue_depth ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 			0 : IB_SEND_SIGNALED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	ib_dma_sync_single_for_device(sess->s.dev->ib_dev, req->iu->dma_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 				      req->sg_size, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	return rtrs_iu_post_rdma_write_imm(&con->c, req->iu, &sge, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 					    rbuf->rkey, rbuf->addr + off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 					    imm, flags, wr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) static void process_io_rsp(struct rtrs_clt_sess *sess, u32 msg_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 			   s16 errno, bool w_inval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	struct rtrs_clt_io_req *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	if (WARN_ON(msg_id >= sess->queue_depth))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	req = &sess->reqs[msg_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	/* Drop need_inv if server responded with send with invalidation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	req->need_inv &= !w_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	complete_rdma_req(req, errno, true, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) static void rtrs_clt_recv_done(struct rtrs_clt_con *con, struct ib_wc *wc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	struct rtrs_iu *iu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	WARN_ON((sess->flags & RTRS_MSG_NEW_RKEY_F) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	iu = container_of(wc->wr_cqe, struct rtrs_iu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 			  cqe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	err = rtrs_iu_post_recv(&con->c, iu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		rtrs_err(con->c.sess, "post iu failed %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		rtrs_rdma_error_recovery(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) static void rtrs_clt_rkey_rsp_done(struct rtrs_clt_con *con, struct ib_wc *wc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	struct rtrs_msg_rkey_rsp *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	u32 imm_type, imm_payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	bool w_inval = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	struct rtrs_iu *iu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	u32 buf_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	WARN_ON((sess->flags & RTRS_MSG_NEW_RKEY_F) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	if (unlikely(wc->byte_len < sizeof(*msg))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		rtrs_err(con->c.sess, "rkey response is malformed: size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 			  wc->byte_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	ib_dma_sync_single_for_cpu(sess->s.dev->ib_dev, iu->dma_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 				   iu->size, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	msg = iu->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	if (unlikely(le16_to_cpu(msg->type) != RTRS_MSG_RKEY_RSP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		rtrs_err(sess->clt, "rkey response is malformed: type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 			  le16_to_cpu(msg->type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	buf_id = le16_to_cpu(msg->buf_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	if (WARN_ON(buf_id >= sess->queue_depth))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	rtrs_from_imm(be32_to_cpu(wc->ex.imm_data), &imm_type, &imm_payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	if (likely(imm_type == RTRS_IO_RSP_IMM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		   imm_type == RTRS_IO_RSP_W_INV_IMM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		u32 msg_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		w_inval = (imm_type == RTRS_IO_RSP_W_INV_IMM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		rtrs_from_io_rsp_imm(imm_payload, &msg_id, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		if (WARN_ON(buf_id != msg_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		sess->rbufs[buf_id].rkey = le32_to_cpu(msg->rkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		process_io_rsp(sess, msg_id, err, w_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	ib_dma_sync_single_for_device(sess->s.dev->ib_dev, iu->dma_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 				      iu->size, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	return rtrs_clt_recv_done(con, wc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	rtrs_rdma_error_recovery(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) static struct ib_cqe io_comp_cqe = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	.done = rtrs_clt_rdma_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573)  * Post x2 empty WRs: first is for this RDMA with IMM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574)  * second is for RECV with INV, which happened earlier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) static int rtrs_post_recv_empty_x2(struct rtrs_con *con, struct ib_cqe *cqe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	struct ib_recv_wr wr_arr[2], *wr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	memset(wr_arr, 0, sizeof(wr_arr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	for (i = 0; i < ARRAY_SIZE(wr_arr); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		wr = &wr_arr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		wr->wr_cqe  = cqe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 			/* Chain backwards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 			wr->next = &wr_arr[i - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	return ib_post_recv(con->qp, wr, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	struct rtrs_clt_con *con = cq->cq_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	u32 imm_type, imm_payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	bool w_inval = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		if (wc->status != IB_WC_WR_FLUSH_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 			rtrs_err(sess->clt, "RDMA failed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 				  ib_wc_status_msg(wc->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 			rtrs_rdma_error_recovery(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	rtrs_clt_update_wc_stats(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	switch (wc->opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	case IB_WC_RECV_RDMA_WITH_IMM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		 * post_recv() RDMA write completions of IO reqs (read/write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		 * and hb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		if (WARN_ON(wc->wr_cqe->done != rtrs_clt_rdma_done))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 		rtrs_from_imm(be32_to_cpu(wc->ex.imm_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 			       &imm_type, &imm_payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		if (likely(imm_type == RTRS_IO_RSP_IMM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 			   imm_type == RTRS_IO_RSP_W_INV_IMM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 			u32 msg_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 			w_inval = (imm_type == RTRS_IO_RSP_W_INV_IMM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 			rtrs_from_io_rsp_imm(imm_payload, &msg_id, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 			process_io_rsp(sess, msg_id, err, w_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 		} else if (imm_type == RTRS_HB_MSG_IMM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 			WARN_ON(con->c.cid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 			rtrs_send_hb_ack(&sess->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 			if (sess->flags & RTRS_MSG_NEW_RKEY_F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 				return  rtrs_clt_recv_done(con, wc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		} else if (imm_type == RTRS_HB_ACK_IMM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 			WARN_ON(con->c.cid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 			sess->s.hb_missed_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			if (sess->flags & RTRS_MSG_NEW_RKEY_F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 				return  rtrs_clt_recv_done(con, wc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 			rtrs_wrn(con->c.sess, "Unknown IMM type %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 				  imm_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		if (w_inval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 			 * Post x2 empty WRs: first is for this RDMA with IMM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			 * second is for RECV with INV, which happened earlier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 			err = rtrs_post_recv_empty_x2(&con->c, &io_comp_cqe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			err = rtrs_post_recv_empty(&con->c, &io_comp_cqe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 			rtrs_err(con->c.sess, "rtrs_post_recv_empty(): %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 				  err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 			rtrs_rdma_error_recovery(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	case IB_WC_RECV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		 * Key invalidations from server side
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		WARN_ON(!(wc->wc_flags & IB_WC_WITH_INVALIDATE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 			  wc->wc_flags & IB_WC_WITH_IMM));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		WARN_ON(wc->wr_cqe->done != rtrs_clt_rdma_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		if (sess->flags & RTRS_MSG_NEW_RKEY_F) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			if (wc->wc_flags & IB_WC_WITH_INVALIDATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 				return  rtrs_clt_recv_done(con, wc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			return  rtrs_clt_rkey_rsp_done(con, wc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	case IB_WC_RDMA_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		 * post_send() RDMA write completions of IO reqs (read/write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		rtrs_wrn(sess->clt, "Unexpected WC type: %d\n", wc->opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) static int post_recv_io(struct rtrs_clt_con *con, size_t q_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	for (i = 0; i < q_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		if (sess->flags & RTRS_MSG_NEW_RKEY_F) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			struct rtrs_iu *iu = &con->rsp_ius[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 			err = rtrs_iu_post_recv(&con->c, iu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 			err = rtrs_post_recv_empty(&con->c, &io_comp_cqe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) static int post_recv_sess(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	size_t q_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	int err, cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	for (cid = 0; cid < sess->s.con_num; cid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		if (cid == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			q_size = SERVICE_CON_QUEUE_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 			q_size = sess->queue_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		 * x2 for RDMA read responses + FR key invalidations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		 * RDMA writes do not require any FR registrations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		q_size *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		err = post_recv_io(to_clt_con(sess->s.con[cid]), q_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 			rtrs_err(sess->clt, "post_recv_io(), err: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) struct path_it {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	struct list_head skip_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	struct rtrs_clt *clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	struct rtrs_clt_sess *(*next_path)(struct path_it *it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739)  * list_next_or_null_rr_rcu - get next list element in round-robin fashion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740)  * @head:	the head for the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741)  * @ptr:        the list head to take the next element from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742)  * @type:       the type of the struct this is embedded in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743)  * @memb:       the name of the list_head within the struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745)  * Next element returned in round-robin fashion, i.e. head will be skipped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746)  * but if list is observed as empty, NULL will be returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748)  * This primitive may safely run concurrently with the _rcu list-mutation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749)  * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) #define list_next_or_null_rr_rcu(head, ptr, type, memb) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	list_next_or_null_rcu(head, ptr, type, memb) ?: \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		list_next_or_null_rcu(head, READ_ONCE((ptr)->next), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 				      type, memb); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759)  * get_next_path_rr() - Returns path in round-robin fashion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760)  * @it:	the path pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762)  * Related to @MP_POLICY_RR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764)  * Locks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765)  *    rcu_read_lock() must be hold.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) static struct rtrs_clt_sess *get_next_path_rr(struct path_it *it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	struct rtrs_clt_sess __rcu **ppcpu_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	struct rtrs_clt_sess *path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	struct rtrs_clt *clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	clt = it->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	 * Here we use two RCU objects: @paths_list and @pcpu_path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	 * pointer.  See rtrs_clt_remove_path_from_arr() for details
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	 * how that is handled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	ppcpu_path = this_cpu_ptr(clt->pcpu_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	path = rcu_dereference(*ppcpu_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	if (unlikely(!path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		path = list_first_or_null_rcu(&clt->paths_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 					      typeof(*path), s.entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		path = list_next_or_null_rr_rcu(&clt->paths_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 						&path->s.entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 						typeof(*path),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 						s.entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	rcu_assign_pointer(*ppcpu_path, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	return path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797)  * get_next_path_min_inflight() - Returns path with minimal inflight count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798)  * @it:	the path pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800)  * Related to @MP_POLICY_MIN_INFLIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802)  * Locks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803)  *    rcu_read_lock() must be hold.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) static struct rtrs_clt_sess *get_next_path_min_inflight(struct path_it *it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	struct rtrs_clt_sess *min_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	struct rtrs_clt *clt = it->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	struct rtrs_clt_sess *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	int min_inflight = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	int inflight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	list_for_each_entry_rcu(sess, &clt->paths_list, s.entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		if (unlikely(READ_ONCE(sess->state) != RTRS_CLT_CONNECTED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		if (unlikely(!list_empty(raw_cpu_ptr(sess->mp_skip_entry))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		inflight = atomic_read(&sess->stats->inflight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		if (inflight < min_inflight) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 			min_inflight = inflight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 			min_path = sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	 * add the path to the skip list, so that next time we can get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	 * a different one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	if (min_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		list_add(raw_cpu_ptr(min_path->mp_skip_entry), &it->skip_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	return min_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) static inline void path_it_init(struct path_it *it, struct rtrs_clt *clt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	INIT_LIST_HEAD(&it->skip_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	it->clt = clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	it->i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	if (clt->mp_policy == MP_POLICY_RR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		it->next_path = get_next_path_rr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		it->next_path = get_next_path_min_inflight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) static inline void path_it_deinit(struct path_it *it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	struct list_head *skip, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	 * The skip_list is used only for the MIN_INFLIGHT policy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	 * We need to remove paths from it, so that next IO can insert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	 * paths (->mp_skip_entry) into a skip_list again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	list_for_each_safe(skip, tmp, &it->skip_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		list_del_init(skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863)  * rtrs_clt_init_req() Initialize an rtrs_clt_io_req holding information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864)  * about an inflight IO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865)  * The user buffer holding user control message (not data) is copied into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866)  * the corresponding buffer of rtrs_iu (req->iu->buf), which later on will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867)  * also hold the control message of rtrs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868)  * @req: an io request holding information about IO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869)  * @sess: client session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870)  * @conf: conformation callback function to notify upper layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871)  * @permit: permit for allocation of RDMA remote buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872)  * @priv: private pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873)  * @vec: kernel vector containing control message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874)  * @usr_len: length of the user message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875)  * @sg: scater list for IO data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876)  * @sg_cnt: number of scater list entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877)  * @data_len: length of the IO data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878)  * @dir: direction of the IO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) static void rtrs_clt_init_req(struct rtrs_clt_io_req *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			      struct rtrs_clt_sess *sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 			      void (*conf)(void *priv, int errno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			      struct rtrs_permit *permit, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 			      const struct kvec *vec, size_t usr_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			      struct scatterlist *sg, size_t sg_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 			      size_t data_len, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	struct iov_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	req->permit = permit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	req->in_use = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	req->usr_len = usr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	req->data_len = data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	req->sglist = sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	req->sg_cnt = sg_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	req->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	req->dir = dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	req->con = rtrs_permit_to_clt_con(sess, permit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	req->conf = conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	req->need_inv = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	req->need_inv_comp = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	req->inv_errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	iov_iter_kvec(&iter, READ, vec, 1, usr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	len = _copy_from_iter(req->iu->buf, usr_len, &iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	WARN_ON(len != usr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	reinit_completion(&req->inv_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) static struct rtrs_clt_io_req *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) rtrs_clt_get_req(struct rtrs_clt_sess *sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		 void (*conf)(void *priv, int errno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		 struct rtrs_permit *permit, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		 const struct kvec *vec, size_t usr_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		 struct scatterlist *sg, size_t sg_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		 size_t data_len, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	struct rtrs_clt_io_req *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	req = &sess->reqs[permit->mem_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	rtrs_clt_init_req(req, sess, conf, permit, priv, vec, usr_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 			   sg, sg_cnt, data_len, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) static struct rtrs_clt_io_req *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) rtrs_clt_get_copy_req(struct rtrs_clt_sess *alive_sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		       struct rtrs_clt_io_req *fail_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	struct rtrs_clt_io_req *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	struct kvec vec = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		.iov_base = fail_req->iu->buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		.iov_len  = fail_req->usr_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	req = &alive_sess->reqs[fail_req->permit->mem_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	rtrs_clt_init_req(req, alive_sess, fail_req->conf, fail_req->permit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 			   fail_req->priv, &vec, fail_req->usr_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 			   fail_req->sglist, fail_req->sg_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 			   fail_req->data_len, fail_req->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) static int rtrs_post_rdma_write_sg(struct rtrs_clt_con *con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 				    struct rtrs_clt_io_req *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 				    struct rtrs_rbuf *rbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 				    u32 size, u32 imm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	struct ib_sge *sge = req->sge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	enum ib_send_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	size_t num_sge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	for_each_sg(req->sglist, sg, req->sg_cnt, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		sge[i].addr   = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		sge[i].length = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		sge[i].lkey   = sess->s.dev->ib_pd->local_dma_lkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	sge[i].addr   = req->iu->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	sge[i].length = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	sge[i].lkey   = sess->s.dev->ib_pd->local_dma_lkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	num_sge = 1 + req->sg_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	 * From time to time we have to post signalled sends,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	 * or send queue will fill up and only QP reset can help.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	flags = atomic_inc_return(&con->io_cnt) % sess->queue_depth ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 			0 : IB_SEND_SIGNALED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	ib_dma_sync_single_for_device(sess->s.dev->ib_dev, req->iu->dma_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 				      size, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	return rtrs_iu_post_rdma_write_imm(&con->c, req->iu, sge, num_sge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 					    rbuf->rkey, rbuf->addr, imm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 					    flags, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) static int rtrs_clt_write_req(struct rtrs_clt_io_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	struct rtrs_clt_con *con = req->con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	struct rtrs_sess *s = con->c.sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	struct rtrs_clt_sess *sess = to_clt_sess(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	struct rtrs_msg_rdma_write *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	struct rtrs_rbuf *rbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	int ret, count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	u32 imm, buf_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	const size_t tsize = sizeof(*msg) + req->data_len + req->usr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	if (unlikely(tsize > sess->chunk_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		rtrs_wrn(s, "Write request failed, size too big %zu > %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 			  tsize, sess->chunk_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	if (req->sg_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		count = ib_dma_map_sg(sess->s.dev->ib_dev, req->sglist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 				      req->sg_cnt, req->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		if (unlikely(!count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 			rtrs_wrn(s, "Write request failed, map failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	/* put rtrs msg after sg and user message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	msg = req->iu->buf + req->usr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	msg->type = cpu_to_le16(RTRS_MSG_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	msg->usr_len = cpu_to_le16(req->usr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	/* rtrs message on server side will be after user data and message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	imm = req->permit->mem_off + req->data_len + req->usr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	imm = rtrs_to_io_req_imm(imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	buf_id = req->permit->mem_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	req->sg_size = tsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	rbuf = &sess->rbufs[buf_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	 * Update stats now, after request is successfully sent it is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	 * safe anymore to touch it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	rtrs_clt_update_all_stats(req, WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	ret = rtrs_post_rdma_write_sg(req->con, req, rbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 				       req->usr_len + sizeof(*msg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 				       imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	if (unlikely(ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		rtrs_err(s, "Write request failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		if (sess->clt->mp_policy == MP_POLICY_MIN_INFLIGHT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 			atomic_dec(&sess->stats->inflight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		if (req->sg_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 			ib_dma_unmap_sg(sess->s.dev->ib_dev, req->sglist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 					req->sg_cnt, req->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) static int rtrs_map_sg_fr(struct rtrs_clt_io_req *req, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	int nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	/* Align the MR to a 4K page size to match the block virt boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	nr = ib_map_mr_sg(req->mr, req->sglist, count, NULL, SZ_4K);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	if (nr < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		return nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	if (unlikely(nr < req->sg_cnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	ib_update_fast_reg_key(req->mr, ib_inc_rkey(req->mr->rkey));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	return nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static int rtrs_clt_read_req(struct rtrs_clt_io_req *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	struct rtrs_clt_con *con = req->con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	struct rtrs_sess *s = con->c.sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	struct rtrs_clt_sess *sess = to_clt_sess(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	struct rtrs_msg_rdma_read *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	struct rtrs_ib_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	struct ib_reg_wr rwr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	struct ib_send_wr *wr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	int ret, count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	u32 imm, buf_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	const size_t tsize = sizeof(*msg) + req->data_len + req->usr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	s = &sess->s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	dev = sess->s.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	if (unlikely(tsize > sess->chunk_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		rtrs_wrn(s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 			  "Read request failed, message size is %zu, bigger than CHUNK_SIZE %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			  tsize, sess->chunk_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	if (req->sg_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		count = ib_dma_map_sg(dev->ib_dev, req->sglist, req->sg_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 				      req->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		if (unlikely(!count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 			rtrs_wrn(s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 				  "Read request failed, dma map failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	/* put our message into req->buf after user message*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	msg = req->iu->buf + req->usr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	msg->type = cpu_to_le16(RTRS_MSG_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	msg->usr_len = cpu_to_le16(req->usr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	if (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		ret = rtrs_map_sg_fr(req, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 			rtrs_err_rl(s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 				     "Read request failed, failed to map  fast reg. data, err: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 				     ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 			ib_dma_unmap_sg(dev->ib_dev, req->sglist, req->sg_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 					req->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		rwr = (struct ib_reg_wr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 			.wr.opcode = IB_WR_REG_MR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 			.wr.wr_cqe = &fast_reg_cqe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 			.mr = req->mr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 			.key = req->mr->rkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 			.access = (IB_ACCESS_LOCAL_WRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 				   IB_ACCESS_REMOTE_WRITE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		wr = &rwr.wr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		msg->sg_cnt = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		msg->flags = cpu_to_le16(RTRS_MSG_NEED_INVAL_F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		msg->desc[0].addr = cpu_to_le64(req->mr->iova);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		msg->desc[0].key = cpu_to_le32(req->mr->rkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		msg->desc[0].len = cpu_to_le32(req->mr->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		/* Further invalidation is required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		req->need_inv = !!RTRS_MSG_NEED_INVAL_F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 		msg->sg_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		msg->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	 * rtrs message will be after the space reserved for disk data and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	 * user message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	imm = req->permit->mem_off + req->data_len + req->usr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	imm = rtrs_to_io_req_imm(imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	buf_id = req->permit->mem_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	req->sg_size  = sizeof(*msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	req->sg_size += le16_to_cpu(msg->sg_cnt) * sizeof(struct rtrs_sg_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	req->sg_size += req->usr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	 * Update stats now, after request is successfully sent it is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	 * safe anymore to touch it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	rtrs_clt_update_all_stats(req, READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	ret = rtrs_post_send_rdma(req->con, req, &sess->rbufs[buf_id],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 				   req->data_len, imm, wr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	if (unlikely(ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		rtrs_err(s, "Read request failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		if (sess->clt->mp_policy == MP_POLICY_MIN_INFLIGHT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 			atomic_dec(&sess->stats->inflight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		req->need_inv = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		if (req->sg_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 			ib_dma_unmap_sg(dev->ib_dev, req->sglist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 					req->sg_cnt, req->dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)  * rtrs_clt_failover_req() Try to find an active path for a failed request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)  * @clt: clt context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)  * @fail_req: a failed io request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) static int rtrs_clt_failover_req(struct rtrs_clt *clt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 				 struct rtrs_clt_io_req *fail_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	struct rtrs_clt_sess *alive_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	struct rtrs_clt_io_req *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	int err = -ECONNABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	struct path_it it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	for (path_it_init(&it, clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	     (alive_sess = it.next_path(&it)) && it.i < it.clt->paths_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	     it.i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		if (unlikely(READ_ONCE(alive_sess->state) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 			     RTRS_CLT_CONNECTED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		req = rtrs_clt_get_copy_req(alive_sess, fail_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 		if (req->dir == DMA_TO_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 			err = rtrs_clt_write_req(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 			err = rtrs_clt_read_req(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 		if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 			req->in_use = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		/* Success path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		rtrs_clt_inc_failover_cnt(alive_sess->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	path_it_deinit(&it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) static void fail_all_outstanding_reqs(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	struct rtrs_clt *clt = sess->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	struct rtrs_clt_io_req *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	if (!sess->reqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	for (i = 0; i < sess->queue_depth; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		req = &sess->reqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		if (!req->in_use)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 		 * Safely (without notification) complete failed request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		 * After completion this request is still useble and can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		 * be failovered to another path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		complete_rdma_req(req, -ECONNABORTED, false, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		err = rtrs_clt_failover_req(clt, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 			/* Failover failed, notify anyway */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 			req->conf(req->priv, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) static void free_sess_reqs(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	struct rtrs_clt_io_req *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	if (!sess->reqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	for (i = 0; i < sess->queue_depth; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		req = &sess->reqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		if (req->mr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 			ib_dereg_mr(req->mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 		kfree(req->sge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		rtrs_iu_free(req->iu, sess->s.dev->ib_dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	kfree(sess->reqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	sess->reqs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static int alloc_sess_reqs(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	struct rtrs_clt_io_req *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	struct rtrs_clt *clt = sess->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	int i, err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	sess->reqs = kcalloc(sess->queue_depth, sizeof(*sess->reqs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 			     GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	if (!sess->reqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	for (i = 0; i < sess->queue_depth; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		req = &sess->reqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 		req->iu = rtrs_iu_alloc(1, sess->max_hdr_size, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 					 sess->s.dev->ib_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 					 DMA_TO_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 					 rtrs_clt_rdma_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		if (!req->iu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 		req->sge = kmalloc_array(clt->max_segments + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 					 sizeof(*req->sge), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 		if (!req->sge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 		req->mr = ib_alloc_mr(sess->s.dev->ib_pd, IB_MR_TYPE_MEM_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 				      sess->max_pages_per_mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		if (IS_ERR(req->mr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 			err = PTR_ERR(req->mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 			req->mr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 			pr_err("Failed to alloc sess->max_pages_per_mr %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 			       sess->max_pages_per_mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 		init_completion(&req->inv_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	free_sess_reqs(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) static int alloc_permits(struct rtrs_clt *clt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	unsigned int chunk_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	clt->permits_map = kcalloc(BITS_TO_LONGS(clt->queue_depth),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 				   sizeof(long), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	if (!clt->permits_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	clt->permits = kcalloc(clt->queue_depth, permit_size(clt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	if (!clt->permits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 		goto err_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	chunk_bits = ilog2(clt->queue_depth - 1) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	for (i = 0; i < clt->queue_depth; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		struct rtrs_permit *permit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		permit = get_permit(clt, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		permit->mem_id = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 		permit->mem_off = i << (MAX_IMM_PAYL_BITS - chunk_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) err_map:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	kfree(clt->permits_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	clt->permits_map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) static void free_permits(struct rtrs_clt *clt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	if (clt->permits_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		size_t sz = clt->queue_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		wait_event(clt->permits_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 			   find_first_bit(clt->permits_map, sz) >= sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	kfree(clt->permits_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	clt->permits_map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	kfree(clt->permits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	clt->permits = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) static void query_fast_reg_mode(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	struct ib_device *ib_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	u64 max_pages_per_mr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	int mr_page_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	ib_dev = sess->s.dev->ib_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	 * Use the smallest page size supported by the HCA, down to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	 * minimum of 4096 bytes. We're unlikely to build large sglists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	 * out of smaller entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	mr_page_shift      = max(12, ffs(ib_dev->attrs.page_size_cap) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	max_pages_per_mr   = ib_dev->attrs.max_mr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	do_div(max_pages_per_mr, (1ull << mr_page_shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	sess->max_pages_per_mr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		min3(sess->max_pages_per_mr, (u32)max_pages_per_mr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		     ib_dev->attrs.max_fast_reg_page_list_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	sess->max_send_sge = ib_dev->attrs.max_send_sge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) static bool rtrs_clt_change_state_get_old(struct rtrs_clt_sess *sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 					   enum rtrs_clt_state new_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 					   enum rtrs_clt_state *old_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	bool changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	spin_lock_irq(&sess->state_wq.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	*old_state = sess->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	changed = __rtrs_clt_change_state(sess, new_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	spin_unlock_irq(&sess->state_wq.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) static bool rtrs_clt_change_state(struct rtrs_clt_sess *sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 				   enum rtrs_clt_state new_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	enum rtrs_clt_state old_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	return rtrs_clt_change_state_get_old(sess, new_state, &old_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static void rtrs_clt_hb_err_handler(struct rtrs_con *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	struct rtrs_clt_con *con = container_of(c, typeof(*con), c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	rtrs_rdma_error_recovery(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) static void rtrs_clt_init_hb(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	rtrs_init_hb(&sess->s, &io_comp_cqe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		      RTRS_HB_INTERVAL_MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		      RTRS_HB_MISSED_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 		      rtrs_clt_hb_err_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 		      rtrs_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) static void rtrs_clt_start_hb(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	rtrs_start_hb(&sess->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) static void rtrs_clt_stop_hb(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	rtrs_stop_hb(&sess->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) static void rtrs_clt_reconnect_work(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static void rtrs_clt_close_work(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static struct rtrs_clt_sess *alloc_sess(struct rtrs_clt *clt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 					 const struct rtrs_addr *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 					 size_t con_num, u16 max_segments,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 					 size_t max_segment_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	struct rtrs_clt_sess *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	sess = kzalloc(sizeof(*sess), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	if (!sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	/* Extra connection for user messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	con_num += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	sess->s.con = kcalloc(con_num, sizeof(*sess->s.con), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	if (!sess->s.con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 		goto err_free_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	sess->stats = kzalloc(sizeof(*sess->stats), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	if (!sess->stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 		goto err_free_con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	mutex_init(&sess->init_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	uuid_gen(&sess->s.uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	memcpy(&sess->s.dst_addr, path->dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	       rdma_addr_size((struct sockaddr *)path->dst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	 * rdma_resolve_addr() passes src_addr to cma_bind_addr, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	 * checks the sa_family to be non-zero. If user passed src_addr=NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	 * the sess->src_addr will contain only zeros, which is then fine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	if (path->src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		memcpy(&sess->s.src_addr, path->src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 		       rdma_addr_size((struct sockaddr *)path->src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	strlcpy(sess->s.sessname, clt->sessname, sizeof(sess->s.sessname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	sess->s.con_num = con_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	sess->clt = clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	sess->max_pages_per_mr = max_segments * max_segment_size >> 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	init_waitqueue_head(&sess->state_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	sess->state = RTRS_CLT_CONNECTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	atomic_set(&sess->connected_cnt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	INIT_WORK(&sess->close_work, rtrs_clt_close_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	INIT_DELAYED_WORK(&sess->reconnect_dwork, rtrs_clt_reconnect_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	rtrs_clt_init_hb(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	sess->mp_skip_entry = alloc_percpu(typeof(*sess->mp_skip_entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	if (!sess->mp_skip_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		goto err_free_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	for_each_possible_cpu(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		INIT_LIST_HEAD(per_cpu_ptr(sess->mp_skip_entry, cpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	err = rtrs_clt_init_stats(sess->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		goto err_free_percpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	return sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) err_free_percpu:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	free_percpu(sess->mp_skip_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) err_free_stats:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	kfree(sess->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) err_free_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	kfree(sess->s.con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) err_free_sess:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	kfree(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) void free_sess(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	free_percpu(sess->mp_skip_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	mutex_destroy(&sess->init_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	kfree(sess->s.con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	kfree(sess->rbufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	kfree(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) static int create_con(struct rtrs_clt_sess *sess, unsigned int cid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	struct rtrs_clt_con *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	con = kzalloc(sizeof(*con), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	if (!con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	/* Map first two connections to the first CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	con->cpu  = (cid ? cid - 1 : 0) % nr_cpu_ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	con->c.cid = cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	con->c.sess = &sess->s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	atomic_set(&con->io_cnt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	sess->s.con[cid] = &con->c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) static void destroy_con(struct rtrs_clt_con *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	sess->s.con[con->c.cid] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	kfree(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) static int create_con_cq_qp(struct rtrs_clt_con *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	u32 max_send_wr, max_recv_wr, cq_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	int err, cq_vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	struct rtrs_msg_rkey_rsp *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	 * This function can fail, but still destroy_con_cq_qp() should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	 * be called, this is because create_con_cq_qp() is called on cm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	 * event path, thus caller/waiter never knows: have we failed before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	 * create_con_cq_qp() or after.  To solve this dilemma without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	 * creating any additional flags just allow destroy_con_cq_qp() be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	 * called many times.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	if (con->c.cid == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 		 * One completion for each receive and two for each send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		 * (send request + registration)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		 * + 2 for drain and heartbeat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		 * in case qp gets into error state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		max_send_wr = SERVICE_CON_QUEUE_DEPTH * 2 + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 		max_recv_wr = SERVICE_CON_QUEUE_DEPTH * 2 + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 		/* We must be the first here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 		if (WARN_ON(sess->s.dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 		 * The whole session uses device from user connection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 		 * Be careful not to close user connection before ib dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		 * is gracefully put.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 		sess->s.dev = rtrs_ib_dev_find_or_add(con->c.cm_id->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 						       &dev_pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 		if (!sess->s.dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 			rtrs_wrn(sess->clt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 				  "rtrs_ib_dev_find_get_or_add(): no memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 		sess->s.dev_ref = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 		query_fast_reg_mode(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		 * Here we assume that session members are correctly set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		 * This is always true if user connection (cid == 0) is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		 * established first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 		if (WARN_ON(!sess->s.dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		if (WARN_ON(!sess->queue_depth))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 		/* Shared between connections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 		sess->s.dev_ref++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 		max_send_wr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 			min_t(int, sess->s.dev->ib_dev->attrs.max_qp_wr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 			      /* QD * (REQ + RSP + FR REGS or INVS) + drain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 			      sess->queue_depth * 3 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 		max_recv_wr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 			min_t(int, sess->s.dev->ib_dev->attrs.max_qp_wr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 			      sess->queue_depth * 3 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	/* alloc iu to recv new rkey reply when server reports flags set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	if (sess->flags & RTRS_MSG_NEW_RKEY_F || con->c.cid == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 		con->rsp_ius = rtrs_iu_alloc(max_recv_wr, sizeof(*rsp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 					      GFP_KERNEL, sess->s.dev->ib_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 					      DMA_FROM_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 					      rtrs_clt_rdma_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 		if (!con->rsp_ius)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 		con->queue_size = max_recv_wr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	cq_size = max_send_wr + max_recv_wr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	cq_vector = con->cpu % sess->s.dev->ib_dev->num_comp_vectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	err = rtrs_cq_qp_create(&sess->s, &con->c, sess->max_send_sge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 				 cq_vector, cq_size, max_send_wr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 				 max_recv_wr, IB_POLL_SOFTIRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	 * In case of error we do not bother to clean previous allocations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	 * since destroy_con_cq_qp() must be called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) static void destroy_con_cq_qp(struct rtrs_clt_con *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	 * Be careful here: destroy_con_cq_qp() can be called even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	 * create_con_cq_qp() failed, see comments there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	rtrs_cq_qp_destroy(&con->c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	if (con->rsp_ius) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 		rtrs_iu_free(con->rsp_ius, sess->s.dev->ib_dev, con->queue_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 		con->rsp_ius = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 		con->queue_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	if (sess->s.dev_ref && !--sess->s.dev_ref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 		rtrs_ib_dev_put(sess->s.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		sess->s.dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) static void stop_cm(struct rtrs_clt_con *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	rdma_disconnect(con->c.cm_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	if (con->c.qp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 		ib_drain_qp(con->c.qp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) static void destroy_cm(struct rtrs_clt_con *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	rdma_destroy_id(con->c.cm_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	con->c.cm_id = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) static int rtrs_rdma_addr_resolved(struct rtrs_clt_con *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	struct rtrs_sess *s = con->c.sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	err = create_con_cq_qp(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		rtrs_err(s, "create_con_cq_qp(), err: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	err = rdma_resolve_route(con->c.cm_id, RTRS_CONNECT_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 		rtrs_err(s, "Resolving route failed, err: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) static int rtrs_rdma_route_resolved(struct rtrs_clt_con *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	struct rtrs_clt *clt = sess->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	struct rtrs_msg_conn_req msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	struct rdma_conn_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	param = (struct rdma_conn_param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 		.retry_count = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 		.rnr_retry_count = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 		.private_data = &msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 		.private_data_len = sizeof(msg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	msg = (struct rtrs_msg_conn_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		.magic = cpu_to_le16(RTRS_MAGIC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 		.version = cpu_to_le16(RTRS_PROTO_VER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 		.cid = cpu_to_le16(con->c.cid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		.cid_num = cpu_to_le16(sess->s.con_num),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 		.recon_cnt = cpu_to_le16(sess->s.recon_cnt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	msg.first_conn = sess->for_new_clt ? FIRST_CONN : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	uuid_copy(&msg.sess_uuid, &sess->s.uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	uuid_copy(&msg.paths_uuid, &clt->paths_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	err = rdma_connect_locked(con->c.cm_id, &param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 		rtrs_err(clt, "rdma_connect_locked(): %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 				       struct rdma_cm_event *ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	struct rtrs_clt *clt = sess->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	const struct rtrs_msg_conn_rsp *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	u16 version, queue_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	int errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 	u8 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	msg = ev->param.conn.private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	len = ev->param.conn.private_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	if (len < sizeof(*msg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 		rtrs_err(clt, "Invalid RTRS connection response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 		return -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 	if (le16_to_cpu(msg->magic) != RTRS_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		rtrs_err(clt, "Invalid RTRS magic\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 		return -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	version = le16_to_cpu(msg->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 	if (version >> 8 != RTRS_PROTO_VER_MAJOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 		rtrs_err(clt, "Unsupported major RTRS version: %d, expected %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 			  version >> 8, RTRS_PROTO_VER_MAJOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 		return -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	errno = le16_to_cpu(msg->errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	if (errno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 		rtrs_err(clt, "Invalid RTRS message: errno %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 			  errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		return -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	if (con->c.cid == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 		queue_depth = le16_to_cpu(msg->queue_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 		if (queue_depth > MAX_SESS_QUEUE_DEPTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 			rtrs_err(clt, "Invalid RTRS message: queue=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 				  queue_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 			return -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 		if (sess->queue_depth > 0 && queue_depth != sess->queue_depth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 			rtrs_err(clt, "Error: queue depth changed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 			 * Stop any more reconnection attempts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 			sess->reconnect_attempts = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 			rtrs_err(clt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 				"Disabling auto-reconnect. Trigger a manual reconnect after issue is resolved\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 			return -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		if (!sess->rbufs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 			kfree(sess->rbufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 			sess->rbufs = kcalloc(queue_depth, sizeof(*sess->rbufs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 					      GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 			if (!sess->rbufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 				return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 		sess->queue_depth = queue_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 		sess->max_hdr_size = le32_to_cpu(msg->max_hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 		sess->max_io_size = le32_to_cpu(msg->max_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 		sess->flags = le32_to_cpu(msg->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 		sess->chunk_size = sess->max_io_size + sess->max_hdr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 		 * Global IO size is always a minimum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 		 * If while a reconnection server sends us a value a bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 		 * higher - client does not care and uses cached minimum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 		 * Since we can have several sessions (paths) restablishing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 		 * connections in parallel, use lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 		mutex_lock(&clt->paths_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 		clt->queue_depth = sess->queue_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 		clt->max_io_size = min_not_zero(sess->max_io_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 						clt->max_io_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 		mutex_unlock(&clt->paths_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 		 * Cache the hca_port and hca_name for sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 		sess->hca_port = con->c.cm_id->port_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 		scnprintf(sess->hca_name, sizeof(sess->hca_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 			  sess->s.dev->ib_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 		sess->s.src_addr = con->c.cm_id->route.addr.src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 		/* set for_new_clt, to allow future reconnect on any path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 		sess->for_new_clt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) static inline void flag_success_on_conn(struct rtrs_clt_con *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	atomic_inc(&sess->connected_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 	con->cm_err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) static int rtrs_rdma_conn_rejected(struct rtrs_clt_con *con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 				    struct rdma_cm_event *ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	struct rtrs_sess *s = con->c.sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	const struct rtrs_msg_conn_rsp *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	const char *rej_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	int status, errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	u8 data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 	status = ev->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	rej_msg = rdma_reject_msg(con->c.cm_id, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	msg = rdma_consumer_reject_data(con->c.cm_id, ev, &data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	if (msg && data_len >= sizeof(*msg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 		errno = (int16_t)le16_to_cpu(msg->errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 		if (errno == -EBUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 			rtrs_err(s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 				  "Previous session is still exists on the server, please reconnect later\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 			rtrs_err(s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 				  "Connect rejected: status %d (%s), rtrs errno %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 				  status, rej_msg, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 		rtrs_err(s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 			  "Connect rejected but with malformed message: status %d (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 			  status, rej_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	return -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) static void rtrs_clt_close_conns(struct rtrs_clt_sess *sess, bool wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	if (rtrs_clt_change_state(sess, RTRS_CLT_CLOSING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 		queue_work(rtrs_wq, &sess->close_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	if (wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 		flush_work(&sess->close_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) static inline void flag_error_on_conn(struct rtrs_clt_con *con, int cm_err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	if (con->cm_err == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 		struct rtrs_clt_sess *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 		sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 		if (atomic_dec_and_test(&sess->connected_cnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 			wake_up(&sess->state_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 	con->cm_err = cm_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) static int rtrs_clt_rdma_cm_handler(struct rdma_cm_id *cm_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 				     struct rdma_cm_event *ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	struct rtrs_clt_con *con = cm_id->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 	struct rtrs_sess *s = con->c.sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	struct rtrs_clt_sess *sess = to_clt_sess(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 	int cm_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	switch (ev->event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	case RDMA_CM_EVENT_ADDR_RESOLVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 		cm_err = rtrs_rdma_addr_resolved(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	case RDMA_CM_EVENT_ROUTE_RESOLVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 		cm_err = rtrs_rdma_route_resolved(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	case RDMA_CM_EVENT_ESTABLISHED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 		cm_err = rtrs_rdma_conn_established(con, ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 		if (likely(!cm_err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 			 * Report success and wake up. Here we abuse state_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 			 * i.e. wake up without state change, but we set cm_err.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 			flag_success_on_conn(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 			wake_up(&sess->state_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	case RDMA_CM_EVENT_REJECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 		cm_err = rtrs_rdma_conn_rejected(con, ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	case RDMA_CM_EVENT_CONNECT_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 	case RDMA_CM_EVENT_UNREACHABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 		rtrs_wrn(s, "CM error event %d\n", ev->event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 		cm_err = -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	case RDMA_CM_EVENT_ADDR_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 	case RDMA_CM_EVENT_ROUTE_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 		cm_err = -EHOSTUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	case RDMA_CM_EVENT_DISCONNECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 	case RDMA_CM_EVENT_ADDR_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	case RDMA_CM_EVENT_TIMEWAIT_EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 		cm_err = -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	case RDMA_CM_EVENT_DEVICE_REMOVAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 		 * Device removal is a special case.  Queue close and return 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 		rtrs_clt_close_conns(sess, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 		rtrs_err(s, "Unexpected RDMA CM event (%d)\n", ev->event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 		cm_err = -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	if (cm_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 		 * cm error makes sense only on connection establishing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 		 * in other cases we rely on normal procedure of reconnecting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 		flag_error_on_conn(con, cm_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 		rtrs_rdma_error_recovery(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) static int create_cm(struct rtrs_clt_con *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	struct rtrs_sess *s = con->c.sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	struct rtrs_clt_sess *sess = to_clt_sess(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	struct rdma_cm_id *cm_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	cm_id = rdma_create_id(&init_net, rtrs_clt_rdma_cm_handler, con,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 			       sess->s.dst_addr.ss_family == AF_IB ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 			       RDMA_PS_IB : RDMA_PS_TCP, IB_QPT_RC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	if (IS_ERR(cm_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 		err = PTR_ERR(cm_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 		rtrs_err(s, "Failed to create CM ID, err: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	con->c.cm_id = cm_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	con->cm_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	/* allow the port to be reused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	err = rdma_set_reuseaddr(cm_id, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	if (err != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 		rtrs_err(s, "Set address reuse failed, err: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 		goto destroy_cm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	err = rdma_resolve_addr(cm_id, (struct sockaddr *)&sess->s.src_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 				(struct sockaddr *)&sess->s.dst_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 				RTRS_CONNECT_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 		rtrs_err(s, "Failed to resolve address, err: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 		goto destroy_cm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	 * Combine connection status and session events. This is needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	 * for waiting two possible cases: cm_err has something meaningful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	 * or session state was really changed to error by device removal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	err = wait_event_interruptible_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 			sess->state_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 			con->cm_err || sess->state != RTRS_CLT_CONNECTING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 			msecs_to_jiffies(RTRS_CONNECT_TIMEOUT_MS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	if (err == 0 || err == -ERESTARTSYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 		if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 			err = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 		/* Timedout or interrupted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 		goto errr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	if (con->cm_err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 		err = con->cm_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 		goto errr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	if (READ_ONCE(sess->state) != RTRS_CLT_CONNECTING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 		/* Device removal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 		err = -ECONNABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 		goto errr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) errr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	stop_cm(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	/* Is safe to call destroy if cq_qp is not inited */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	destroy_con_cq_qp(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) destroy_cm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	destroy_cm(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) static void rtrs_clt_sess_up(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	struct rtrs_clt *clt = sess->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	int up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 	 * We can fire RECONNECTED event only when all paths were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	 * connected on rtrs_clt_open(), then each was disconnected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	 * and the first one connected again.  That's why this nasty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	 * game with counter value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 	mutex_lock(&clt->paths_ev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	up = ++clt->paths_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 	 * Here it is safe to access paths num directly since up counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	 * is greater than MAX_PATHS_NUM only while rtrs_clt_open() is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	 * in progress, thus paths removals are impossible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	if (up > MAX_PATHS_NUM && up == MAX_PATHS_NUM + clt->paths_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 		clt->paths_up = clt->paths_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	else if (up == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 		clt->link_ev(clt->priv, RTRS_CLT_LINK_EV_RECONNECTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	mutex_unlock(&clt->paths_ev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 	/* Mark session as established */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	sess->established = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	sess->reconnect_attempts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 	sess->stats->reconnects.successful_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) static void rtrs_clt_sess_down(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	struct rtrs_clt *clt = sess->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 	if (!sess->established)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	sess->established = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 	mutex_lock(&clt->paths_ev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	WARN_ON(!clt->paths_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	if (--clt->paths_up == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 		clt->link_ev(clt->priv, RTRS_CLT_LINK_EV_DISCONNECTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	mutex_unlock(&clt->paths_ev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) static void rtrs_clt_stop_and_destroy_conns(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	struct rtrs_clt_con *con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	unsigned int cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	WARN_ON(READ_ONCE(sess->state) == RTRS_CLT_CONNECTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	 * Possible race with rtrs_clt_open(), when DEVICE_REMOVAL comes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	 * exactly in between.  Start destroying after it finishes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	mutex_lock(&sess->init_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 	mutex_unlock(&sess->init_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 	 * All IO paths must observe !CONNECTED state before we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	 * free everything.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	rtrs_clt_stop_hb(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	 * The order it utterly crucial: firstly disconnect and complete all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	 * rdma requests with error (thus set in_use=false for requests),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 	 * then fail outstanding requests checking in_use for each, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	 * eventually notify upper layer about session disconnection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	for (cid = 0; cid < sess->s.con_num; cid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 		if (!sess->s.con[cid])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 		con = to_clt_con(sess->s.con[cid]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 		stop_cm(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 	fail_all_outstanding_reqs(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	free_sess_reqs(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 	rtrs_clt_sess_down(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	 * Wait for graceful shutdown, namely when peer side invokes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	 * rdma_disconnect(). 'connected_cnt' is decremented only on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	 * CM events, thus if other side had crashed and hb has detected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	 * something is wrong, here we will stuck for exactly timeout ms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	 * since CM does not fire anything.  That is fine, we are not in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	 * hurry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	wait_event_timeout(sess->state_wq, !atomic_read(&sess->connected_cnt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 			   msecs_to_jiffies(RTRS_CONNECT_TIMEOUT_MS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	for (cid = 0; cid < sess->s.con_num; cid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 		if (!sess->s.con[cid])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 		con = to_clt_con(sess->s.con[cid]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 		destroy_con_cq_qp(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 		destroy_cm(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 		destroy_con(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) static inline bool xchg_sessions(struct rtrs_clt_sess __rcu **rcu_ppcpu_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 				 struct rtrs_clt_sess *sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 				 struct rtrs_clt_sess *next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	struct rtrs_clt_sess **ppcpu_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	/* Call cmpxchg() without sparse warnings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	ppcpu_path = (typeof(ppcpu_path))rcu_ppcpu_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	return sess == cmpxchg(ppcpu_path, sess, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) static void rtrs_clt_remove_path_from_arr(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	struct rtrs_clt *clt = sess->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	struct rtrs_clt_sess *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 	bool wait_for_grace = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 	mutex_lock(&clt->paths_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 	list_del_rcu(&sess->s.entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	/* Make sure everybody observes path removal. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 	synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 	 * At this point nobody sees @sess in the list, but still we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	 * dangling pointer @pcpu_path which _can_ point to @sess.  Since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 	 * nobody can observe @sess in the list, we guarantee that IO path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 	 * will not assign @sess to @pcpu_path, i.e. @pcpu_path can be equal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	 * to @sess, but can never again become @sess.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 	 * Decrement paths number only after grace period, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 	 * caller of do_each_path() must firstly observe list without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	 * path and only then decremented paths number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 	 * Otherwise there can be the following situation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	 *    o Two paths exist and IO is coming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 	 *    o One path is removed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 	 *      CPU#0                          CPU#1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 	 *      do_each_path():                rtrs_clt_remove_path_from_arr():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	 *          path = get_next_path()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 	 *          ^^^                            list_del_rcu(path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 	 *          [!CONNECTED path]              clt->paths_num--
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	 *                                              ^^^^^^^^^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	 *          load clt->paths_num                 from 2 to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	 *                    ^^^^^^^^^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	 *                    sees 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 	 *      path is observed as !CONNECTED, but do_each_path() loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	 *      ends, because expression i < clt->paths_num is false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	clt->paths_num--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 	 * Get @next connection from current @sess which is going to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	 * removed.  If @sess is the last element, then @next is NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	next = list_next_or_null_rr_rcu(&clt->paths_list, &sess->s.entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 					typeof(*next), s.entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 	 * @pcpu paths can still point to the path which is going to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 	 * removed, so change the pointer manually.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 		struct rtrs_clt_sess __rcu **ppcpu_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 		ppcpu_path = per_cpu_ptr(clt->pcpu_path, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 		if (rcu_dereference_protected(*ppcpu_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 			lockdep_is_held(&clt->paths_mutex)) != sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 			 * synchronize_rcu() was called just after deleting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 			 * entry from the list, thus IO code path cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 			 * change pointer back to the pointer which is going
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 			 * to be removed, we are safe here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 		 * We race with IO code path, which also changes pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 		 * thus we have to be careful not to overwrite it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 		if (xchg_sessions(ppcpu_path, sess, next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 			 * @ppcpu_path was successfully replaced with @next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 			 * that means that someone could also pick up the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 			 * @sess and dereferencing it right now, so wait for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 			 * a grace period is required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 			wait_for_grace = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 	if (wait_for_grace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 		synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 	mutex_unlock(&clt->paths_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) static void rtrs_clt_add_path_to_arr(struct rtrs_clt_sess *sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 				      struct rtrs_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	struct rtrs_clt *clt = sess->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	mutex_lock(&clt->paths_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 	clt->paths_num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 	list_add_tail_rcu(&sess->s.entry, &clt->paths_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	mutex_unlock(&clt->paths_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) static void rtrs_clt_close_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	struct rtrs_clt_sess *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	sess = container_of(work, struct rtrs_clt_sess, close_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	cancel_delayed_work_sync(&sess->reconnect_dwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	rtrs_clt_stop_and_destroy_conns(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	rtrs_clt_change_state(sess, RTRS_CLT_CLOSED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) static int init_conns(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	unsigned int cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	 * On every new session connections increase reconnect counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	 * to avoid clashes with previous sessions not yet closed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 	 * sessions on a server side.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 	sess->s.recon_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 	/* Establish all RDMA connections  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	for (cid = 0; cid < sess->s.con_num; cid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 		err = create_con(sess, cid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 			goto destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 		err = create_cm(to_clt_con(sess->s.con[cid]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 			destroy_con(to_clt_con(sess->s.con[cid]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 			goto destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	err = alloc_sess_reqs(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 		goto destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 	rtrs_clt_start_hb(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) destroy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	while (cid--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 		struct rtrs_clt_con *con = to_clt_con(sess->s.con[cid]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 		stop_cm(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 		destroy_con_cq_qp(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 		destroy_cm(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 		destroy_con(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	 * If we've never taken async path and got an error, say,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	 * doing rdma_resolve_addr(), switch to CONNECTION_ERR state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	 * manually to keep reconnecting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	rtrs_clt_change_state(sess, RTRS_CLT_CONNECTING_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) static void rtrs_clt_info_req_done(struct ib_cq *cq, struct ib_wc *wc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	struct rtrs_clt_con *con = cq->cq_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	struct rtrs_iu *iu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 	iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	rtrs_iu_free(iu, sess->s.dev->ib_dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 		rtrs_err(sess->clt, "Sess info request send failed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 			  ib_wc_status_msg(wc->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 		rtrs_clt_change_state(sess, RTRS_CLT_CONNECTING_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	rtrs_clt_update_wc_stats(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) static int process_info_rsp(struct rtrs_clt_sess *sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 			    const struct rtrs_msg_info_rsp *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	unsigned int sg_cnt, total_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	int i, sgi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	sg_cnt = le16_to_cpu(msg->sg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	if (unlikely(!sg_cnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 	 * Check if IB immediate data size is enough to hold the mem_id and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	 * the offset inside the memory chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	if (unlikely((ilog2(sg_cnt - 1) + 1) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 		     (ilog2(sess->chunk_size - 1) + 1) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 		     MAX_IMM_PAYL_BITS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 		rtrs_err(sess->clt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 			  "RDMA immediate size (%db) not enough to encode %d buffers of size %dB\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 			  MAX_IMM_PAYL_BITS, sg_cnt, sess->chunk_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	if (unlikely(!sg_cnt || (sess->queue_depth % sg_cnt))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 		rtrs_err(sess->clt, "Incorrect sg_cnt %d, is not multiple\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 			  sg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 	total_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	for (sgi = 0, i = 0; sgi < sg_cnt && i < sess->queue_depth; sgi++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 		const struct rtrs_sg_desc *desc = &msg->desc[sgi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 		u32 len, rkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 		u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 		addr = le64_to_cpu(desc->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 		rkey = le32_to_cpu(desc->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 		len  = le32_to_cpu(desc->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 		total_len += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 		if (unlikely(!len || (len % sess->chunk_size))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 			rtrs_err(sess->clt, "Incorrect [%d].len %d\n", sgi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 				  len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 		for ( ; len && i < sess->queue_depth; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 			sess->rbufs[i].addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 			sess->rbufs[i].rkey = rkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 			len  -= sess->chunk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 			addr += sess->chunk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	/* Sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	if (unlikely(sgi != sg_cnt || i != sess->queue_depth)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 		rtrs_err(sess->clt, "Incorrect sg vector, not fully mapped\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	if (unlikely(total_len != sess->chunk_size * sess->queue_depth)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 		rtrs_err(sess->clt, "Incorrect total_len %d\n", total_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) static void rtrs_clt_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	struct rtrs_clt_con *con = cq->cq_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	struct rtrs_clt_sess *sess = to_clt_sess(con->c.sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 	struct rtrs_msg_info_rsp *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	enum rtrs_clt_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	struct rtrs_iu *iu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	size_t rx_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	state = RTRS_CLT_CONNECTING_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	WARN_ON(con->c.cid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	if (unlikely(wc->status != IB_WC_SUCCESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 		rtrs_err(sess->clt, "Sess info response recv failed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 			  ib_wc_status_msg(wc->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	WARN_ON(wc->opcode != IB_WC_RECV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 	if (unlikely(wc->byte_len < sizeof(*msg))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 		rtrs_err(sess->clt, "Sess info response is malformed: size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 			  wc->byte_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	ib_dma_sync_single_for_cpu(sess->s.dev->ib_dev, iu->dma_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 				   iu->size, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	msg = iu->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	if (unlikely(le16_to_cpu(msg->type) != RTRS_MSG_INFO_RSP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 		rtrs_err(sess->clt, "Sess info response is malformed: type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 			  le16_to_cpu(msg->type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	rx_sz  = sizeof(*msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	rx_sz += sizeof(msg->desc[0]) * le16_to_cpu(msg->sg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	if (unlikely(wc->byte_len < rx_sz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 		rtrs_err(sess->clt, "Sess info response is malformed: size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 			  wc->byte_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	err = process_info_rsp(sess, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 	err = post_recv_sess(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 	if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 	state = RTRS_CLT_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	rtrs_clt_update_wc_stats(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 	rtrs_iu_free(iu, sess->s.dev->ib_dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 	rtrs_clt_change_state(sess, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) static int rtrs_send_sess_info(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	struct rtrs_clt_con *usr_con = to_clt_con(sess->s.con[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	struct rtrs_msg_info_req *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	struct rtrs_iu *tx_iu, *rx_iu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	size_t rx_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	rx_sz  = sizeof(struct rtrs_msg_info_rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 	rx_sz += sizeof(u64) * MAX_SESS_QUEUE_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 	tx_iu = rtrs_iu_alloc(1, sizeof(struct rtrs_msg_info_req), GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 			       sess->s.dev->ib_dev, DMA_TO_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 			       rtrs_clt_info_req_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	rx_iu = rtrs_iu_alloc(1, rx_sz, GFP_KERNEL, sess->s.dev->ib_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 			       DMA_FROM_DEVICE, rtrs_clt_info_rsp_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	if (unlikely(!tx_iu || !rx_iu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	/* Prepare for getting info response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 	err = rtrs_iu_post_recv(&usr_con->c, rx_iu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 	if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 		rtrs_err(sess->clt, "rtrs_iu_post_recv(), err: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 	rx_iu = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 	msg = tx_iu->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 	msg->type = cpu_to_le16(RTRS_MSG_INFO_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	memcpy(msg->sessname, sess->s.sessname, sizeof(msg->sessname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 	ib_dma_sync_single_for_device(sess->s.dev->ib_dev, tx_iu->dma_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 				      tx_iu->size, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	/* Send info request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 	err = rtrs_iu_post_send(&usr_con->c, tx_iu, sizeof(*msg), NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 		rtrs_err(sess->clt, "rtrs_iu_post_send(), err: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 	tx_iu = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	/* Wait for state change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 	wait_event_interruptible_timeout(sess->state_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 					 sess->state != RTRS_CLT_CONNECTING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 					 msecs_to_jiffies(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 						 RTRS_CONNECT_TIMEOUT_MS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	if (unlikely(READ_ONCE(sess->state) != RTRS_CLT_CONNECTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 		if (READ_ONCE(sess->state) == RTRS_CLT_CONNECTING_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 			err = -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 			err = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	if (tx_iu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 		rtrs_iu_free(tx_iu, sess->s.dev->ib_dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	if (rx_iu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 		rtrs_iu_free(rx_iu, sess->s.dev->ib_dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 		/* If we've never taken async path because of malloc problems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 		rtrs_clt_change_state(sess, RTRS_CLT_CONNECTING_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475)  * init_sess() - establishes all session connections and does handshake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476)  * @sess: client session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477)  * In case of error full close or reconnect procedure should be taken,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478)  * because reconnect or close async works can be started.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) static int init_sess(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 	mutex_lock(&sess->init_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	err = init_conns(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 		rtrs_err(sess->clt, "init_conns(), err: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	err = rtrs_send_sess_info(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 		rtrs_err(sess->clt, "rtrs_send_sess_info(), err: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	rtrs_clt_sess_up(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 	mutex_unlock(&sess->init_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) static void rtrs_clt_reconnect_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	struct rtrs_clt_sess *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	struct rtrs_clt *clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	unsigned int delay_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 	sess = container_of(to_delayed_work(work), struct rtrs_clt_sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 			    reconnect_dwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	clt = sess->clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	if (READ_ONCE(sess->state) != RTRS_CLT_RECONNECTING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 	if (sess->reconnect_attempts >= clt->max_reconnect_attempts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 		/* Close a session completely if max attempts is reached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 		rtrs_clt_close_conns(sess, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 	sess->reconnect_attempts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	/* Stop everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	rtrs_clt_stop_and_destroy_conns(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	msleep(RTRS_RECONNECT_BACKOFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	if (rtrs_clt_change_state(sess, RTRS_CLT_CONNECTING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 		err = init_sess(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 			goto reconnect_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) reconnect_again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	if (rtrs_clt_change_state(sess, RTRS_CLT_RECONNECTING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 		sess->stats->reconnects.fail_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 		delay_ms = clt->reconnect_delay_sec * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 		queue_delayed_work(rtrs_wq, &sess->reconnect_dwork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 				   msecs_to_jiffies(delay_ms +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 						    prandom_u32() %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 						    RTRS_RECONNECT_SEED));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) static void rtrs_clt_dev_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	struct rtrs_clt *clt = container_of(dev, struct rtrs_clt, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	mutex_destroy(&clt->paths_ev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	mutex_destroy(&clt->paths_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	kfree(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) static struct rtrs_clt *alloc_clt(const char *sessname, size_t paths_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 				  u16 port, size_t pdu_sz, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 				  void	(*link_ev)(void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 						   enum rtrs_clt_link_ev ev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 				  unsigned int max_segments,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 				  size_t max_segment_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 				  unsigned int reconnect_delay_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 				  unsigned int max_reconnect_attempts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	struct rtrs_clt *clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 	if (!paths_num || paths_num > MAX_PATHS_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	if (strlen(sessname) >= sizeof(clt->sessname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	clt = kzalloc(sizeof(*clt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 	if (!clt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	clt->pcpu_path = alloc_percpu(typeof(*clt->pcpu_path));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 	if (!clt->pcpu_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 		kfree(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 	clt->dev.class = rtrs_clt_dev_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	clt->dev.release = rtrs_clt_dev_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	uuid_gen(&clt->paths_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	INIT_LIST_HEAD_RCU(&clt->paths_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	clt->paths_num = paths_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 	clt->paths_up = MAX_PATHS_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	clt->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	clt->pdu_sz = pdu_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 	clt->max_segments = max_segments;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 	clt->max_segment_size = max_segment_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 	clt->reconnect_delay_sec = reconnect_delay_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	clt->max_reconnect_attempts = max_reconnect_attempts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	clt->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	clt->link_ev = link_ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 	clt->mp_policy = MP_POLICY_MIN_INFLIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	strlcpy(clt->sessname, sessname, sizeof(clt->sessname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	init_waitqueue_head(&clt->permits_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 	mutex_init(&clt->paths_ev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	mutex_init(&clt->paths_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	device_initialize(&clt->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	err = dev_set_name(&clt->dev, "%s", sessname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 		goto err_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	 * Suppress user space notification until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 	 * sysfs files are created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 	dev_set_uevent_suppress(&clt->dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 	err = device_add(&clt->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 		goto err_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	clt->kobj_paths = kobject_create_and_add("paths", &clt->dev.kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 	if (!clt->kobj_paths) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 		goto err_del;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 	err = rtrs_clt_create_sysfs_root_files(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 		kobject_del(clt->kobj_paths);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 		kobject_put(clt->kobj_paths);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 		goto err_del;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 	dev_set_uevent_suppress(&clt->dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	kobject_uevent(&clt->dev.kobj, KOBJ_ADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	return clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) err_del:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	device_del(&clt->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) err_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	free_percpu(clt->pcpu_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	put_device(&clt->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) static void free_clt(struct rtrs_clt *clt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	free_percpu(clt->pcpu_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 	 * release callback will free clt and destroy mutexes in last put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 	device_unregister(&clt->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)  * rtrs_clt_open() - Open a session to an RTRS server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)  * @ops: holds the link event callback and the private pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)  * @sessname: name of the session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)  * @paths: Paths to be established defined by their src and dst addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654)  * @paths_num: Number of elements in the @paths array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655)  * @port: port to be used by the RTRS session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)  * @pdu_sz: Size of extra payload which can be accessed after permit allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657)  * @reconnect_delay_sec: time between reconnect tries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)  * @max_segments: Max. number of segments per IO request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659)  * @max_segment_size: Max. size of one segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660)  * @max_reconnect_attempts: Number of times to reconnect on error before giving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661)  *			    up, 0 for * disabled, -1 for forever
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663)  * Starts session establishment with the rtrs_server. The function can block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)  * up to ~2000ms before it returns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)  * Return a valid pointer on success otherwise PTR_ERR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 				 const char *sessname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 				 const struct rtrs_addr *paths,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 				 size_t paths_num, u16 port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 				 size_t pdu_sz, u8 reconnect_delay_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 				 u16 max_segments,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 				 size_t max_segment_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 				 s16 max_reconnect_attempts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 	struct rtrs_clt_sess *sess, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	struct rtrs_clt *clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	clt = alloc_clt(sessname, paths_num, port, pdu_sz, ops->priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 			ops->link_ev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 			max_segments, max_segment_size, reconnect_delay_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 			max_reconnect_attempts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 	if (IS_ERR(clt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 		err = PTR_ERR(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 	for (i = 0; i < paths_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 		struct rtrs_clt_sess *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 		sess = alloc_sess(clt, &paths[i], nr_cpu_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 				  max_segments, max_segment_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 		if (IS_ERR(sess)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 			err = PTR_ERR(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 			goto close_all_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 		if (!i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 			sess->for_new_clt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 		list_add_tail_rcu(&sess->s.entry, &clt->paths_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 		err = init_sess(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 			list_del_rcu(&sess->s.entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 			rtrs_clt_close_conns(sess, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 			free_percpu(sess->stats->pcpu_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 			kfree(sess->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 			free_sess(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 			goto close_all_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 		err = rtrs_clt_create_sess_files(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 			list_del_rcu(&sess->s.entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 			rtrs_clt_close_conns(sess, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 			free_percpu(sess->stats->pcpu_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 			kfree(sess->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 			free_sess(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 			goto close_all_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 	err = alloc_permits(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 		goto close_all_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 	return clt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) close_all_sess:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	list_for_each_entry_safe(sess, tmp, &clt->paths_list, s.entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 		rtrs_clt_destroy_sess_files(sess, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 		rtrs_clt_close_conns(sess, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 		kobject_put(&sess->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 	rtrs_clt_destroy_sysfs_root_files(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 	rtrs_clt_destroy_sysfs_root_folders(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 	free_clt(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) EXPORT_SYMBOL(rtrs_clt_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744)  * rtrs_clt_close() - Close a session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)  * @clt: Session handle. Session is freed upon return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) void rtrs_clt_close(struct rtrs_clt *clt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 	struct rtrs_clt_sess *sess, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	/* Firstly forbid sysfs access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	rtrs_clt_destroy_sysfs_root_files(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 	rtrs_clt_destroy_sysfs_root_folders(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	/* Now it is safe to iterate over all paths without locks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 	list_for_each_entry_safe(sess, tmp, &clt->paths_list, s.entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 		rtrs_clt_close_conns(sess, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 		rtrs_clt_destroy_sess_files(sess, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 		kobject_put(&sess->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 	free_permits(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	free_clt(clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) EXPORT_SYMBOL(rtrs_clt_close);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) int rtrs_clt_reconnect_from_sysfs(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 	enum rtrs_clt_state old_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 	int err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 	bool changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 	changed = rtrs_clt_change_state_get_old(sess, RTRS_CLT_RECONNECTING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 						 &old_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 	if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 		sess->reconnect_attempts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 		queue_delayed_work(rtrs_wq, &sess->reconnect_dwork, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 	if (changed || old_state == RTRS_CLT_RECONNECTING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 		 * flush_delayed_work() queues pending work for immediate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 		 * execution, so do the flush if we have queued something
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 		 * right now or work is pending.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 		flush_delayed_work(&sess->reconnect_dwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 		err = (READ_ONCE(sess->state) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 		       RTRS_CLT_CONNECTED ? 0 : -ENOTCONN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) int rtrs_clt_disconnect_from_sysfs(struct rtrs_clt_sess *sess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 	rtrs_clt_close_conns(sess, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) int rtrs_clt_remove_path_from_sysfs(struct rtrs_clt_sess *sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 				     const struct attribute *sysfs_self)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 	enum rtrs_clt_state old_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	bool changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 	 * Continue stopping path till state was changed to DEAD or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 	 * state was observed as DEAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 	 * 1. State was changed to DEAD - we were fast and nobody
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 	 *    invoked rtrs_clt_reconnect(), which can again start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 	 *    reconnecting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 	 * 2. State was observed as DEAD - we have someone in parallel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	 *    removing the path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 		rtrs_clt_close_conns(sess, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 		changed = rtrs_clt_change_state_get_old(sess,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 							RTRS_CLT_DEAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 							&old_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	} while (!changed && old_state != RTRS_CLT_DEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	if (likely(changed)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 		rtrs_clt_remove_path_from_arr(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 		rtrs_clt_destroy_sess_files(sess, sysfs_self);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 		kobject_put(&sess->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) void rtrs_clt_set_max_reconnect_attempts(struct rtrs_clt *clt, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 	clt->max_reconnect_attempts = (unsigned int)value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) int rtrs_clt_get_max_reconnect_attempts(const struct rtrs_clt *clt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 	return (int)clt->max_reconnect_attempts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841)  * rtrs_clt_request() - Request data transfer to/from server via RDMA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843)  * @dir:	READ/WRITE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844)  * @ops:	callback function to be called as confirmation, and the pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845)  * @clt:	Session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846)  * @permit:	Preallocated permit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)  * @vec:	Message that is sent to server together with the request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848)  *		Sum of len of all @vec elements limited to <= IO_MSG_SIZE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849)  *		Since the msg is copied internally it can be allocated on stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850)  * @nr:		Number of elements in @vec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851)  * @data_len:	length of data sent to/from server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)  * @sg:		Pages to be sent/received to/from server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853)  * @sg_cnt:	Number of elements in the @sg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855)  * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856)  * 0:		Success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857)  * <0:		Error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859)  * On dir=READ rtrs client will request a data transfer from Server to client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860)  * The data that the server will respond with will be stored in @sg when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861)  * the user receives an %RTRS_CLT_RDMA_EV_RDMA_REQUEST_WRITE_COMPL event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862)  * On dir=WRITE rtrs client will rdma write data in sg to server side.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) int rtrs_clt_request(int dir, struct rtrs_clt_req_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 		     struct rtrs_clt *clt, struct rtrs_permit *permit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 		      const struct kvec *vec, size_t nr, size_t data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 		      struct scatterlist *sg, unsigned int sg_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 	struct rtrs_clt_io_req *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 	struct rtrs_clt_sess *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 	enum dma_data_direction dma_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	int err = -ECONNABORTED, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 	size_t usr_len, hdr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 	struct path_it it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 	/* Get kvec length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 	for (i = 0, usr_len = 0; i < nr; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 		usr_len += vec[i].iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 	if (dir == READ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 		hdr_len = sizeof(struct rtrs_msg_rdma_read) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 			  sg_cnt * sizeof(struct rtrs_sg_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 		dma_dir = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 		hdr_len = sizeof(struct rtrs_msg_rdma_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 		dma_dir = DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	for (path_it_init(&it, clt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 	     (sess = it.next_path(&it)) && it.i < it.clt->paths_num; it.i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 		if (unlikely(READ_ONCE(sess->state) != RTRS_CLT_CONNECTED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 		if (unlikely(usr_len + hdr_len > sess->max_hdr_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 			rtrs_wrn_rl(sess->clt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 				     "%s request failed, user message size is %zu and header length %zu, but max size is %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 				     dir == READ ? "Read" : "Write",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 				     usr_len, hdr_len, sess->max_hdr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 			err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		req = rtrs_clt_get_req(sess, ops->conf_fn, permit, ops->priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 				       vec, usr_len, sg, sg_cnt, data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 				       dma_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 		if (dir == READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 			err = rtrs_clt_read_req(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 			err = rtrs_clt_write_req(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 		if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 			req->in_use = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 		/* Success path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 	path_it_deinit(&it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) EXPORT_SYMBOL(rtrs_clt_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926)  * rtrs_clt_query() - queries RTRS session attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927)  *@clt: session pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928)  *@attr: query results for session attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930)  *    0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931)  *    -ECOMM		no connection to the server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) int rtrs_clt_query(struct rtrs_clt *clt, struct rtrs_attrs *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	if (!rtrs_clt_is_connected(clt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 		return -ECOMM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 	attr->queue_depth      = clt->queue_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 	attr->max_io_size      = clt->max_io_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 	attr->sess_kobj	       = &clt->dev.kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 	strlcpy(attr->sessname, clt->sessname, sizeof(attr->sessname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) EXPORT_SYMBOL(rtrs_clt_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) int rtrs_clt_create_path_from_sysfs(struct rtrs_clt *clt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 				     struct rtrs_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 	struct rtrs_clt_sess *sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	sess = alloc_sess(clt, addr, nr_cpu_ids, clt->max_segments,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 			  clt->max_segment_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 	if (IS_ERR(sess))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 		return PTR_ERR(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 	 * It is totally safe to add path in CONNECTING state: coming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 	 * IO will never grab it.  Also it is very important to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 	 * path before init, since init fires LINK_CONNECTED event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 	rtrs_clt_add_path_to_arr(sess, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	err = init_sess(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 		goto close_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 	err = rtrs_clt_create_sess_files(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 		goto close_sess;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) close_sess:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 	rtrs_clt_remove_path_from_arr(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 	rtrs_clt_close_conns(sess, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 	free_percpu(sess->stats->pcpu_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 	kfree(sess->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 	free_sess(sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) static int rtrs_clt_ib_dev_init(struct rtrs_ib_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	if (!(dev->ib_dev->attrs.device_cap_flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 	      IB_DEVICE_MEM_MGT_EXTENSIONS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 		pr_err("Memory registrations not supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 		return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) static const struct rtrs_rdma_dev_pd_ops dev_pd_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 	.init = rtrs_clt_ib_dev_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) static int __init rtrs_client_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	rtrs_rdma_dev_pd_init(0, &dev_pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	rtrs_clt_dev_class = class_create(THIS_MODULE, "rtrs-client");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	if (IS_ERR(rtrs_clt_dev_class)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 		pr_err("Failed to create rtrs-client dev class\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 		return PTR_ERR(rtrs_clt_dev_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 	rtrs_wq = alloc_workqueue("rtrs_client_wq", 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	if (!rtrs_wq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 		class_destroy(rtrs_clt_dev_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) static void __exit rtrs_client_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 	destroy_workqueue(rtrs_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 	class_destroy(rtrs_clt_dev_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 	rtrs_rdma_dev_pd_deinit(&dev_pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) module_init(rtrs_client_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) module_exit(rtrs_client_exit);