// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * RDMA Transport Layer
 *
 * Copyright (c) 2014 - 2018 ProfitBricks GmbH. All rights reserved.
 * Copyright (c) 2018 - 2019 1&1 IONOS Cloud GmbH. All rights reserved.
 * Copyright (c) 2019 - 2020 1&1 IONOS SE. All rights reserved.
 */

#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt

#include <linux/module.h>

#include "rtrs-srv.h"
#include "rtrs-log.h"
#include <rdma/ib_cm.h>
#include <rdma/ib_verbs.h>
#include "rtrs-srv-trace.h"

MODULE_DESCRIPTION("RDMA Transport Server");
MODULE_LICENSE("GPL");

/* Must be power of 2, see mask from mr->page_size in ib_sg_to_pages() */
#define DEFAULT_MAX_CHUNK_SIZE (128 << 10)
#define DEFAULT_SESS_QUEUE_DEPTH 512
#define MAX_HDR_SIZE PAGE_SIZE

static const struct rtrs_rdma_dev_pd_ops dev_pd_ops;
static struct rtrs_rdma_dev_pd dev_pd = {
	.ops = &dev_pd_ops
};
const struct class rtrs_dev_class = {
	.name = "rtrs-server",
};
static struct rtrs_srv_ib_ctx ib_ctx;

static int __read_mostly max_chunk_size = DEFAULT_MAX_CHUNK_SIZE;
static int __read_mostly sess_queue_depth = DEFAULT_SESS_QUEUE_DEPTH;

static bool always_invalidate = true;
module_param(always_invalidate, bool, 0444);
MODULE_PARM_DESC(always_invalidate,
		 "Invalidate memory registration for contiguous memory regions before accessing.");

module_param_named(max_chunk_size, max_chunk_size, int, 0444);
MODULE_PARM_DESC(max_chunk_size,
		 "Max size for each IO request, when change the unit is in byte (default: "
		 __stringify(DEFAULT_MAX_CHUNK_SIZE) "KB)");

module_param_named(sess_queue_depth, sess_queue_depth, int, 0444);
MODULE_PARM_DESC(sess_queue_depth,
		 "Number of buffers for pending I/O requests to allocate per session. Maximum: "
		 __stringify(MAX_SESS_QUEUE_DEPTH) " (default: "
		 __stringify(DEFAULT_SESS_QUEUE_DEPTH) ")");

static cpumask_t cq_affinity_mask = { CPU_BITS_ALL };

static struct workqueue_struct *rtrs_wq;

static inline struct rtrs_srv_con *to_srv_con(struct rtrs_con *c)
{
	return container_of(c, struct rtrs_srv_con, c);
}

static bool rtrs_srv_change_state(struct rtrs_srv_path *srv_path,
				  enum rtrs_srv_state new_state)
{
	enum rtrs_srv_state old_state;
	bool changed = false;
	unsigned long flags;

	spin_lock_irqsave(&srv_path->state_lock, flags);
	old_state = srv_path->state;
	switch (new_state) {
	case RTRS_SRV_CONNECTED:
		if (old_state == RTRS_SRV_CONNECTING)
			changed = true;
		break;
	case RTRS_SRV_CLOSING:
		if (old_state == RTRS_SRV_CONNECTING ||
		    old_state == RTRS_SRV_CONNECTED)
			changed = true;
		break;
	case RTRS_SRV_CLOSED:
		if (old_state == RTRS_SRV_CLOSING)
			changed = true;
		break;
	default:
		break;
	}
	if (changed)
		srv_path->state = new_state;
	spin_unlock_irqrestore(&srv_path->state_lock, flags);

	return changed;
}

static void free_id(struct rtrs_srv_op *id)
{
	if (!id)
		return;
	kfree(id);
}

static void rtrs_srv_free_ops_ids(struct rtrs_srv_path *srv_path)
{
	struct rtrs_srv_sess *srv = srv_path->srv;
	int i;

	if (srv_path->ops_ids) {
		for (i = 0; i < srv->queue_depth; i++)
			free_id(srv_path->ops_ids[i]);
		kfree(srv_path->ops_ids);
		srv_path->ops_ids = NULL;
	}
}

static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc);

static struct ib_cqe io_comp_cqe = {
	.done = rtrs_srv_rdma_done
};

static inline void rtrs_srv_inflight_ref_release(struct percpu_ref *ref)
{
	struct rtrs_srv_path *srv_path = container_of(ref,
						      struct rtrs_srv_path,
						      ids_inflight_ref);

	percpu_ref_exit(&srv_path->ids_inflight_ref);
	complete(&srv_path->complete_done);
}

static int rtrs_srv_alloc_ops_ids(struct rtrs_srv_path *srv_path)
{
	struct rtrs_srv_sess *srv = srv_path->srv;
	struct rtrs_srv_op *id;
	int i, ret;

	srv_path->ops_ids = kcalloc(srv->queue_depth,
				    sizeof(*srv_path->ops_ids),
				    GFP_KERNEL);
	if (!srv_path->ops_ids)
		goto err;

	for (i = 0; i < srv->queue_depth; ++i) {
		id = kzalloc(sizeof(*id), GFP_KERNEL);
		if (!id)
			goto err;

		srv_path->ops_ids[i] = id;
	}

	ret = percpu_ref_init(&srv_path->ids_inflight_ref,
			      rtrs_srv_inflight_ref_release, 0, GFP_KERNEL);
	if (ret) {
		pr_err("Percpu reference init failed\n");
		goto err;
	}
	init_completion(&srv_path->complete_done);

	return 0;

err:
	rtrs_srv_free_ops_ids(srv_path);
	return -ENOMEM;
}

static inline void rtrs_srv_get_ops_ids(struct rtrs_srv_path *srv_path)
{
	percpu_ref_get(&srv_path->ids_inflight_ref);
}

static inline void rtrs_srv_put_ops_ids(struct rtrs_srv_path *srv_path)
{
	percpu_ref_put(&srv_path->ids_inflight_ref);
}

static void rtrs_srv_reg_mr_done(struct ib_cq *cq, struct ib_wc *wc)
{
	struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
	struct rtrs_path *s = con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);

	if (wc->status != IB_WC_SUCCESS) {
		rtrs_err(s, "REG MR failed: %s\n",
			  ib_wc_status_msg(wc->status));
		close_path(srv_path);
		return;
	}
}

static struct ib_cqe local_reg_cqe = {
	.done = rtrs_srv_reg_mr_done
};

static int rdma_write_sg(struct rtrs_srv_op *id)
{
	struct rtrs_path *s = id->con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);
	dma_addr_t dma_addr = srv_path->dma_addr[id->msg_id];
	struct rtrs_srv_mr *srv_mr;
	struct ib_send_wr inv_wr;
	struct ib_rdma_wr imm_wr;
	struct ib_rdma_wr *wr = NULL;
	enum ib_send_flags flags;
	size_t sg_cnt;
	int err, offset;
	bool need_inval;
	u32 rkey = 0;
	struct ib_reg_wr rwr;
	struct ib_sge *plist;
	struct ib_sge list;

	sg_cnt = le16_to_cpu(id->rd_msg->sg_cnt);
	need_inval = le16_to_cpu(id->rd_msg->flags) & RTRS_MSG_NEED_INVAL_F;
	if (sg_cnt != 1)
		return -EINVAL;

	offset = 0;

	wr		= &id->tx_wr;
	plist		= &id->tx_sg;
	plist->addr	= dma_addr + offset;
	plist->length	= le32_to_cpu(id->rd_msg->desc[0].len);

	/* WR will fail with length error
	 * if this is 0
	 */
	if (plist->length == 0) {
		rtrs_err(s, "Invalid RDMA-Write sg list length 0\n");
		return -EINVAL;
	}

	plist->lkey = srv_path->s.dev->ib_pd->local_dma_lkey;
	offset += plist->length;

	wr->wr.sg_list	= plist;
	wr->wr.num_sge	= 1;
	wr->remote_addr	= le64_to_cpu(id->rd_msg->desc[0].addr);
	wr->rkey	= le32_to_cpu(id->rd_msg->desc[0].key);
	if (rkey == 0)
		rkey = wr->rkey;
	else
		/* Only one key is actually used */
		WARN_ON_ONCE(rkey != wr->rkey);

	wr->wr.opcode = IB_WR_RDMA_WRITE;
	wr->wr.wr_cqe   = &io_comp_cqe;
	wr->wr.ex.imm_data = 0;
	wr->wr.send_flags  = 0;

	if (need_inval && always_invalidate) {
		wr->wr.next = &rwr.wr;
		rwr.wr.next = &inv_wr;
		inv_wr.next = &imm_wr.wr;
	} else if (always_invalidate) {
		wr->wr.next = &rwr.wr;
		rwr.wr.next = &imm_wr.wr;
	} else if (need_inval) {
		wr->wr.next = &inv_wr;
		inv_wr.next = &imm_wr.wr;
	} else {
		wr->wr.next = &imm_wr.wr;
	}
	/*
	 * From time to time we have to post signaled sends,
	 * or send queue will fill up and only QP reset can help.
	 */
	flags = (atomic_inc_return(&id->con->c.wr_cnt) % s->signal_interval) ?
		0 : IB_SEND_SIGNALED;

	if (need_inval) {
		inv_wr.sg_list = NULL;
		inv_wr.num_sge = 0;
		inv_wr.opcode = IB_WR_SEND_WITH_INV;
		inv_wr.wr_cqe   = &io_comp_cqe;
		inv_wr.send_flags = 0;
		inv_wr.ex.invalidate_rkey = rkey;
	}

	imm_wr.wr.next = NULL;
	if (always_invalidate) {
		struct rtrs_msg_rkey_rsp *msg;

		srv_mr = &srv_path->mrs[id->msg_id];
		rwr.wr.opcode = IB_WR_REG_MR;
		rwr.wr.wr_cqe = &local_reg_cqe;
		rwr.wr.num_sge = 0;
		rwr.mr = srv_mr->mr;
		rwr.wr.send_flags = 0;
		rwr.key = srv_mr->mr->rkey;
		rwr.access = (IB_ACCESS_LOCAL_WRITE |
			      IB_ACCESS_REMOTE_WRITE);
		msg = srv_mr->iu->buf;
		msg->buf_id = cpu_to_le16(id->msg_id);
		msg->type = cpu_to_le16(RTRS_MSG_RKEY_RSP);
		msg->rkey = cpu_to_le32(srv_mr->mr->rkey);

		list.addr   = srv_mr->iu->dma_addr;
		list.length = sizeof(*msg);
		list.lkey   = srv_path->s.dev->ib_pd->local_dma_lkey;
		imm_wr.wr.sg_list = &list;
		imm_wr.wr.num_sge = 1;
		imm_wr.wr.opcode = IB_WR_SEND_WITH_IMM;
		ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev,
					      srv_mr->iu->dma_addr,
					      srv_mr->iu->size, DMA_TO_DEVICE);
	} else {
		imm_wr.wr.sg_list = NULL;
		imm_wr.wr.num_sge = 0;
		imm_wr.wr.opcode = IB_WR_RDMA_WRITE_WITH_IMM;
	}
	imm_wr.wr.send_flags = flags;
	imm_wr.wr.ex.imm_data = cpu_to_be32(rtrs_to_io_rsp_imm(id->msg_id,
							     0, need_inval));

	imm_wr.wr.wr_cqe   = &io_comp_cqe;
	ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev, dma_addr,
				      offset, DMA_BIDIRECTIONAL);

	err = ib_post_send(id->con->c.qp, &id->tx_wr.wr, NULL);
	if (err)
		rtrs_err(s,
			  "Posting RDMA-Write-Request to QP failed, err: %d\n",
			  err);

	return err;
}

