/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.gnu.org/licenses/gpl-2.0.html
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lnet/lnet/lib-md.c
 *
 * Memory Descriptor management routines
 */

#define DEBUG_SUBSYSTEM S_LNET

#include "../../include/linux/lnet/lib-lnet.h"

/* must be called with lnet_res_lock held */
void
lnet_md_unlink(lnet_libmd_t *md)
{
	if (!(md->md_flags & LNET_MD_FLAG_ZOMBIE)) {
		/* first unlink attempt... */
		lnet_me_t *me = md->md_me;

		md->md_flags |= LNET_MD_FLAG_ZOMBIE;

		/*
		 * Disassociate from ME (if any),
		 * and unlink it if it was created
		 * with LNET_UNLINK
		 */
		if (me) {
			/* detach MD from portal */
			lnet_ptl_detach_md(me, md);
			if (me->me_unlink == LNET_UNLINK)
				lnet_me_unlink(me);
		}

		/* ensure all future handle lookups fail */
		lnet_res_lh_invalidate(&md->md_lh);
	}

	if (md->md_refcount) {
		CDEBUG(D_NET, "Queueing unlink of md %p\n", md);
		return;
	}

	CDEBUG(D_NET, "Unlinking md %p\n", md);

	if (md->md_eq) {
		int cpt = lnet_cpt_of_cookie(md->md_lh.lh_cookie);

		LASSERT(*md->md_eq->eq_refs[cpt] > 0);
		(*md->md_eq->eq_refs[cpt])--;
	}

	LASSERT(!list_empty(&md->md_list));
	list_del_init(&md->md_list);
	lnet_md_free(md);
}

static int
lnet_md_build(lnet_libmd_t *lmd, lnet_md_t *umd, int unlink)
{
	int i;
	unsigned int niov;
	int total_length = 0;

	lmd->md_me = NULL;
	lmd->md_start = umd->start;
	lmd->md_offset = 0;
	lmd->md_max_size = umd->max_size;
	lmd->md_options = umd->options;
	lmd->md_user_ptr = umd->user_ptr;
	lmd->md_eq = NULL;
	lmd->md_threshold = umd->threshold;
	lmd->md_refcount = 0;
	lmd->md_flags = (unlink == LNET_UNLINK) ? LNET_MD_FLAG_AUTO_UNLINK : 0;

	if (umd->options & LNET_MD_IOVEC) {
		if (umd->options & LNET_MD_KIOV) /* Can't specify both */
			return -EINVAL;

		niov = umd->length;
		lmd->md_niov = umd->length;
		memcpy(lmd->md_iov.iov, umd->start,
		       niov * sizeof(lmd->md_iov.iov[0]));

		for (i = 0; i < (int)niov; i++) {
			/* We take the base address on trust */
			/* invalid length */
			if (lmd->md_iov.iov[i].iov_len <= 0)
				return -EINVAL;

			total_length += lmd->md_iov.iov[i].iov_len;
		}

		lmd->md_length = total_length;

		if ((umd->options & LNET_MD_MAX_SIZE) && /* use max size */
		    (umd->max_size < 0 ||
		     umd->max_size > total_length)) /* illegal max_size */
			return -EINVAL;

	} else if (umd->options & LNET_MD_KIOV) {
		niov = umd->length;
		lmd->md_niov = umd->length;
		memcpy(lmd->md_iov.kiov, umd->start,
		       niov * sizeof(lmd->md_iov.kiov[0]));

		for (i = 0; i < (int)niov; i++) {
			/* We take the page pointer on trust */
			if (lmd->md_iov.kiov[i].bv_offset +
			    lmd->md_iov.kiov[i].bv_len > PAGE_SIZE)
				return -EINVAL; /* invalid length */

			total_length += lmd->md_iov.kiov[i].bv_len;
		}

		lmd->md_length = total_length;

		if ((umd->options & LNET_MD_MAX_SIZE) && /* max size used */
		    (umd->max_size < 0 ||
		     umd->max_size > total_length)) /* illegal max_size */
			return -EINVAL;
	} else {   /* contiguous */
		lmd->md_length = umd->length;
		niov = 1;
		lmd->md_niov = 1;
		lmd->md_iov.iov[0].iov_base = umd->start;
		lmd->md_iov.iov[0].iov_len = umd->length;

		if ((umd->options & LNET_MD_MAX_SIZE) && /* max size used */
		    (umd->max_size < 0 ||
		     umd->max_size > (int)umd->length)) /* illegal max_size */
			return -EINVAL;
	}

	return 0;
}

