// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/*
 * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
 * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
 */

#include "rxe.h"

#define RXE_POOL_TIMEOUT	(200)
#define RXE_POOL_ALIGN		(16)

static const struct rxe_type_info {
	const char *name;
	size_t size;
	size_t elem_offset;
	void (*cleanup)(struct rxe_pool_elem *elem);
	u32 min_index;
	u32 max_index;
	u32 max_elem;
} rxe_type_info[RXE_NUM_TYPES] = {
	[RXE_TYPE_UC] = {
		.name		= "uc",
		.size		= sizeof(struct rxe_ucontext),
		.elem_offset	= offsetof(struct rxe_ucontext, elem),
		.min_index	= 1,
		.max_index	= RXE_MAX_UCONTEXT,
		.max_elem	= RXE_MAX_UCONTEXT,
	},
	[RXE_TYPE_PD] = {
		.name		= "pd",
		.size		= sizeof(struct rxe_pd),
		.elem_offset	= offsetof(struct rxe_pd, elem),
		.min_index	= 1,
		.max_index	= RXE_MAX_PD,
		.max_elem	= RXE_MAX_PD,
	},
	[RXE_TYPE_AH] = {
		.name		= "ah",
		.size		= sizeof(struct rxe_ah),
		.elem_offset	= offsetof(struct rxe_ah, elem),
		.min_index	= RXE_MIN_AH_INDEX,
		.max_index	= RXE_MAX_AH_INDEX,
		.max_elem	= RXE_MAX_AH,
	},
	[RXE_TYPE_SRQ] = {
		.name		= "srq",
		.size		= sizeof(struct rxe_srq),
		.elem_offset	= offsetof(struct rxe_srq, elem),
		.cleanup	= rxe_srq_cleanup,
		.min_index	= RXE_MIN_SRQ_INDEX,
		.max_index	= RXE_MAX_SRQ_INDEX,
		.max_elem	= RXE_MAX_SRQ,
	},
	[RXE_TYPE_QP] = {
		.name		= "qp",
		.size		= sizeof(struct rxe_qp),
		.elem_offset	= offsetof(struct rxe_qp, elem),
		.cleanup	= rxe_qp_cleanup,
		.min_index	= RXE_MIN_QP_INDEX,
		.max_index	= RXE_MAX_QP_INDEX,
		.max_elem	= RXE_MAX_QP,
	},
	[RXE_TYPE_CQ] = {
		.name		= "cq",
		.size		= sizeof(struct rxe_cq),
		.elem_offset	= offsetof(struct rxe_cq, elem),
		.cleanup	= rxe_cq_cleanup,
		.min_index	= 1,
		.max_index	= RXE_MAX_CQ,
		.max_elem	= RXE_MAX_CQ,
	},
	[RXE_TYPE_MR] = {
		.name		= "mr",
		.size		= sizeof(struct rxe_mr),
		.elem_offset	= offsetof(struct rxe_mr, elem),
		.cleanup	= rxe_mr_cleanup,
		.min_index	= RXE_MIN_MR_INDEX,
		.max_index	= RXE_MAX_MR_INDEX,
		.max_elem	= RXE_MAX_MR,
	},
	[RXE_TYPE_MW] = {
		.name		= "mw",
		.size		= sizeof(struct rxe_mw),
		.elem_offset	= offsetof(struct rxe_mw, elem),
		.cleanup	= rxe_mw_cleanup,
		.min_index	= RXE_MIN_MW_INDEX,
		.max_index	= RXE_MAX_MW_INDEX,
		.max_elem	= RXE_MAX_MW,
	},
};

void rxe_pool_init(struct rxe_dev *rxe, struct rxe_pool *pool,
		   enum rxe_elem_type type)
{
	const struct rxe_type_info *info = &rxe_type_info[type];

	memset(pool, 0, sizeof(*pool));

	pool->rxe		= rxe;
	pool->name		= info->name;
	pool->type		= type;
	pool->max_elem		= info->max_elem;
	pool->elem_size		= ALIGN(info->size, RXE_POOL_ALIGN);
	pool->elem_offset	= info->elem_offset;
	pool->cleanup		= info->cleanup;

	atomic_set(&pool->num_elem, 0);