/**
 * send_io_resp_imm() - respond to client with empty IMM on failed READ/WRITE
 *                      requests or on successful WRITE request.
 * @con:	the connection to send back result
 * @id:		the id associated with the IO
 * @errno:	the error number of the IO.
 *
 * Return 0 on success, errno otherwise.
 */
static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
			    int errno)
{
	struct rtrs_path *s = con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);
	struct ib_send_wr inv_wr, *wr = NULL;
	struct ib_rdma_wr imm_wr;
	struct ib_reg_wr rwr;
	struct rtrs_srv_mr *srv_mr;
	bool need_inval = false;
	enum ib_send_flags flags;
	u32 imm;
	int err;

	if (id->dir == READ) {
		struct rtrs_msg_rdma_read *rd_msg = id->rd_msg;
		size_t sg_cnt;

		need_inval = le16_to_cpu(rd_msg->flags) &
				RTRS_MSG_NEED_INVAL_F;
		sg_cnt = le16_to_cpu(rd_msg->sg_cnt);

		if (need_inval) {
			if (sg_cnt) {
				inv_wr.wr_cqe   = &io_comp_cqe;
				inv_wr.sg_list = NULL;
				inv_wr.num_sge = 0;
				inv_wr.opcode = IB_WR_SEND_WITH_INV;
				inv_wr.send_flags = 0;
				/* Only one key is actually used */
				inv_wr.ex.invalidate_rkey =
					le32_to_cpu(rd_msg->desc[0].key);
			} else {
				WARN_ON_ONCE(1);
				need_inval = false;
			}
		}
	}

	trace_send_io_resp_imm(id, need_inval, always_invalidate, errno);

	if (need_inval && always_invalidate) {
		wr = &inv_wr;
		inv_wr.next = &rwr.wr;
		rwr.wr.next = &imm_wr.wr;
	} else if (always_invalidate) {
		wr = &rwr.wr;
		rwr.wr.next = &imm_wr.wr;
	} else if (need_inval) {
		wr = &inv_wr;
		inv_wr.next = &imm_wr.wr;
	} else {
		wr = &imm_wr.wr;
	}
	/*
	 * From time to time we have to post signalled sends,
	 * or send queue will fill up and only QP reset can help.
	 */
	flags = (atomic_inc_return(&con->c.wr_cnt) % s->signal_interval) ?
		0 : IB_SEND_SIGNALED;
	imm = rtrs_to_io_rsp_imm(id->msg_id, errno, need_inval);
	imm_wr.wr.next = NULL;
	if (always_invalidate) {
		struct ib_sge list;
		struct rtrs_msg_rkey_rsp *msg;

		srv_mr = &srv_path->mrs[id->msg_id];
		rwr.wr.next = &imm_wr.wr;
		rwr.wr.opcode = IB_WR_REG_MR;
		rwr.wr.wr_cqe = &local_reg_cqe;
		rwr.wr.num_sge = 0;
		rwr.wr.send_flags = 0;
		rwr.mr = srv_mr->mr;
		rwr.key = srv_mr->mr->rkey;
		rwr.access = (IB_ACCESS_LOCAL_WRITE |
			      IB_ACCESS_REMOTE_WRITE);
		msg = srv_mr->iu->buf;
		msg->buf_id = cpu_to_le16(id->msg_id);
		msg->type = cpu_to_le16(RTRS_MSG_RKEY_RSP);
		msg->rkey = cpu_to_le32(srv_mr->mr->rkey);

		list.addr   = srv_mr->iu->dma_addr;
		list.length = sizeof(*msg);
		list.lkey   = srv_path->s.dev->ib_pd->local_dma_lkey;
		imm_wr.wr.sg_list = &list;
		imm_wr.wr.num_sge = 1;
		imm_wr.wr.opcode = IB_WR_SEND_WITH_IMM;
		ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev,
					      srv_mr->iu->dma_addr,
					      srv_mr->iu->size, DMA_TO_DEVICE);
	} else {
		imm_wr.wr.sg_list = NULL;
		imm_wr.wr.num_sge = 0;
		imm_wr.wr.opcode = IB_WR_RDMA_WRITE_WITH_IMM;
	}
	imm_wr.wr.send_flags = flags;
	imm_wr.wr.wr_cqe   = &io_comp_cqe;

	imm_wr.wr.ex.imm_data = cpu_to_be32(imm);

	err = ib_post_send(id->con->c.qp, wr, NULL);
	if (err)
		rtrs_err_rl(s, "Posting RDMA-Reply to QP failed, err: %d\n",
			     err);

	return err;
}

void close_path(struct rtrs_srv_path *srv_path)
{
	if (rtrs_srv_change_state(srv_path, RTRS_SRV_CLOSING))
		queue_work(rtrs_wq, &srv_path->close_work);
	WARN_ON(srv_path->state != RTRS_SRV_CLOSING);
}

static inline const char *rtrs_srv_state_str(enum rtrs_srv_state state)
{
	switch (state) {
	case RTRS_SRV_CONNECTING:
		return "RTRS_SRV_CONNECTING";
	case RTRS_SRV_CONNECTED:
		return "RTRS_SRV_CONNECTED";
	case RTRS_SRV_CLOSING:
		return "RTRS_SRV_CLOSING";
	case RTRS_SRV_CLOSED:
		return "RTRS_SRV_CLOSED";
	default:
		return "UNKNOWN";
	}
}

/**
 * rtrs_srv_resp_rdma() - Finish an RDMA request
 *
 * @id:		Internal RTRS operation identifier
 * @status:	Response Code sent to the other side for this operation.
 *		0 = success, <=0 error
 * Context: any
 *
 * Finish a RDMA operation. A message is sent to the client and the
 * corresponding memory areas will be released.
 */
bool rtrs_srv_resp_rdma(struct rtrs_srv_op *id, int status)
{
	struct rtrs_srv_path *srv_path;
	struct rtrs_srv_con *con;
	struct rtrs_path *s;
	int err;

	if (WARN_ON(!id))
		return true;

	con = id->con;
	s = con->c.path;
	srv_path = to_srv_path(s);

	id->status = status;

	if (srv_path->state != RTRS_SRV_CONNECTED) {
		rtrs_err_rl(s,
			    "Sending I/O response failed,  server path %s is disconnected, path state %s\n",
			    kobject_name(&srv_path->kobj),
			    rtrs_srv_state_str(srv_path->state));
		goto out;
	}
	if (always_invalidate) {
		struct rtrs_srv_mr *mr = &srv_path->mrs[id->msg_id];

		ib_update_fast_reg_key(mr->mr, ib_inc_rkey(mr->mr->rkey));
	}
	if (atomic_sub_return(1, &con->c.sq_wr_avail) < 0) {
		rtrs_err(s, "IB send queue full: srv_path=%s cid=%d\n",
			 kobject_name(&srv_path->kobj),
			 con->c.cid);
		atomic_add(1, &con->c.sq_wr_avail);
		spin_lock(&con->rsp_wr_wait_lock);
		list_add_tail(&id->wait_list, &con->rsp_wr_wait_list);
		spin_unlock(&con->rsp_wr_wait_lock);
		return false;
	}

	if (status || id->dir == WRITE || !id->rd_msg->sg_cnt)
		err = send_io_resp_imm(con, id, status);
	else
		err = rdma_write_sg(id);

	if (err) {
		rtrs_err_rl(s, "IO response failed: %d: srv_path=%s\n", err,
			    kobject_name(&srv_path->kobj));
		close_path(srv_path);
	}
out:
	rtrs_srv_put_ops_ids(srv_path);
	return true;
}
EXPORT_SYMBOL(rtrs_srv_resp_rdma);

/**
 * rtrs_srv_set_sess_priv() - Set private pointer in rtrs_srv.
 * @srv:	Session pointer
 * @priv:	The private pointer that is associated with the session.
 */
void rtrs_srv_set_sess_priv(struct rtrs_srv_sess *srv, void *priv)
{
	srv->priv = priv;
}
EXPORT_SYMBOL(rtrs_srv_set_sess_priv);

static void unmap_cont_bufs(struct rtrs_srv_path *srv_path)
{
	int i;

	for (i = 0; i < srv_path->mrs_num; i++) {
		struct rtrs_srv_mr *srv_mr;

		srv_mr = &srv_path->mrs[i];

		if (always_invalidate)
			rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1);

		ib_dereg_mr(srv_mr->mr);
		ib_dma_unmap_sg(srv_path->s.dev->ib_dev, srv_mr->sgt.sgl,
				srv_mr->sgt.nents, DMA_BIDIRECTIONAL);
		sg_free_table(&srv_mr->sgt);
	}
	kfree(srv_path->mrs);
}