/* must be called with resource lock held */
static int
lnet_md_link(lnet_libmd_t *md, lnet_handle_eq_t eq_handle, int cpt)
{
	struct lnet_res_container *container = the_lnet.ln_md_containers[cpt];

	/*
	 * NB we are passed an allocated, but inactive md.
	 * if we return success, caller may lnet_md_unlink() it.
	 * otherwise caller may only lnet_md_free() it.
	 */
	/*
	 * This implementation doesn't know how to create START events or
	 * disable END events.  Best to LASSERT our caller is compliant so
	 * we find out quickly...
	 */
	/*
	 * TODO - reevaluate what should be here in light of
	 * the removal of the start and end events
	 * maybe there we shouldn't even allow LNET_EQ_NONE!)
	 * LASSERT(!eq);
	 */
	if (!LNetHandleIsInvalid(eq_handle)) {
		md->md_eq = lnet_handle2eq(&eq_handle);

		if (!md->md_eq)
			return -ENOENT;

		(*md->md_eq->eq_refs[cpt])++;
	}

	lnet_res_lh_initialize(container, &md->md_lh);

	LASSERT(list_empty(&md->md_list));
	list_add(&md->md_list, &container->rec_active);

	return 0;
}

/* must be called with lnet_res_lock held */
void
lnet_md_deconstruct(lnet_libmd_t *lmd, lnet_md_t *umd)
{
	/* NB this doesn't copy out all the iov entries so when a
	 * discontiguous MD is copied out, the target gets to know the
	 * original iov pointer (in start) and the number of entries it had
	 * and that's all.
	 */
	umd->start = lmd->md_start;
	umd->length = !(lmd->md_options &
		      (LNET_MD_IOVEC | LNET_MD_KIOV)) ?
		      lmd->md_length : lmd->md_niov;
	umd->threshold = lmd->md_threshold;
	umd->max_size = lmd->md_max_size;
	umd->options = lmd->md_options;
	umd->user_ptr = lmd->md_user_ptr;
	lnet_eq2handle(&umd->eq_handle, lmd->md_eq);
}

static int
lnet_md_validate(lnet_md_t *umd)
{
	if (!umd->start && umd->length) {
		CERROR("MD start pointer can not be NULL with length %u\n",
		       umd->length);
		return -EINVAL;
	}

	if ((umd->options & (LNET_MD_KIOV | LNET_MD_IOVEC)) &&
	    umd->length > LNET_MAX_IOV) {
		CERROR("Invalid option: too many fragments %u, %d max\n",
		       umd->length, LNET_MAX_IOV);
		return -EINVAL;
	}

	return 0;
}

/**
 * Create a memory descriptor and attach it to a ME
 *
 * \param meh A handle for a ME to associate the new MD with.
 * \param umd Provides initial values for the user-visible parts of a MD.
 * Other than its use for initialization, there is no linkage between this
 * structure and the MD maintained by the LNet.
 * \param unlink A flag to indicate whether the MD is automatically unlinked
 * when it becomes inactive, either because the operation threshold drops to
 * zero or because the available memory becomes less than \a umd.max_size.
 * (Note that the check for unlinking a MD only occurs after the completion
 * of a successful operation on the MD.) The value LNET_UNLINK enables auto
 * unlinking; the value LNET_RETAIN disables it.
 * \param handle On successful returns, a handle to the newly created MD is
 * saved here. This handle can be used later in LNetMDUnlink().
 *
 * \retval 0       On success.
 * \retval -EINVAL If \a umd is not valid.
 * \retval -ENOMEM If new MD cannot be allocated.
 * \retval -ENOENT Either \a meh or \a umd.eq_handle does not point to a
 * valid object. Note that it's OK to supply a NULL \a umd.eq_handle by
 * calling LNetInvalidateHandle() on it.
 * \retval -EBUSY  If the ME pointed to by \a meh is already associated with
 * a MD.
 */
int
LNetMDAttach(lnet_handle_me_t meh, lnet_md_t umd,
	     lnet_unlink_t unlink, lnet_handle_md_t *handle)
{
	LIST_HEAD(matches);
	LIST_HEAD(drops);
	struct lnet_me *me;
	struct lnet_libmd *md;
	int cpt;
	int rc;

	LASSERT(the_lnet.ln_refcount > 0);

	if (lnet_md_validate(&umd))
		return -EINVAL;

	if (!(umd.options & (LNET_MD_OP_GET | LNET_MD_OP_PUT))) {
		CERROR("Invalid option: no MD_OP set\n");
		return -EINVAL;
	}

	md = lnet_md_alloc(&umd);
	if (!md)
		return -ENOMEM;

	rc = lnet_md_build(md, &umd, unlink);
	if (rc)
		goto out_free;

	cpt = lnet_cpt_of_cookie(meh.cookie);

	lnet_res_lock(cpt);

	me = lnet_handle2me(&meh);
	if (!me)
		rc = -ENOENT;
	else if (me->me_md)
		rc = -EBUSY;
	else
		rc = lnet_md_link(md, umd.eq_handle, cpt);

	if (rc)
		goto out_unlock;

	/*
	 * attach this MD to portal of ME and check if it matches any
	 * blocked msgs on this portal
	 */
	lnet_ptl_attach_md(me, md, &matches, &drops);

	lnet_md2handle(handle, md);

	lnet_res_unlock(cpt);

	lnet_drop_delayed_msg_list(&drops, "Bad match");
	lnet_recv_delayed_msg_list(&matches);

	return 0;

out_unlock:
	lnet_res_unlock(cpt);
out_free:
	lnet_md_free(md);
	return rc;
}
EXPORT_SYMBOL(LNetMDAttach);