	xa_init_flags(&pool->xa, XA_FLAGS_ALLOC);
	pool->limit.min = info->min_index;
	pool->limit.max = info->max_index;
}

void rxe_pool_cleanup(struct rxe_pool *pool)
{
	WARN_ON(!xa_empty(&pool->xa));
}

int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem,
				bool sleepable)
{
	int err = -EINVAL;
	gfp_t gfp_flags;

	if (atomic_inc_return(&pool->num_elem) > pool->max_elem)
		goto err_cnt;

	elem->pool = pool;
	elem->obj = (u8 *)elem - pool->elem_offset;
	kref_init(&elem->ref_cnt);
	init_completion(&elem->complete);

	/* AH objects are unique in that the create_ah verb
	 * can be called in atomic context. If the create_ah
	 * call is not sleepable use GFP_ATOMIC.
	 */
	gfp_flags = sleepable ? GFP_KERNEL : GFP_ATOMIC;

	if (sleepable)
		might_sleep();
	err = xa_alloc_cyclic(&pool->xa, &elem->index, NULL, pool->limit,
			      &pool->next, gfp_flags);
	if (err < 0)
		goto err_cnt;

	return 0;

err_cnt:
	atomic_dec(&pool->num_elem);
	return err;
}

void *rxe_pool_get_index(struct rxe_pool *pool, u32 index)
{
	struct rxe_pool_elem *elem;
	struct xarray *xa = &pool->xa;
	void *obj;

	rcu_read_lock();
	elem = xa_load(xa, index);
	if (elem && kref_get_unless_zero(&elem->ref_cnt))
		obj = elem->obj;
	else
		obj = NULL;
	rcu_read_unlock();

	return obj;
}

static void rxe_elem_release(struct kref *kref)
{
	struct rxe_pool_elem *elem = container_of(kref, typeof(*elem), ref_cnt);

	complete(&elem->complete);
}

int __rxe_cleanup(struct rxe_pool_elem *elem, bool sleepable)
{
	struct rxe_pool *pool = elem->pool;
	struct xarray *xa = &pool->xa;
	static int timeout = RXE_POOL_TIMEOUT;
	int ret, err = 0;
	void *xa_ret;

	if (sleepable)
		might_sleep();

	/* erase xarray entry to prevent looking up
	 * the pool elem from its index
	 */
	xa_ret = xa_erase(xa, elem->index);
	WARN_ON(xa_err(xa_ret));

	/* if this is the last call to rxe_put complete the
	 * object. It is safe to touch obj->elem after this since
	 * it is freed below
	 */
	__rxe_put(elem);

	/* wait until all references to the object have been
	 * dropped before final object specific cleanup and
	 * return to rdma-core
	 */
	if (sleepable) {
		if (!completion_done(&elem->complete) && timeout) {
			ret = wait_for_completion_timeout(&elem->complete,
					timeout);

			/* Shouldn't happen. There are still references to
			 * the object but, rather than deadlock, free the
			 * object or pass back to rdma-core.
			 */
			if (WARN_ON(!ret))
				err = -EINVAL;
		}
	} else {
		unsigned long until = jiffies + timeout;

		/* AH objects are unique in that the destroy_ah verb
		 * can be called in atomic context. This delay
		 * replaces the wait_for_completion call above
		 * when the destroy_ah call is not sleepable
		 */
		while (!completion_done(&elem->complete) &&
				time_before(jiffies, until))
			mdelay(1);

		if (WARN_ON(!completion_done(&elem->complete)))
			err = -EINVAL;
	}

	if (pool->cleanup)
		pool->cleanup(elem);

	atomic_dec(&pool->num_elem);

	return err;
}

int __rxe_get(struct rxe_pool_elem *elem)
{
	return kref_get_unless_zero(&elem->ref_cnt);
}

int __rxe_put(struct rxe_pool_elem *elem)
{
	return kref_put(&elem->ref_cnt, rxe_elem_release);
}

void __rxe_finalize(struct rxe_pool_elem *elem)
{
	void *xa_ret;

	xa_ret = xa_store(&elem->pool->xa, elem->index, elem, GFP_KERNEL);
	WARN_ON(xa_err(xa_ret));
}