static int map_cont_bufs(struct rtrs_srv_path *srv_path)
{
	struct rtrs_srv_sess *srv = srv_path->srv;
	struct rtrs_path *ss = &srv_path->s;
	int i, err, mrs_num;
	unsigned int chunk_bits;
	int chunks_per_mr = 1;
	struct ib_mr *mr;
	struct sg_table *sgt;

	/*
	 * Here we map queue_depth chunks to MR.  Firstly we have to
	 * figure out how many chunks can we map per MR.
	 */
	if (always_invalidate) {
		/*
		 * in order to do invalidate for each chunks of memory, we needs
		 * more memory regions.
		 */
		mrs_num = srv->queue_depth;
	} else {
		chunks_per_mr =
			srv_path->s.dev->ib_dev->attrs.max_fast_reg_page_list_len;
		mrs_num = DIV_ROUND_UP(srv->queue_depth, chunks_per_mr);
		chunks_per_mr = DIV_ROUND_UP(srv->queue_depth, mrs_num);
	}

	srv_path->mrs = kcalloc(mrs_num, sizeof(*srv_path->mrs), GFP_KERNEL);
	if (!srv_path->mrs)
		return -ENOMEM;

	for (srv_path->mrs_num = 0; srv_path->mrs_num < mrs_num;
	     srv_path->mrs_num++) {
		struct rtrs_srv_mr *srv_mr = &srv_path->mrs[srv_path->mrs_num];
		struct scatterlist *s;
		int nr, nr_sgt, chunks;

		sgt = &srv_mr->sgt;
		chunks = chunks_per_mr * srv_path->mrs_num;
		if (!always_invalidate)
			chunks_per_mr = min_t(int, chunks_per_mr,
					      srv->queue_depth - chunks);

		err = sg_alloc_table(sgt, chunks_per_mr, GFP_KERNEL);
		if (err)
			goto err;

		for_each_sg(sgt->sgl, s, chunks_per_mr, i)
			sg_set_page(s, srv->chunks[chunks + i],
				    max_chunk_size, 0);

		nr_sgt = ib_dma_map_sg(srv_path->s.dev->ib_dev, sgt->sgl,
				   sgt->nents, DMA_BIDIRECTIONAL);
		if (!nr_sgt) {
			err = -EINVAL;
			goto free_sg;
		}
		mr = ib_alloc_mr(srv_path->s.dev->ib_pd, IB_MR_TYPE_MEM_REG,
				 nr_sgt);
		if (IS_ERR(mr)) {
			err = PTR_ERR(mr);
			goto unmap_sg;
		}
		nr = ib_map_mr_sg(mr, sgt->sgl, nr_sgt,
				  NULL, max_chunk_size);
		if (nr != nr_sgt) {
			err = nr < 0 ? nr : -EINVAL;
			goto dereg_mr;
		}

		if (always_invalidate) {
			srv_mr->iu = rtrs_iu_alloc(1,
					sizeof(struct rtrs_msg_rkey_rsp),
					GFP_KERNEL, srv_path->s.dev->ib_dev,
					DMA_TO_DEVICE, rtrs_srv_rdma_done);
			if (!srv_mr->iu) {
				err = -ENOMEM;
				rtrs_err(ss, "rtrs_iu_alloc(), err: %d\n", err);
				goto dereg_mr;
			}
		}
		/* Eventually dma addr for each chunk can be cached */
		for_each_sg(sgt->sgl, s, nr_sgt, i)
			srv_path->dma_addr[chunks + i] = sg_dma_address(s);

		ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey));
		srv_mr->mr = mr;
	}

	chunk_bits = ilog2(srv->queue_depth - 1) + 1;
	srv_path->mem_bits = (MAX_IMM_PAYL_BITS - chunk_bits);

	return 0;

dereg_mr:
	ib_dereg_mr(mr);
unmap_sg:
	ib_dma_unmap_sg(srv_path->s.dev->ib_dev, sgt->sgl,
			sgt->nents, DMA_BIDIRECTIONAL);
free_sg:
	sg_free_table(sgt);
err:
	unmap_cont_bufs(srv_path);

	return err;
}

static void rtrs_srv_hb_err_handler(struct rtrs_con *c)
{
	struct rtrs_srv_con *con = container_of(c, typeof(*con), c);
	struct rtrs_srv_path *srv_path = to_srv_path(con->c.path);

	rtrs_err(con->c.path, "HB err handler for path=%s\n", kobject_name(&srv_path->kobj));
	close_path(to_srv_path(c->path));
}

static void rtrs_srv_init_hb(struct rtrs_srv_path *srv_path)
{
	rtrs_init_hb(&srv_path->s, &io_comp_cqe,
		      RTRS_HB_INTERVAL_MS,
		      RTRS_HB_MISSED_MAX,
		      rtrs_srv_hb_err_handler,
		      rtrs_wq);
}

static void rtrs_srv_start_hb(struct rtrs_srv_path *srv_path)
{
	rtrs_start_hb(&srv_path->s);
}

static void rtrs_srv_stop_hb(struct rtrs_srv_path *srv_path)
{
	rtrs_stop_hb(&srv_path->s);
}

static void rtrs_srv_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc)
{
	struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
	struct rtrs_path *s = con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);
	struct rtrs_iu *iu;

	iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe);
	rtrs_iu_free(iu, srv_path->s.dev->ib_dev, 1);

	if (wc->status != IB_WC_SUCCESS) {
		rtrs_err(s, "Sess info response send failed: %s\n",
			  ib_wc_status_msg(wc->status));
		close_path(srv_path);
		return;
	}
	WARN_ON(wc->opcode != IB_WC_SEND);
}

static int rtrs_srv_path_up(struct rtrs_srv_path *srv_path)
{
	struct rtrs_srv_sess *srv = srv_path->srv;
	struct rtrs_srv_ctx *ctx = srv->ctx;
	int up, ret = 0;

	mutex_lock(&srv->paths_ev_mutex);
	up = ++srv->paths_up;
	if (up == 1)
		ret = ctx->ops.link_ev(srv, RTRS_SRV_LINK_EV_CONNECTED, NULL);
	mutex_unlock(&srv->paths_ev_mutex);

	/* Mark session as established */
	if (!ret)
		srv_path->established = true;

	return ret;
}

static void rtrs_srv_path_down(struct rtrs_srv_path *srv_path)
{
	struct rtrs_srv_sess *srv = srv_path->srv;
	struct rtrs_srv_ctx *ctx = srv->ctx;

	if (!srv_path->established)
		return;

	srv_path->established = false;
	mutex_lock(&srv->paths_ev_mutex);
	WARN_ON(!srv->paths_up);
	if (--srv->paths_up == 0)
		ctx->ops.link_ev(srv, RTRS_SRV_LINK_EV_DISCONNECTED, srv->priv);
	mutex_unlock(&srv->paths_ev_mutex);
}

static bool exist_pathname(struct rtrs_srv_ctx *ctx,
			   const char *pathname, const uuid_t *path_uuid)
{
	struct rtrs_srv_sess *srv;
	struct rtrs_srv_path *srv_path;
	bool found = false;

	mutex_lock(&ctx->srv_mutex);
	list_for_each_entry(srv, &ctx->srv_list, ctx_list) {
		mutex_lock(&srv->paths_mutex);

		/* when a client with same uuid and same sessname tried to add a path */
		if (uuid_equal(&srv->paths_uuid, path_uuid)) {
			mutex_unlock(&srv->paths_mutex);
			continue;
		}

		list_for_each_entry(srv_path, &srv->paths_list, s.entry) {
			if (strlen(srv_path->s.sessname) == strlen(pathname) &&
			    !strcmp(srv_path->s.sessname, pathname)) {
				found = true;
				break;
			}
		}
		mutex_unlock(&srv->paths_mutex);
		if (found)
			break;
	}
	mutex_unlock(&ctx->srv_mutex);
	return found;
}

static int post_recv_path(struct rtrs_srv_path *srv_path);
static int rtrs_rdma_do_reject(struct rdma_cm_id *cm_id, int errno);