/**
 * Create a "free floating" memory descriptor - a MD that is not associated
 * with a ME. Such MDs are usually used in LNetPut() and LNetGet() operations.
 *
 * \param umd,unlink See the discussion for LNetMDAttach().
 * \param handle On successful returns, a handle to the newly created MD is
 * saved here. This handle can be used later in LNetMDUnlink(), LNetPut(),
 * and LNetGet() operations.
 *
 * \retval 0       On success.
 * \retval -EINVAL If \a umd is not valid.
 * \retval -ENOMEM If new MD cannot be allocated.
 * \retval -ENOENT \a umd.eq_handle does not point to a valid EQ. Note that
 * it's OK to supply a NULL \a umd.eq_handle by calling
 * LNetInvalidateHandle() on it.
 */
int
LNetMDBind(lnet_md_t umd, lnet_unlink_t unlink, lnet_handle_md_t *handle)
{
	lnet_libmd_t *md;
	int cpt;
	int rc;

	LASSERT(the_lnet.ln_refcount > 0);

	if (lnet_md_validate(&umd))
		return -EINVAL;

	if ((umd.options & (LNET_MD_OP_GET | LNET_MD_OP_PUT))) {
		CERROR("Invalid option: GET|PUT illegal on active MDs\n");
		return -EINVAL;
	}

	md = lnet_md_alloc(&umd);
	if (!md)
		return -ENOMEM;

	rc = lnet_md_build(md, &umd, unlink);
	if (rc)
		goto out_free;

	cpt = lnet_res_lock_current();

	rc = lnet_md_link(md, umd.eq_handle, cpt);
	if (rc)
		goto out_unlock;

	lnet_md2handle(handle, md);

	lnet_res_unlock(cpt);
	return 0;

out_unlock:
	lnet_res_unlock(cpt);
out_free:
	lnet_md_free(md);

	return rc;
}
EXPORT_SYMBOL(LNetMDBind);

/**
 * Unlink the memory descriptor from any ME it may be linked to and release
 * the internal resources associated with it. As a result, active messages
 * associated with the MD may get aborted.
 *
 * This function does not free the memory region associated with the MD;
 * i.e., the memory the user allocated for this MD. If the ME associated with
 * this MD is not NULL and was created with auto unlink enabled, the ME is
 * unlinked as well (see LNetMEAttach()).
 *
 * Explicitly unlinking a MD via this function call has the same behavior as
 * a MD that has been automatically unlinked, except that no LNET_EVENT_UNLINK
 * is generated in the latter case.
 *
 * An unlinked event can be reported in two ways:
 * - If there's no pending operations on the MD, it's unlinked immediately
 *   and an LNET_EVENT_UNLINK event is logged before this function returns.
 * - Otherwise, the MD is only marked for deletion when this function
 *   returns, and the unlinked event will be piggybacked on the event of
 *   the completion of the last operation by setting the unlinked field of
 *   the event. No dedicated LNET_EVENT_UNLINK event is generated.
 *
 * Note that in both cases the unlinked field of the event is always set; no
 * more event will happen on the MD after such an event is logged.
 *
 * \param mdh A handle for the MD to be unlinked.
 *
 * \retval 0       On success.
 * \retval -ENOENT If \a mdh does not point to a valid MD object.
 */
int
LNetMDUnlink(lnet_handle_md_t mdh)
{
	lnet_event_t ev;
	lnet_libmd_t *md;
	int cpt;

	LASSERT(the_lnet.ln_refcount > 0);

	cpt = lnet_cpt_of_cookie(mdh.cookie);
	lnet_res_lock(cpt);

	md = lnet_handle2md(&mdh);
	if (!md) {
		lnet_res_unlock(cpt);
		return -ENOENT;
	}

	md->md_flags |= LNET_MD_FLAG_ABORTED;
	/*
	 * If the MD is busy, lnet_md_unlink just marks it for deletion, and
	 * when the LND is done, the completion event flags that the MD was
	 * unlinked.  Otherwise, we enqueue an event now...
	 */
	if (md->md_eq && !md->md_refcount) {
		lnet_build_unlink_event(md, &ev);
		lnet_eq_enqueue_event(md->md_eq, &ev);
	}

	lnet_md_unlink(md);

	lnet_res_unlock(cpt);
	return 0;
}
EXPORT_SYMBOL(LNetMDUnlink);