static int process_info_req(struct rtrs_srv_con *con,
			    struct rtrs_msg_info_req *msg)
{
	struct rtrs_path *s = con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);
	struct ib_send_wr *reg_wr = NULL;
	struct rtrs_msg_info_rsp *rsp;
	struct rtrs_iu *tx_iu;
	struct ib_reg_wr *rwr;
	int mri, err;
	size_t tx_sz;

	err = post_recv_path(srv_path);
	if (err) {
		rtrs_err(s, "post_recv_path(), err: %d\n", err);
		return err;
	}

	if (strchr(msg->pathname, '/') || strchr(msg->pathname, '.')) {
		rtrs_err(s, "pathname cannot contain / and .\n");
		return -EINVAL;
	}

	if (exist_pathname(srv_path->srv->ctx,
			   msg->pathname, &srv_path->srv->paths_uuid)) {
		rtrs_err(s, "pathname is duplicated: %s\n", msg->pathname);
		return -EPERM;
	}
	strscpy(srv_path->s.sessname, msg->pathname,
		sizeof(srv_path->s.sessname));

	rwr = kcalloc(srv_path->mrs_num, sizeof(*rwr), GFP_KERNEL);
	if (!rwr)
		return -ENOMEM;

	tx_sz  = sizeof(*rsp);
	tx_sz += sizeof(rsp->desc[0]) * srv_path->mrs_num;
	tx_iu = rtrs_iu_alloc(1, tx_sz, GFP_KERNEL, srv_path->s.dev->ib_dev,
			       DMA_TO_DEVICE, rtrs_srv_info_rsp_done);
	if (!tx_iu) {
		err = -ENOMEM;
		goto rwr_free;
	}

	rsp = tx_iu->buf;
	rsp->type = cpu_to_le16(RTRS_MSG_INFO_RSP);
	rsp->sg_cnt = cpu_to_le16(srv_path->mrs_num);

	for (mri = 0; mri < srv_path->mrs_num; mri++) {
		struct ib_mr *mr = srv_path->mrs[mri].mr;

		rsp->desc[mri].addr = cpu_to_le64(mr->iova);
		rsp->desc[mri].key  = cpu_to_le32(mr->rkey);
		rsp->desc[mri].len  = cpu_to_le32(mr->length);

		/*
		 * Fill in reg MR request and chain them *backwards*
		 */
		rwr[mri].wr.next = mri ? &rwr[mri - 1].wr : NULL;
		rwr[mri].wr.opcode = IB_WR_REG_MR;
		rwr[mri].wr.wr_cqe = &local_reg_cqe;
		rwr[mri].wr.num_sge = 0;
		rwr[mri].wr.send_flags = 0;
		rwr[mri].mr = mr;
		rwr[mri].key = mr->rkey;
		rwr[mri].access = (IB_ACCESS_LOCAL_WRITE |
				   IB_ACCESS_REMOTE_WRITE);
		reg_wr = &rwr[mri].wr;
	}

	err = rtrs_srv_create_path_files(srv_path);
	if (err)
		goto iu_free;
	kobject_get(&srv_path->kobj);
	get_device(&srv_path->srv->dev);
	err = rtrs_srv_change_state(srv_path, RTRS_SRV_CONNECTED);
	if (!err) {
		rtrs_err(s, "rtrs_srv_change_state(), err: %d\n", err);
		goto iu_free;
	}

	rtrs_srv_start_hb(srv_path);

	/*
	 * We do not account number of established connections at the current
	 * moment, we rely on the client, which should send info request when
	 * all connections are successfully established.  Thus, simply notify
	 * listener with a proper event if we are the first path.
	 */
	err = rtrs_srv_path_up(srv_path);
	if (err) {
		rtrs_err(s, "rtrs_srv_path_up(), err: %d\n", err);
		goto iu_free;
	}

	ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev,
				      tx_iu->dma_addr,
				      tx_iu->size, DMA_TO_DEVICE);

	/* Send info response */
	err = rtrs_iu_post_send(&con->c, tx_iu, tx_sz, reg_wr);
	if (err) {
		rtrs_err(s, "rtrs_iu_post_send(), err: %d\n", err);
iu_free:
		rtrs_iu_free(tx_iu, srv_path->s.dev->ib_dev, 1);
	}
rwr_free:
	kfree(rwr);

	return err;
}

static void rtrs_srv_info_req_done(struct ib_cq *cq, struct ib_wc *wc)
{
	struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
	struct rtrs_path *s = con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);
	struct rtrs_msg_info_req *msg;
	struct rtrs_iu *iu;
	int err;

	WARN_ON(con->c.cid);

	iu = container_of(wc->wr_cqe, struct rtrs_iu, cqe);
	if (wc->status != IB_WC_SUCCESS) {
		rtrs_err(s, "Sess info request receive failed: %s\n",
			  ib_wc_status_msg(wc->status));
		goto close;
	}
	WARN_ON(wc->opcode != IB_WC_RECV);

	if (wc->byte_len < sizeof(*msg)) {
		rtrs_err(s, "Sess info request is malformed: size %d\n",
			  wc->byte_len);
		goto close;
	}
	ib_dma_sync_single_for_cpu(srv_path->s.dev->ib_dev, iu->dma_addr,
				   iu->size, DMA_FROM_DEVICE);
	msg = iu->buf;
	if (le16_to_cpu(msg->type) != RTRS_MSG_INFO_REQ) {
		rtrs_err(s, "Sess info request is malformed: type %d\n",
			  le16_to_cpu(msg->type));
		goto close;
	}
	err = process_info_req(con, msg);
	if (err)
		goto close;

	rtrs_iu_free(iu, srv_path->s.dev->ib_dev, 1);
	return;
close:
	rtrs_iu_free(iu, srv_path->s.dev->ib_dev, 1);
	close_path(srv_path);
}

static int post_recv_info_req(struct rtrs_srv_con *con)
{
	struct rtrs_path *s = con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);
	struct rtrs_iu *rx_iu;
	int err;

	rx_iu = rtrs_iu_alloc(1, sizeof(struct rtrs_msg_info_req),
			       GFP_KERNEL, srv_path->s.dev->ib_dev,
			       DMA_FROM_DEVICE, rtrs_srv_info_req_done);
	if (!rx_iu)
		return -ENOMEM;
	/* Prepare for getting info response */
	err = rtrs_iu_post_recv(&con->c, rx_iu);
	if (err) {
		rtrs_err(s, "rtrs_iu_post_recv(), err: %d\n", err);
		rtrs_iu_free(rx_iu, srv_path->s.dev->ib_dev, 1);
		return err;
	}

	return 0;
}

static int post_recv_io(struct rtrs_srv_con *con, size_t q_size)
{
	int i, err;

	for (i = 0; i < q_size; i++) {
		err = rtrs_post_recv_empty(&con->c, &io_comp_cqe);
		if (err)
			return err;
	}

	return 0;
}

static int post_recv_path(struct rtrs_srv_path *srv_path)
{
	struct rtrs_srv_sess *srv = srv_path->srv;
	struct rtrs_path *s = &srv_path->s;
	size_t q_size;
	int err, cid;

	for (cid = 0; cid < srv_path->s.con_num; cid++) {
		if (cid == 0)
			q_size = SERVICE_CON_QUEUE_DEPTH;
		else
			q_size = srv->queue_depth;
		if (srv_path->state != RTRS_SRV_CONNECTING) {
			rtrs_err(s, "Path state invalid. state %s\n",
				 rtrs_srv_state_str(srv_path->state));
			return -EIO;
		}

		if (!srv_path->s.con[cid]) {
			rtrs_err(s, "Conn not set for %d\n", cid);
			return -EIO;
		}

		err = post_recv_io(to_srv_con(srv_path->s.con[cid]), q_size);
		if (err) {
			rtrs_err(s, "post_recv_io(), err: %d\n", err);
			return err;
		}
	}

	return 0;
}

static void process_read(struct rtrs_srv_con *con,
			 struct rtrs_msg_rdma_read *msg,
			 u32 buf_id, u32 off)
{
	struct rtrs_path *s = con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);
	struct rtrs_srv_sess *srv = srv_path->srv;
	struct rtrs_srv_ctx *ctx = srv->ctx;
	struct rtrs_srv_op *id;

	size_t usr_len, data_len;
	void *data;
	int ret;

	if (srv_path->state != RTRS_SRV_CONNECTED) {
		rtrs_err_rl(s,
			     "Processing read request failed,  session is disconnected, sess state %s\n",
			     rtrs_srv_state_str(srv_path->state));
		return;
	}
	if (msg->sg_cnt != 1 && msg->sg_cnt != 0) {
		rtrs_err_rl(s,
			    "Processing read request failed, invalid message\n");
		return;
	}
	rtrs_srv_get_ops_ids(srv_path);
	rtrs_srv_update_rdma_stats(srv_path->stats, off, READ);
	id = srv_path->ops_ids[buf_id];
	id->con		= con;
	id->dir		= READ;
	id->msg_id	= buf_id;
	id->rd_msg	= msg;
	usr_len = le16_to_cpu(msg->usr_len);
	data_len = off - usr_len;
	data = page_address(srv->chunks[buf_id]);
	ret = ctx->ops.rdma_ev(srv->priv, id, data, data_len,
			   data + data_len, usr_len);

	if (ret) {
		rtrs_err_rl(s,
			     "Processing read request failed, user module cb reported for msg_id %d, err: %d\n",
			     buf_id, ret);
		goto send_err_msg;
	}

	return;

send_err_msg:
	ret = send_io_resp_imm(con, id, ret);
	if (ret < 0) {
		rtrs_err_rl(s,
			     "Sending err msg for failed RDMA-Write-Req failed, msg_id %d, err: %d\n",
			     buf_id, ret);
		close_path(srv_path);
	}
	rtrs_srv_put_ops_ids(srv_path);
}

static void process_write(struct rtrs_srv_con *con,
			  struct rtrs_msg_rdma_write *req,
			  u32 buf_id, u32 off)
{
	struct rtrs_path *s = con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);
	struct rtrs_srv_sess *srv = srv_path->srv;
	struct rtrs_srv_ctx *ctx = srv->ctx;
	struct rtrs_srv_op *id;

	size_t data_len, usr_len;
	void *data;
	int ret;

	if (srv_path->state != RTRS_SRV_CONNECTED) {
		rtrs_err_rl(s,
			     "Processing write request failed,  session is disconnected, sess state %s\n",
			     rtrs_srv_state_str(srv_path->state));
		return;
	}
	rtrs_srv_get_ops_ids(srv_path);
	rtrs_srv_update_rdma_stats(srv_path->stats, off, WRITE);
	id = srv_path->ops_ids[buf_id];
	id->con    = con;
	id->dir    = WRITE;
	id->msg_id = buf_id;

	usr_len = le16_to_cpu(req->usr_len);
	data_len = off - usr_len;
	data = page_address(srv->chunks[buf_id]);
	ret = ctx->ops.rdma_ev(srv->priv, id, data, data_len,
			       data + data_len, usr_len);
	if (ret) {
		rtrs_err_rl(s,
			     "Processing write request failed, user module callback reports err: %d\n",
			     ret);
		goto send_err_msg;
	}

	return;

send_err_msg:
	ret = send_io_resp_imm(con, id, ret);
	if (ret < 0) {
		rtrs_err_rl(s,
			     "Processing write request failed, sending I/O response failed, msg_id %d, err: %d\n",
			     buf_id, ret);
		close_path(srv_path);
	}
	rtrs_srv_put_ops_ids(srv_path);
}

static void process_io_req(struct rtrs_srv_con *con, void *msg,
			   u32 id, u32 off)
{
	struct rtrs_path *s = con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);
	struct rtrs_msg_rdma_hdr *hdr;
	unsigned int type;

	ib_dma_sync_single_for_cpu(srv_path->s.dev->ib_dev,
				   srv_path->dma_addr[id],
				   max_chunk_size, DMA_BIDIRECTIONAL);
	hdr = msg;
	type = le16_to_cpu(hdr->type);

	switch (type) {
	case RTRS_MSG_WRITE:
		process_write(con, msg, id, off);
		break;
	case RTRS_MSG_READ:
		process_read(con, msg, id, off);
		break;
	default:
		rtrs_err(s,
			  "Processing I/O request failed, unknown message type received: 0x%02x\n",
			  type);
		goto err;
	}

	return;

err:
	close_path(srv_path);
}

static void rtrs_srv_inv_rkey_done(struct ib_cq *cq, struct ib_wc *wc)
{
	struct rtrs_srv_mr *mr =
		container_of(wc->wr_cqe, typeof(*mr), inv_cqe);
	struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
	struct rtrs_path *s = con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);
	struct rtrs_srv_sess *srv = srv_path->srv;
	u32 msg_id, off;
	void *data;

	if (wc->status != IB_WC_SUCCESS) {
		rtrs_err(s, "Failed IB_WR_LOCAL_INV: %s\n",
			  ib_wc_status_msg(wc->status));
		close_path(srv_path);
	}
	msg_id = mr->msg_id;
	off = mr->msg_off;
	data = page_address(srv->chunks[msg_id]) + off;
	process_io_req(con, data, msg_id, off);
}

static int rtrs_srv_inv_rkey(struct rtrs_srv_con *con,
			      struct rtrs_srv_mr *mr)
{
	struct ib_send_wr wr = {
		.opcode		    = IB_WR_LOCAL_INV,
		.wr_cqe		    = &mr->inv_cqe,
		.send_flags	    = IB_SEND_SIGNALED,
		.ex.invalidate_rkey = mr->mr->rkey,
	};
	mr->inv_cqe.done = rtrs_srv_inv_rkey_done;

	return ib_post_send(con->c.qp, &wr, NULL);
}

static void rtrs_rdma_process_wr_wait_list(struct rtrs_srv_con *con)
{
	spin_lock(&con->rsp_wr_wait_lock);
	while (!list_empty(&con->rsp_wr_wait_list)) {
		struct rtrs_srv_op *id;
		int ret;

		id = list_entry(con->rsp_wr_wait_list.next,
				struct rtrs_srv_op, wait_list);
		list_del(&id->wait_list);

		spin_unlock(&con->rsp_wr_wait_lock);
		ret = rtrs_srv_resp_rdma(id, id->status);
		spin_lock(&con->rsp_wr_wait_lock);

		if (!ret) {
			list_add(&id->wait_list, &con->rsp_wr_wait_list);
			break;
		}
	}
	spin_unlock(&con->rsp_wr_wait_lock);
}

static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
{
	struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
	struct rtrs_path *s = con->c.path;
	struct rtrs_srv_path *srv_path = to_srv_path(s);
	struct rtrs_srv_sess *srv = srv_path->srv;
	u32 imm_type, imm_payload;
	int err;

	if (wc->status != IB_WC_SUCCESS) {
		if (wc->status != IB_WC_WR_FLUSH_ERR) {
			rtrs_err(s,
				  "%s (wr_cqe: %p, type: %d, vendor_err: 0x%x, len: %u)\n",
				  ib_wc_status_msg(wc->status), wc->wr_cqe,
				  wc->opcode, wc->vendor_err, wc->byte_len);
			close_path(srv_path);
		}
		return;
	}

	switch (wc->opcode) {
	case IB_WC_RECV_RDMA_WITH_IMM:
		/*
		 * post_recv() RDMA write completions of IO reqs (read/write)
		 * and hb
		 */
		if (WARN_ON(wc->wr_cqe != &io_comp_cqe))
			return;
		srv_path->s.hb_missed_cnt = 0;
		err = rtrs_post_recv_empty(&con->c, &io_comp_cqe);
		if (err) {
			rtrs_err(s, "rtrs_post_recv(), err: %d\n", err);
			close_path(srv_path);
			break;
		}
		rtrs_from_imm(be32_to_cpu(wc->ex.imm_data),
			       &imm_type, &imm_payload);
		if (imm_type == RTRS_IO_REQ_IMM) {
			u32 msg_id, off;
			void *data;

			msg_id = imm_payload >> srv_path->mem_bits;
			off = imm_payload & ((1 << srv_path->mem_bits) - 1);
			if (msg_id >= srv->queue_depth || off >= max_chunk_size) {
				rtrs_err(s, "Wrong msg_id %u, off %u\n",
					  msg_id, off);
				close_path(srv_path);
				return;
			}
			if (always_invalidate) {
				struct rtrs_srv_mr *mr = &srv_path->mrs[msg_id];

				mr->msg_off = off;
				mr->msg_id = msg_id;
				err = rtrs_srv_inv_rkey(con, mr);
				if (err) {
					rtrs_err(s, "rtrs_post_recv(), err: %d\n",
						  err);
					close_path(srv_path);
					break;
				}
			} else {
				data = page_address(srv->chunks[msg_id]) + off;
				process_io_req(con, data, msg_id, off);
			}
		} else if (imm_type == RTRS_HB_MSG_IMM) {
			WARN_ON(con->c.cid);
			rtrs_send_hb_ack(&srv_path->s);
		} else if (imm_type == RTRS_HB_ACK_IMM) {
			WARN_ON(con->c.cid);
			srv_path->s.hb_missed_cnt = 0;
		} else {
			rtrs_wrn(s, "Unknown IMM type %u\n", imm_type);
		}
		break;
	case IB_WC_RDMA_WRITE:
	case IB_WC_SEND:
		/*
		 * post_send() RDMA write completions of IO reqs (read/write)
		 * and hb.
		 */
		atomic_add(s->signal_interval, &con->c.sq_wr_avail);

		if (!list_empty_careful(&con->rsp_wr_wait_list))
			rtrs_rdma_process_wr_wait_list(con);

		break;
	default:
		rtrs_wrn(s, "Unexpected WC type: %d\n", wc->opcode);
		return;
	}
}

/**
 * rtrs_srv_get_path_name() - Get rtrs_srv peer hostname.
 * @srv:	Session
 * @pathname:	Pathname buffer
 * @len:	Length of sessname buffer
 */
int rtrs_srv_get_path_name(struct rtrs_srv_sess *srv, char *pathname,
			   size_t len)
{
	struct rtrs_srv_path *srv_path;
	int err = -ENOTCONN;

	mutex_lock(&srv->paths_mutex);
	list_for_each_entry(srv_path, &srv->paths_list, s.entry) {
		if (srv_path->state != RTRS_SRV_CONNECTED)
			continue;
		strscpy(pathname, srv_path->s.sessname,
			min_t(size_t, sizeof(srv_path->s.sessname), len));
		err = 0;
		break;
	}
	mutex_unlock(&srv->paths_mutex);

	return err;
}
EXPORT_SYMBOL(rtrs_srv_get_path_name);

/**
 * rtrs_srv_get_queue_depth() - Get rtrs_srv qdepth.
 * @srv:	Session
 */
int rtrs_srv_get_queue_depth(struct rtrs_srv_sess *srv)
{
	return srv->queue_depth;
}
EXPORT_SYMBOL(rtrs_srv_get_queue_depth);

static int find_next_bit_ring(struct rtrs_srv_path *srv_path)
{
	struct ib_device *ib_dev = srv_path->s.dev->ib_dev;
	int v;

	v = cpumask_next(srv_path->cur_cq_vector, &cq_affinity_mask);
	if (v >= nr_cpu_ids || v >= ib_dev->num_comp_vectors)
		v = cpumask_first(&cq_affinity_mask);
	return v;
}

static int rtrs_srv_get_next_cq_vector(struct rtrs_srv_path *srv_path)
{
	srv_path->cur_cq_vector = find_next_bit_ring(srv_path);

	return srv_path->cur_cq_vector;
}

static void rtrs_srv_dev_release(struct device *dev)
{
	struct rtrs_srv_sess *srv = container_of(dev, struct rtrs_srv_sess,
						 dev);

	kfree(srv);
}

static void free_srv(struct rtrs_srv_sess *srv)
{
	int i;

	WARN_ON(refcount_read(&srv->refcount));
	for (i = 0; i < srv->queue_depth; i++)
		__free_pages(srv->chunks[i], get_order(max_chunk_size));
	kfree(srv->chunks);
	mutex_destroy(&srv->paths_mutex);
	mutex_destroy(&srv->paths_ev_mutex);
	/* last put to release the srv structure */
	put_device(&srv->dev);
}

static struct rtrs_srv_sess *get_or_create_srv(struct rtrs_srv_ctx *ctx,
					  const uuid_t *paths_uuid,
					  bool first_conn)
{
	struct rtrs_srv_sess *srv;
	int i;

	mutex_lock(&ctx->srv_mutex);
	list_for_each_entry(srv, &ctx->srv_list, ctx_list) {
		if (uuid_equal(&srv->paths_uuid, paths_uuid) &&
		    refcount_inc_not_zero(&srv->refcount)) {
			mutex_unlock(&ctx->srv_mutex);
			return srv;
		}
	}
	mutex_unlock(&ctx->srv_mutex);
	/*
	 * If this request is not the first connection request from the
	 * client for this session then fail and return error.
	 */
	if (!first_conn) {
		pr_err_ratelimited("Error: Not the first connection request for this session\n");
		return ERR_PTR(-ENXIO);
	}

	/* need to allocate a new srv */
	srv = kzalloc(sizeof(*srv), GFP_KERNEL);
	if  (!srv)
		return ERR_PTR(-ENOMEM);

	INIT_LIST_HEAD(&srv->paths_list);
	mutex_init(&srv->paths_mutex);
	mutex_init(&srv->paths_ev_mutex);
	uuid_copy(&srv->paths_uuid, paths_uuid);
	srv->queue_depth = sess_queue_depth;
	srv->ctx = ctx;
	device_initialize(&srv->dev);
	srv->dev.release = rtrs_srv_dev_release;

	srv->chunks = kcalloc(srv->queue_depth, sizeof(*srv->chunks),
			      GFP_KERNEL);
	if (!srv->chunks)
		goto err_free_srv;

	for (i = 0; i < srv->queue_depth; i++) {
		srv->chunks[i] = alloc_pages(GFP_KERNEL,
					     get_order(max_chunk_size));
		if (!srv->chunks[i])
			goto err_free_chunks;
	}
	refcount_set(&srv->refcount, 1);
	mutex_lock(&ctx->srv_mutex);
	list_add(&srv->ctx_list, &ctx->srv_list);
	mutex_unlock(&ctx->srv_mutex);

	return srv;

err_free_chunks:
	while (i--)
		__free_pages(srv->chunks[i], get_order(max_chunk_size));
	kfree(srv->chunks);

err_free_srv:
	kfree(srv);
	return ERR_PTR(-ENOMEM);
}

static void put_srv(struct rtrs_srv_sess *srv)
{
	if (refcount_dec_and_test(&srv->refcount)) {
		struct rtrs_srv_ctx *ctx = srv->ctx;

		WARN_ON(srv->dev.kobj.state_in_sysfs);

		mutex_lock(&ctx->srv_mutex);
		list_del(&srv->ctx_list);
		mutex_unlock(&ctx->srv_mutex);
		free_srv(srv);
	}
}

static void __add_path_to_srv(struct rtrs_srv_sess *srv,
			      struct rtrs_srv_path *srv_path)
{
	list_add_tail(&srv_path->s.entry, &srv->paths_list);
	srv->paths_num++;
	WARN_ON(srv->paths_num >= MAX_PATHS_NUM);
}

static void del_path_from_srv(struct rtrs_srv_path *srv_path)
{
	struct rtrs_srv_sess *srv = srv_path->srv;

	if (WARN_ON(!srv))
		return;

	mutex_lock(&srv->paths_mutex);
	list_del(&srv_path->s.entry);
	WARN_ON(!srv->paths_num);
	srv->paths_num--;
	mutex_unlock(&srv->paths_mutex);
}

/* return true if addresses are the same, error other wise */
static int sockaddr_cmp(const struct sockaddr *a, const struct sockaddr *b)
{
	switch (a->sa_family) {
	case AF_IB:
		return memcmp(&((struct sockaddr_ib *)a)->sib_addr,
			      &((struct sockaddr_ib *)b)->sib_addr,
			      sizeof(struct ib_addr)) &&
			(b->sa_family == AF_IB);
	case AF_INET:
		return memcmp(&((struct sockaddr_in *)a)->sin_addr,
			      &((struct sockaddr_in *)b)->sin_addr,
			      sizeof(struct in_addr)) &&
			(b->sa_family == AF_INET);
	case AF_INET6:
		return memcmp(&((struct sockaddr_in6 *)a)->sin6_addr,
			      &((struct sockaddr_in6 *)b)->sin6_addr,
			      sizeof(struct in6_addr)) &&
			(b->sa_family == AF_INET6);
	default:
		return -ENOENT;
	}
}

static bool __is_path_w_addr_exists(struct rtrs_srv_sess *srv,
				    struct rdma_addr *addr)
{
	struct rtrs_srv_path *srv_path;

	list_for_each_entry(srv_path, &srv->paths_list, s.entry)
		if (!sockaddr_cmp((struct sockaddr *)&srv_path->s.dst_addr,
				  (struct sockaddr *)&addr->dst_addr) &&
		    !sockaddr_cmp((struct sockaddr *)&srv_path->s.src_addr,
				  (struct sockaddr *)&addr->src_addr))
			return true;

	return false;
}

static void free_path(struct rtrs_srv_path *srv_path)
{
	if (srv_path->kobj.state_in_sysfs) {
		kobject_del(&srv_path->kobj);
		kobject_put(&srv_path->kobj);
	} else {
		free_percpu(srv_path->stats->rdma_stats);
		kfree(srv_path->stats);
		kfree(srv_path);
	}
}

static void rtrs_srv_close_work(struct work_struct *work)
{
	struct rtrs_srv_path *srv_path;
	struct rtrs_srv_con *con;
	int i;

	srv_path = container_of(work, typeof(*srv_path), close_work);

	rtrs_srv_stop_hb(srv_path);

	for (i = 0; i < srv_path->s.con_num; i++) {
		if (!srv_path->s.con[i])
			continue;
		con = to_srv_con(srv_path->s.con[i]);
		rdma_disconnect(con->c.cm_id);
		ib_drain_qp(con->c.qp);
	}

	/*
	 * Degrade ref count to the usual model with a single shared
	 * atomic_t counter
	 */
	percpu_ref_kill(&srv_path->ids_inflight_ref);

	/* Wait for all completion */
	wait_for_completion(&srv_path->complete_done);

	rtrs_srv_destroy_path_files(srv_path);

	/* Notify upper layer if we are the last path */
	rtrs_srv_path_down(srv_path);

	unmap_cont_bufs(srv_path);
	rtrs_srv_free_ops_ids(srv_path);

	for (i = 0; i < srv_path->s.con_num; i++) {
		if (!srv_path->s.con[i])
			continue;
		con = to_srv_con(srv_path->s.con[i]);
		rtrs_cq_qp_destroy(&con->c);
		rdma_destroy_id(con->c.cm_id);
		kfree(con);
	}
	rtrs_ib_dev_put(srv_path->s.dev);

	del_path_from_srv(srv_path);
	put_srv(srv_path->srv);
	srv_path->srv = NULL;
	rtrs_srv_change_state(srv_path, RTRS_SRV_CLOSED);

	kfree(srv_path->dma_addr);
	kfree(srv_path->s.con);
	free_path(srv_path);
}

static int rtrs_rdma_do_accept(struct rtrs_srv_path *srv_path,
			       struct rdma_cm_id *cm_id)
{
	struct rtrs_srv_sess *srv = srv_path->srv;
	struct rtrs_msg_conn_rsp msg;
	struct rdma_conn_param param;
	int err;

	param = (struct rdma_conn_param) {
		.rnr_retry_count = 7,
		.private_data = &msg,
		.private_data_len = sizeof(msg),
	};

	msg = (struct rtrs_msg_conn_rsp) {
		.magic = cpu_to_le16(RTRS_MAGIC),
		.version = cpu_to_le16(RTRS_PROTO_VER),
		.queue_depth = cpu_to_le16(srv->queue_depth),
		.max_io_size = cpu_to_le32(max_chunk_size - MAX_HDR_SIZE),
		.max_hdr_size = cpu_to_le32(MAX_HDR_SIZE),
	};

	if (always_invalidate)
		msg.flags = cpu_to_le32(RTRS_MSG_NEW_RKEY_F);

	err = rdma_accept(cm_id, &param);
	if (err)
		pr_err("rdma_accept(), err: %d\n", err);

	return err;
}

static int rtrs_rdma_do_reject(struct rdma_cm_id *cm_id, int errno)
{
	struct rtrs_msg_conn_rsp msg;
	int err;

	msg = (struct rtrs_msg_conn_rsp) {
		.magic = cpu_to_le16(RTRS_MAGIC),
		.version = cpu_to_le16(RTRS_PROTO_VER),
		.errno = cpu_to_le16(errno),
	};

	err = rdma_reject(cm_id, &msg, sizeof(msg), IB_CM_REJ_CONSUMER_DEFINED);
	if (err)
		pr_err("rdma_reject(), err: %d\n", err);

	/* Bounce errno back */
	return errno;
}

static struct rtrs_srv_path *
__find_path(struct rtrs_srv_sess *srv, const uuid_t *sess_uuid)
{
	struct rtrs_srv_path *srv_path;

	list_for_each_entry(srv_path, &srv->paths_list, s.entry) {
		if (uuid_equal(&srv_path->s.uuid, sess_uuid))
			return srv_path;
	}

	return NULL;
}

static int create_con(struct rtrs_srv_path *srv_path,
		      struct rdma_cm_id *cm_id,
		      unsigned int cid)
{
	struct rtrs_srv_sess *srv = srv_path->srv;
	struct rtrs_path *s = &srv_path->s;
	struct rtrs_srv_con *con;

	u32 cq_num, max_send_wr, max_recv_wr, wr_limit;
	int err, cq_vector;

	con = kzalloc(sizeof(*con), GFP_KERNEL);
	if (!con) {
		err = -ENOMEM;
		goto err;
	}

	spin_lock_init(&con->rsp_wr_wait_lock);
	INIT_LIST_HEAD(&con->rsp_wr_wait_list);
	con->c.cm_id = cm_id;
	con->c.path = &srv_path->s;
	con->c.cid = cid;
	atomic_set(&con->c.wr_cnt, 1);
	wr_limit = srv_path->s.dev->ib_dev->attrs.max_qp_wr;

	if (con->c.cid == 0) {
		/*
		 * All receive and all send (each requiring invalidate)
		 * + 2 for drain and heartbeat
		 */
		max_send_wr = min_t(int, wr_limit,
				    SERVICE_CON_QUEUE_DEPTH * 2 + 2);
		max_recv_wr = max_send_wr;
		s->signal_interval = min_not_zero(srv->queue_depth,
						  (size_t)SERVICE_CON_QUEUE_DEPTH);
	} else {
		/* when always_invlaidate enalbed, we need linv+rinv+mr+imm */
		if (always_invalidate)
			max_send_wr =
				min_t(int, wr_limit,
				      srv->queue_depth * (1 + 4) + 1);
		else
			max_send_wr =
				min_t(int, wr_limit,
				      srv->queue_depth * (1 + 2) + 1);

		max_recv_wr = srv->queue_depth + 1;
	}
	cq_num = max_send_wr + max_recv_wr;
	atomic_set(&con->c.sq_wr_avail, max_send_wr);
	cq_vector = rtrs_srv_get_next_cq_vector(srv_path);

	/* TODO: SOFTIRQ can be faster, but be careful with softirq context */
	err = rtrs_cq_qp_create(&srv_path->s, &con->c, 1, cq_vector, cq_num,
				 max_send_wr, max_recv_wr,
				 IB_POLL_WORKQUEUE);
	if (err) {
		rtrs_err(s, "rtrs_cq_qp_create(), err: %d\n", err);
		goto free_con;
	}
	if (con->c.cid == 0) {
		err = post_recv_info_req(con);
		if (err)
			goto free_cqqp;
	}
	WARN_ON(srv_path->s.con[cid]);
	srv_path->s.con[cid] = &con->c;

	/*
	 * Change context from server to current connection.  The other
	 * way is to use cm_id->qp->qp_context, which does not work on OFED.
	 */
	cm_id->context = &con->c;

	return 0;

free_cqqp:
	rtrs_cq_qp_destroy(&con->c);
free_con:
	kfree(con);

err:
	return err;
}

static struct rtrs_srv_path *__alloc_path(struct rtrs_srv_sess *srv,
					   struct rdma_cm_id *cm_id,
					   unsigned int con_num,
					   unsigned int recon_cnt,
					   const uuid_t *uuid)
{
	struct rtrs_srv_path *srv_path;
	int err = -ENOMEM;
	char str[NAME_MAX];
	struct rtrs_addr path;

	if (srv->paths_num >= MAX_PATHS_NUM) {
		err = -ECONNRESET;
		goto err;
	}
	if (__is_path_w_addr_exists(srv, &cm_id->route.addr)) {
		err = -EEXIST;
		pr_err("Path with same addr exists\n");
		goto err;
	}
	srv_path = kzalloc(sizeof(*srv_path), GFP_KERNEL);
	if (!srv_path)
		goto err;

	srv_path->stats = kzalloc(sizeof(*srv_path->stats), GFP_KERNEL);
	if (!srv_path->stats)
		goto err_free_sess;

	srv_path->stats->rdma_stats = alloc_percpu(struct rtrs_srv_stats_rdma_stats);
	if (!srv_path->stats->rdma_stats)
		goto err_free_stats;

	srv_path->stats->srv_path = srv_path;

	srv_path->dma_addr = kcalloc(srv->queue_depth,
				     sizeof(*srv_path->dma_addr),
				     GFP_KERNEL);
	if (!srv_path->dma_addr)
		goto err_free_percpu;

	srv_path->s.con = kcalloc(con_num, sizeof(*srv_path->s.con),
				  GFP_KERNEL);
	if (!srv_path->s.con)
		goto err_free_dma_addr;

	srv_path->state = RTRS_SRV_CONNECTING;
	srv_path->srv = srv;
	srv_path->cur_cq_vector = -1;
	srv_path->s.dst_addr = cm_id->route.addr.dst_addr;
	srv_path->s.src_addr = cm_id->route.addr.src_addr;

	/* temporary until receiving session-name from client */
	path.src = &srv_path->s.src_addr;
	path.dst = &srv_path->s.dst_addr;
	rtrs_addr_to_str(&path, str, sizeof(str));
	strscpy(srv_path->s.sessname, str, sizeof(srv_path->s.sessname));

	srv_path->s.con_num = con_num;
	srv_path->s.irq_con_num = con_num;
	srv_path->s.recon_cnt = recon_cnt;
	uuid_copy(&srv_path->s.uuid, uuid);
	spin_lock_init(&srv_path->state_lock);
	INIT_WORK(&srv_path->close_work, rtrs_srv_close_work);
	rtrs_srv_init_hb(srv_path);

	srv_path->s.dev = rtrs_ib_dev_find_or_add(cm_id->device, &dev_pd);
	if (!srv_path->s.dev) {
		err = -ENOMEM;
		goto err_free_con;
	}
	err = map_cont_bufs(srv_path);
	if (err)
		goto err_put_dev;

	err = rtrs_srv_alloc_ops_ids(srv_path);
	if (err)
		goto err_unmap_bufs;

	__add_path_to_srv(srv, srv_path);

	return srv_path;

err_unmap_bufs:
	unmap_cont_bufs(srv_path);
err_put_dev:
	rtrs_ib_dev_put(srv_path->s.dev);
err_free_con:
	kfree(srv_path->s.con);
err_free_dma_addr:
	kfree(srv_path->dma_addr);
err_free_percpu:
	free_percpu(srv_path->stats->rdma_stats);
err_free_stats:
	kfree(srv_path->stats);
err_free_sess:
	kfree(srv_path);
err:
	return ERR_PTR(err);
}

static int rtrs_rdma_connect(struct rdma_cm_id *cm_id,
			      const struct rtrs_msg_conn_req *msg,
			      size_t len)
{
	struct rtrs_srv_ctx *ctx = cm_id->context;
	struct rtrs_srv_path *srv_path;
	struct rtrs_srv_sess *srv;

	u16 version, con_num, cid;
	u16 recon_cnt;
	int err = -ECONNRESET;

	if (len < sizeof(*msg)) {
		pr_err("Invalid RTRS connection request\n");
		goto reject_w_err;
	}
	if (le16_to_cpu(msg->magic) != RTRS_MAGIC) {
		pr_err("Invalid RTRS magic\n");
		goto reject_w_err;
	}
	version = le16_to_cpu(msg->version);
	if (version >> 8 != RTRS_PROTO_VER_MAJOR) {
		pr_err("Unsupported major RTRS version: %d, expected %d\n",
		       version >> 8, RTRS_PROTO_VER_MAJOR);
		goto reject_w_err;
	}
	con_num = le16_to_cpu(msg->cid_num);
	if (con_num > 4096) {
		/* Sanity check */
		pr_err("Too many connections requested: %d\n", con_num);
		goto reject_w_err;
	}
	cid = le16_to_cpu(msg->cid);
	if (cid >= con_num) {
		/* Sanity check */
		pr_err("Incorrect cid: %d >= %d\n", cid, con_num);
		goto reject_w_err;
	}
	recon_cnt = le16_to_cpu(msg->recon_cnt);
	srv = get_or_create_srv(ctx, &msg->paths_uuid, msg->first_conn);
	if (IS_ERR(srv)) {
		err = PTR_ERR(srv);
		pr_err("get_or_create_srv(), error %d\n", err);
		goto reject_w_err;
	}
	mutex_lock(&srv->paths_mutex);
	srv_path = __find_path(srv, &msg->sess_uuid);
	if (srv_path) {
		struct rtrs_path *s = &srv_path->s;

		/* Session already holds a reference */
		put_srv(srv);

		if (srv_path->state != RTRS_SRV_CONNECTING) {
			rtrs_err(s, "Session in wrong state: %s\n",
				  rtrs_srv_state_str(srv_path->state));
			mutex_unlock(&srv->paths_mutex);
			goto reject_w_err;
		}
		/*
		 * Sanity checks
		 */
		if (con_num != s->con_num || cid >= s->con_num) {
			rtrs_err(s, "Incorrect request: %d, %d\n",
				  cid, con_num);
			mutex_unlock(&srv->paths_mutex);
			goto reject_w_err;
		}
		if (s->con[cid]) {
			rtrs_err(s, "Connection already exists: %d\n",
				  cid);
			mutex_unlock(&srv->paths_mutex);
			goto reject_w_err;
		}
	} else {
		srv_path = __alloc_path(srv, cm_id, con_num, recon_cnt,
				    &msg->sess_uuid);
		if (IS_ERR(srv_path)) {
			mutex_unlock(&srv->paths_mutex);
			put_srv(srv);
			err = PTR_ERR(srv_path);
			pr_err("RTRS server session allocation failed: %d\n", err);
			goto reject_w_err;
		}
	}
	err = create_con(srv_path, cm_id, cid);
	if (err) {
		rtrs_err((&srv_path->s), "create_con(), error %d\n", err);
		rtrs_rdma_do_reject(cm_id, err);
		/*
		 * Since session has other connections we follow normal way
		 * through workqueue, but still return an error to tell cma.c
		 * to call rdma_destroy_id() for current connection.
		 */
		goto close_and_return_err;
	}
	err = rtrs_rdma_do_accept(srv_path, cm_id);
	if (err) {
		rtrs_err((&srv_path->s), "rtrs_rdma_do_accept(), error %d\n", err);
		rtrs_rdma_do_reject(cm_id, err);
		/*
		 * Since current connection was successfully added to the
		 * session we follow normal way through workqueue to close the
		 * session, thus return 0 to tell cma.c we call
		 * rdma_destroy_id() ourselves.
		 */
		err = 0;
		goto close_and_return_err;
	}
	mutex_unlock(&srv->paths_mutex);

	return 0;

reject_w_err:
	return rtrs_rdma_do_reject(cm_id, err);

close_and_return_err:
	mutex_unlock(&srv->paths_mutex);
	close_path(srv_path);

	return err;
}

static int rtrs_srv_rdma_cm_handler(struct rdma_cm_id *cm_id,
				     struct rdma_cm_event *ev)
{
	struct rtrs_srv_path *srv_path = NULL;
	struct rtrs_path *s = NULL;
	struct rtrs_con *c = NULL;

	if (ev->event == RDMA_CM_EVENT_CONNECT_REQUEST)
		/*
		 * In case of error cma.c will destroy cm_id,
		 * see cma_process_remove()
		 */
		return rtrs_rdma_connect(cm_id, ev->param.conn.private_data,
					  ev->param.conn.private_data_len);

	c = cm_id->context;
	s = c->path;
	srv_path = to_srv_path(s);

	switch (ev->event) {
	case RDMA_CM_EVENT_ESTABLISHED:
		/* Nothing here */
		break;
	case RDMA_CM_EVENT_REJECTED:
	case RDMA_CM_EVENT_CONNECT_ERROR:
	case RDMA_CM_EVENT_UNREACHABLE:
		rtrs_err(s, "CM error (CM event: %s, err: %d)\n",
			  rdma_event_msg(ev->event), ev->status);
		fallthrough;
	case RDMA_CM_EVENT_DISCONNECTED:
	case RDMA_CM_EVENT_ADDR_CHANGE:
	case RDMA_CM_EVENT_TIMEWAIT_EXIT:
	case RDMA_CM_EVENT_DEVICE_REMOVAL:
		close_path(srv_path);
		break;
	default:
		pr_err("Ignoring unexpected CM event %s, err %d\n",
		       rdma_event_msg(ev->event), ev->status);
		break;
	}

	return 0;
}

static struct rdma_cm_id *rtrs_srv_cm_init(struct rtrs_srv_ctx *ctx,
					    struct sockaddr *addr,
					    enum rdma_ucm_port_space ps)
{
	struct rdma_cm_id *cm_id;
	int ret;

	cm_id = rdma_create_id(&init_net, rtrs_srv_rdma_cm_handler,
			       ctx, ps, IB_QPT_RC);
	if (IS_ERR(cm_id)) {
		ret = PTR_ERR(cm_id);
		pr_err("Creating id for RDMA connection failed, err: %d\n",
		       ret);
		goto err_out;
	}
	ret = rdma_bind_addr(cm_id, addr);
	if (ret) {
		pr_err("Binding RDMA address failed, err: %d\n", ret);
		goto err_cm;
	}
	ret = rdma_listen(cm_id, 64);
	if (ret) {
		pr_err("Listening on RDMA connection failed, err: %d\n",
		       ret);
		goto err_cm;
	}

	return cm_id;

err_cm:
	rdma_destroy_id(cm_id);
err_out:

	return ERR_PTR(ret);
}

static int rtrs_srv_rdma_init(struct rtrs_srv_ctx *ctx, u16 port)
{
	struct sockaddr_in6 sin = {
		.sin6_family	= AF_INET6,
		.sin6_addr	= IN6ADDR_ANY_INIT,
		.sin6_port	= htons(port),
	};
	struct sockaddr_ib sib = {
		.sib_family			= AF_IB,
		.sib_sid	= cpu_to_be64(RDMA_IB_IP_PS_IB | port),
		.sib_sid_mask	= cpu_to_be64(0xffffffffffffffffULL),
		.sib_pkey	= cpu_to_be16(0xffff),
	};
	struct rdma_cm_id *cm_ip, *cm_ib;
	int ret;

	/*
	 * We accept both IPoIB and IB connections, so we need to keep
	 * two cm id's, one for each socket type and port space.
	 * If the cm initialization of one of the id's fails, we abort
	 * everything.
	 */
	cm_ip = rtrs_srv_cm_init(ctx, (struct sockaddr *)&sin, RDMA_PS_TCP);
	if (IS_ERR(cm_ip))
		return PTR_ERR(cm_ip);

	cm_ib = rtrs_srv_cm_init(ctx, (struct sockaddr *)&sib, RDMA_PS_IB);
	if (IS_ERR(cm_ib)) {
		ret = PTR_ERR(cm_ib);
		goto free_cm_ip;
	}

	ctx->cm_id_ip = cm_ip;
	ctx->cm_id_ib = cm_ib;

	return 0;

free_cm_ip:
	rdma_destroy_id(cm_ip);

	return ret;
}

static struct rtrs_srv_ctx *alloc_srv_ctx(struct rtrs_srv_ops *ops)
{
	struct rtrs_srv_ctx *ctx;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return NULL;

	ctx->ops = *ops;
	mutex_init(&ctx->srv_mutex);
	INIT_LIST_HEAD(&ctx->srv_list);

	return ctx;
}

static void free_srv_ctx(struct rtrs_srv_ctx *ctx)
{
	WARN_ON(!list_empty(&ctx->srv_list));
	mutex_destroy(&ctx->srv_mutex);
	kfree(ctx);
}

static int rtrs_srv_add_one(struct ib_device *device)
{
	struct rtrs_srv_ctx *ctx;
	int ret = 0;

	mutex_lock(&ib_ctx.ib_dev_mutex);
	if (ib_ctx.ib_dev_count)
		goto out;

	/*
	 * Since our CM IDs are NOT bound to any ib device we will create them
	 * only once
	 */
	ctx = ib_ctx.srv_ctx;
	ret = rtrs_srv_rdma_init(ctx, ib_ctx.port);
	if (ret) {
		/*
		 * We errored out here.
		 * According to the ib code, if we encounter an error here then the
		 * error code is ignored, and no more calls to our ops are made.
		 */
		pr_err("Failed to initialize RDMA connection");
		goto err_out;
	}

out:
	/*
	 * Keep a track on the number of ib devices added
	 */
	ib_ctx.ib_dev_count++;

err_out:
	mutex_unlock(&ib_ctx.ib_dev_mutex);
	return ret;
}

static void rtrs_srv_remove_one(struct ib_device *device, void *client_data)
{
	struct rtrs_srv_ctx *ctx;

	mutex_lock(&ib_ctx.ib_dev_mutex);
	ib_ctx.ib_dev_count--;

	if (ib_ctx.ib_dev_count)
		goto out;

	/*
	 * Since our CM IDs are NOT bound to any ib device we will remove them
	 * only once, when the last device is removed
	 */
	ctx = ib_ctx.srv_ctx;
	rdma_destroy_id(ctx->cm_id_ip);
	rdma_destroy_id(ctx->cm_id_ib);

out:
	mutex_unlock(&ib_ctx.ib_dev_mutex);
}

static struct ib_client rtrs_srv_client = {
	.name	= "rtrs_server",
	.add	= rtrs_srv_add_one,
	.remove	= rtrs_srv_remove_one
};

/**
 * rtrs_srv_open() - open RTRS server context
 * @ops:		callback functions
 * @port:               port to listen on
 *
 * Creates server context with specified callbacks.
 *
 * Return a valid pointer on success otherwise PTR_ERR.
 */
struct rtrs_srv_ctx *rtrs_srv_open(struct rtrs_srv_ops *ops, u16 port)
{
	struct rtrs_srv_ctx *ctx;
	int err;

	ctx = alloc_srv_ctx(ops);
	if (!ctx)
		return ERR_PTR(-ENOMEM);

	mutex_init(&ib_ctx.ib_dev_mutex);
	ib_ctx.srv_ctx = ctx;
	ib_ctx.port = port;

	err = ib_register_client(&rtrs_srv_client);
	if (err) {
		free_srv_ctx(ctx);
		return ERR_PTR(err);
	}

	return ctx;
}
EXPORT_SYMBOL(rtrs_srv_open);

static void close_paths(struct rtrs_srv_sess *srv)
{
	struct rtrs_srv_path *srv_path;

	mutex_lock(&srv->paths_mutex);
	list_for_each_entry(srv_path, &srv->paths_list, s.entry)
		close_path(srv_path);
	mutex_unlock(&srv->paths_mutex);
}

static void close_ctx(struct rtrs_srv_ctx *ctx)
{
	struct rtrs_srv_sess *srv;

	mutex_lock(&ctx->srv_mutex);
	list_for_each_entry(srv, &ctx->srv_list, ctx_list)
		close_paths(srv);
	mutex_unlock(&ctx->srv_mutex);
	flush_workqueue(rtrs_wq);
}

/**
 * rtrs_srv_close() - close RTRS server context
 * @ctx: pointer to server context
 *
 * Closes RTRS server context with all client sessions.
 */
void rtrs_srv_close(struct rtrs_srv_ctx *ctx)
{
	ib_unregister_client(&rtrs_srv_client);
	mutex_destroy(&ib_ctx.ib_dev_mutex);
	close_ctx(ctx);
	free_srv_ctx(ctx);
}
EXPORT_SYMBOL(rtrs_srv_close);

static int check_module_params(void)
{
	if (sess_queue_depth < 1 || sess_queue_depth > MAX_SESS_QUEUE_DEPTH) {
		pr_err("Invalid sess_queue_depth value %d, has to be >= %d, <= %d.\n",
		       sess_queue_depth, 1, MAX_SESS_QUEUE_DEPTH);
		return -EINVAL;
	}
	if (max_chunk_size < MIN_CHUNK_SIZE || !is_power_of_2(max_chunk_size)) {
		pr_err("Invalid max_chunk_size value %d, has to be >= %d and should be power of two.\n",
		       max_chunk_size, MIN_CHUNK_SIZE);
		return -EINVAL;
	}

	/*
	 * Check if IB immediate data size is enough to hold the mem_id and the
	 * offset inside the memory chunk
	 */
	if ((ilog2(sess_queue_depth - 1) + 1) +
	    (ilog2(max_chunk_size - 1) + 1) > MAX_IMM_PAYL_BITS) {
		pr_err("RDMA immediate size (%db) not enough to encode %d buffers of size %dB. Reduce 'sess_queue_depth' or 'max_chunk_size' parameters.\n",
		       MAX_IMM_PAYL_BITS, sess_queue_depth, max_chunk_size);
		return -EINVAL;
	}

	return 0;
}

void rtrs_srv_ib_event_handler(struct ib_event_handler *handler,
			       struct ib_event *ibevent)
{
	pr_info("Handling event: %s (%d).\n", ib_event_msg(ibevent->event),
		ibevent->event);
}

static int rtrs_srv_ib_dev_init(struct rtrs_ib_dev *dev)
{
	INIT_IB_EVENT_HANDLER(&dev->event_handler, dev->ib_dev,
			      rtrs_srv_ib_event_handler);
	ib_register_event_handler(&dev->event_handler);

	return 0;
}

static void rtrs_srv_ib_dev_deinit(struct rtrs_ib_dev *dev)
{
	ib_unregister_event_handler(&dev->event_handler);
}


static const struct rtrs_rdma_dev_pd_ops dev_pd_ops = {
	.init = rtrs_srv_ib_dev_init,
	.deinit = rtrs_srv_ib_dev_deinit
};


static int __init rtrs_server_init(void)
{
	int err;

	pr_info("Loading module %s, proto %s: (max_chunk_size: %d (pure IO %ld, headers %ld) , sess_queue_depth: %d, always_invalidate: %d)\n",
		KBUILD_MODNAME, RTRS_PROTO_VER_STRING,
		max_chunk_size, max_chunk_size - MAX_HDR_SIZE, MAX_HDR_SIZE,
		sess_queue_depth, always_invalidate);

	rtrs_rdma_dev_pd_init(0, &dev_pd);

	err = check_module_params();
	if (err) {
		pr_err("Failed to load module, invalid module parameters, err: %d\n",
		       err);
		return err;
	}
	err = class_register(&rtrs_dev_class);
	if (err)
		goto out_err;

	rtrs_wq = alloc_workqueue("rtrs_server_wq", 0, 0);
	if (!rtrs_wq) {
		err = -ENOMEM;
		goto out_dev_class;
	}

	return 0;

out_dev_class:
	class_unregister(&rtrs_dev_class);
out_err:
	return err;
}

static void __exit rtrs_server_exit(void)
{
	destroy_workqueue(rtrs_wq);
	class_unregister(&rtrs_dev_class);
	rtrs_rdma_dev_pd_deinit(&dev_pd);
}

module_init(rtrs_server_init);
module_exit(rtrs_server_exit);
